追記

日々の記録


日々の記録を、のーみそのおもむくままに、だらだらと書きつづるところです。

2004|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|

2009-07-04

_ キーピッチ

やまださんのところのコメントを書くにあたって、ポメラのキーボードのキーピッチが気になったので調べた。17mm。
ふむ。
フルキーボードを調べると、だいたい19mmらしい。
ついでなので、手持ちのマシンのキーボードサイズをいろいろ調べた。
いろいろなサイズがあるなー。
最小はZaurus SL-Cシリーズの10.75mmだそうだ。最大はフルサイズキーボード。
常用しているThinkPad s30は18.25mm。X61sは18.5mm。
この微妙な差が(X61sに)慣れない原因か。
MobileGear MC-MKおよびSA1Fは16.5mm。同じサイズなのね。

本日のツッコミ(全2件) [ツッコミを入れる]

_ やまだ [だしょー。 ついつい奥のキーも一緒に押してしまうのよ。 携帯とかのポケットサイズを目指すわけじゃないんだから、ち..]

_ しらが [>>ついつい奥のキーも一緒に押してしまうのよ。 となりを叩くことはあっても、奥を押した経験は無いかな....? ..]

本日のリンク元 | 1 |

2009-07-03

_ 夢の追憶 - II

2009-05-12の続き。個々の曲の感想(?)。

思ったことがなかなか言葉に落ちなくてちょっと苦労。

01 - リズムに気を取られていると主旋律とのズレに足元をすくわれる感じがする。変拍子な気がするのだが、いまいち自信が無い。不思議な世界の入り口という感じがする。

02 - キーキー鳴る音から始まる、ちょっと不思議な広がりを持つ曲。かと思えば、謎の電子音が仲間入りして別のリズムを奏でだすのが面白い。なんか旋律もありそうな感じ。途中までゆったりしているが、リズムが変わったところから急に勢いづいて曲が流れていく。この感じが好き。

03 - 妙に空間の広さを感じさせる曲。「遥かな」の言葉はここから来ているのだろうか? 途中からベースが入り、ちょっと曲の感じが変わる。そして、途中である小節が何度も繰り返される。なんか意味ありそう。溜めに溜めた後、最後にドラムのリズムが変化して最初のパートに戻るところがお気に入り。

04 - 主旋律はのんびりしていて何気ない日常のような様相。一方で最初から最後まで耳に障る音になんとなく非日常性を感じる。途中でテーマがちょっと変化するが、そこの展開がお気に入り。

05 - この曲集のヤマ。太鼓のリズムがお気に入り。徐々に楽器・音が増えていき、ゆっくりながら何か変化を感じさせる。そして徐々に音が減っていき....静かに終わると思いきや、一呼吸の後、目の前がぱっと明るくなるような感じに。コーラスが加わり、ギターと良い感じ。徐々にフェードアウトしていくが、何かが残っている感じ。その感じのまま、エンディングへ。

06 - 風鈴+α曲。M3では風鈴を並べて鳴らしてみた、というような言い方をされていたが、なんか楽しい。風鈴の音以外に聞こえているのはなんだろう?この曲はつかみどころの無い感じと、不思議な余韻を残していると思う。シュレ猫 「curtain call」では何かわからないぽっかり感が残ったが、こちらは微睡みに近いような余韻が残った。

欲をいえば、もうちょっと余韻が欲しかったな....、なんて(^^;

うん、なんか不思議な感想だorz

本日のリンク元 | 1 | 1 |

2009-07-02

_ memo - 下準備 IV (2)

スクリプトに追加しておきたいこと

- 罫線引き:手は面倒

- リサイズ:ディレクトリツリーのところをどうするかが課題?

- Componentの項にConditionの記載追加(Component Table - Condition)

- Fileの項にVersionとAttributeの項追加。可能ならAttributeは数値ではない方が良いか?

- レジストリ、ショートカットについても出力した方が良い?(Registry Table,Shortcut Table)

- Property Tableの情報の一部も出した方が良い?

_ memo

注意:思考垂れ流しモードにつき、エントリが長くなることが予想されます(^^;
ここ 経由 ここ
かるあさん、久々だなー
ってのは置いておいて....。
AnkhSvn-2.1.6941.125.msiをとってきてみた。
Orcaで眺めてみる。流れ判ってないけど(ぉぃ
AdvancedWelcomeEulaDlg->WaitForCostingDlgという流れなのかな?
メッセージを見ると、怒られているというか、ちょっと待て言われてるだけな気もするが....。(待ってれば勝手に進みますね、なコメントもあるし)

興味が出てきたので順に見ていってみようか。
まず、プロパティチェック。

Windows Installer XML (3.0.5308.0)

お?(^^;
ということは....ということでソースを見に行ってみる。
wxsファイルがあちこちに見えるが....。てっぺんはドコだー。
ツリー徘徊中。
徘徊しなくても、ここ見れば良いのか?
....
えーい、面倒だ、dark通してしまえ(マテ
で、UIで出てきたのが

  <UI>
  <ProgressText Action="VS2005Setup" Template="[1]">Updating Visual Studio 2005 registration</ProgressText>
  <ProgressText Action="VS90Setup" Template="[1]">Updating Visual Studio 2008 registration</ProgressText>
  <ProgressText Action="VS100Setup" Template="[1]">Updating Visual Studio 2010 registration</ProgressText>
  </UI>
  <UIRef Id="WixUI_Advanced" />

これ。そのまま使ってるのかな?
だとすると、ここかな?

AdvancedWelcomeEulaDlg.wxs
<Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.AdvancedWelcomeEulaDlgInstall)" Hidden="yes">
    <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
    <Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
    <Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)</Publish>
    <Publish Event="EndDialog" Value="Return">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
    <Publish Event="EnableRollback" Value="False">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
    <Publish Event="SpawnDialog" Value="OutOfDiskDlg">(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")</Publish>
    <Condition Action="disable"><![CDATA[LicenseAccepted <> "1"]]></Condition>
    <Condition Action="enable">LicenseAccepted = "1"</Condition>
    <Condition Action="show">ALLUSERS</Condition>
</Control>

えーと、SpawnWaitDialogでWaitForCostingDlgを出すのね。んで、Condition(CostingComplete = 1)がTRUEになるまでぐるぐる、と。 CostingCompleteの値はここ によれば、CostFinalizeによって0に初期化され、costingよって値が変わり、終わると1になると。ふむ。
CostFinalizeに関係するactionにFileCostとCostInitializeがあって、前後関係はCostFinalizeを呼んだらすぐにFileCostを呼び、そのあとにCostFinalizeを呼ぶこと、とされている。costingに影響を与えるActionはCostInitializeの前に呼んでおくと。
OrcaでInstallUISequenceテーブルを開き、Sequence順に並べると、たしかにCostInitialize(800)->FileCost(900)->(略)->CostFinalize(1000)ってあるなぁ。おかしくなさそう。ついでに、MigrateFeatureStates(1200)もすぐ後に並んでいる。これも順番上は問題なさそう。

うーん、なんだろう?単にcostingが間に合わなかっただけ?
そうじゃないとWaitForCostingDlg中でConditionが変化する状況は発生しそうもない。

どうでもいい気がするけどWindowsServer 2008。
管理者だとInstallの所に盾アイコンでないのかな? WiXのインストールパッケージもWixUI_Advanced使っているように見えるけど、Vistaだと盾アイコン出ているんだよなぁ。

_ こっそり....

X61sを触ったので、LTのプレゼン資料(WiXの紹介)をこっそりと公開
LT版との違いは自己紹介のシートの有無。それとファイル形式がpptx→pptになっている。

_ 宅急便

昨日、NTT-Xより宅急便が届いていた。が不在にて受け取れず。

今日帰宅したところ、20時を越えていたが不在通知無し。まだ回れてないってことかな?

ということで、佐川の人の携帯に電話。名字を告げると、一発で素性を当てられてしまった(^^;

というわけで、受け取り完了。

_ Acer K10

届いたものは、これ→http://nttxstore.jp/_II_QZX0003070

はい、ついカッとなってポチりました(ぉぃ

購入条件がついているので、まずはファースト インプレッションみたいなものをつらつらと並べてみる。

商品の詳細で寸法を書かれていてもピンと来なかったが、箱を見てみると予想外に大きいのでちょっとびっくり。しかし、箱から実物を出したらえらく小さいので驚いた。小さい分だけ配線は簡潔な気もするが、十分だと思う。

意外にも、Kensington ロックの穴が付いていた(ロックを付けてるから盗難に対して安心、という訳では無いようだが)。

本体が小さい分、アダプタがやたら大きく感じる。実際に大きいと思うが(^^;

紙のマニュアルはQuick Startのみ。各言語に対応しているためか、ページ数はぼちぼちあるが、見る場所は1ページ半。電源の入れ方と切り方のみ。CD-ROMが付いていたので、そちらにマニュアルがあるのだろうか?

とりあえず、今夜はここまで。

当面の目的は、MultiTouchJで遊んでみることだったりする(^^;

次は、鏡と赤外線ペンとスクリーン、か。

本日のツッコミ(全1件) [ツッコミを入れる]

_ とっちゃん [あら。WiXで作ってるんだ。。。 じゃぁおいらの記憶の部分は関係ないなw 手抜きしないできちんと中見ればよか..]

本日のリンク元 | 2 |

2009-07-01

_ 下準備 IV

下準備 III で書いた物をベースに、テーブルを組み合わせて表を作るスクリプトを書いてみた。が、ディレクトリ構造をどうしようか迷う。Directoryテーブルを総当りしてツリー構造をつくるか....? 手間かかり過ぎないか?

ふと、一番最初に書いたスクリプト(WiSQLRun.vbs移植モノより古い)を見てみた。

 require 'win32ole'
 
 installer = WIN32OLE.new('WindowsInstaller.Installer')
 database = installer.OpenDatabase(ARGV[0],0)
 preview = database.EnableUIpreview # returns UIPreview object
 view = database.OpenView("SELECT `Property`,`Value` FROM `Property`")
 view.Execute
 
 until (record = view.Fetch) == nil
    p "#{record.StringData(1)} <> #{record.StringData(2)}"
    preview.Property(record.StringData(1), record.StringData(2))
 end
 
 view = database.OpenView("SELECT `Dialog` FROM `Dialog`")
 view.Execute
 count = 0
 until (record = view.Fetch) == nil
    preview.ViewDialog(record.StringData(1))
    sleep 0.5
 end
 preview.ViewDialog("")

これは、WiDialog.vbsの一部を引っ張り出して書いてみたもの。よく見ると、"SELECT `Property`,`Value` FROM `Property`"で列を指定している。もしかすると...?ということで、こんなのを書いてみた

msi.rb(変更点のみ)
 def each_row(table,cols,*opt)
    columns = String.new
    if cols.size == 0
       columns = "*"
    else
       columns = cols.join(",")
    end
    options = opt.join(" ")
    view = @database.OpenView("SELECT #{columns} FROM #{table} #{options}")
    view.Execute
    until (record = view.Fetch) == nil
       rowData = Array.new
       (1..record.FieldCount).each{|idx|
          rowData << record.StringData(idx)
       }
       yield(rowData)
    end
 end
WOVtest1.rb
 require '.\msi.rb'
 
 if __FILE__ == $0
    unless ARGV[0].nil?
       msi = MSI.new
       msi.openDatabase(ARGV[0])
       
       msi.each_row("Directory", ["Directory", "Directory_Parent"], "WHERE Directory_Parent = 'TARGETDIR'"){|row|
          puts row.join(" ")
       }
    end
 end
>WOVTest1.rb hoge.msi
ALLUSERSPROFILE TARGETDIR
AdminToolsFolder TARGETDIR
AppDataFolder TARGETDIR
BUILDROOT TARGETDIR
CommonAppDataFolder TARGETDIR
         :

あ、普通にWHERE句使えるんだ。

_ memo - 下準備 IV

一つ前のエントリに対する、とっちゃんさんのコメント (ありがとうございます)

あと、パラメタライズドクエリーも行けますー

ほへ? ナンデスカソレハ。
ということでふらふら。日本語で見てもピンときた感じがしなかったので、parametarized query, query parameter, parametered queryあたりをうろうろ。何となく朧げながら判ってきた気がする。

明日、時間があったら試してみよう。そのとき参考にする箇所のメモ

SQL Syntaxの"A {marker} is a parameter reference to ...."ってところが該当の説明かな? あ、SELECTはWHERE句かORDER BY句は使えるみたいだけど、他の句は無いみたい。

本日のツッコミ(全1件) [ツッコミを入れる]

_ とっちゃん [where と order by はいけますねー あと、パラメタライズドクエリーも行けますー それ以外はよく..]

本日のリンク元 | 1 |

2009-06-29

_ 下準備 - III

ちょこっと整理。ただし、罠入り(ぉぃ
* 名前と中身が一致していない箇所がありますので、そのまま読むと混乱すると思います。

msi_constants.rb
 module MSI_Constants
    MsiOpenDatabaseModeReadOnly       = 0
    MsiOpenDatabaseModeTransact       = 1
    MsiOpenDatabaseModeDirect         = 2
    MsiOpenDatabaseModeCreate         = 3
    MsiOpenDatabaseModeCreateDirect   = 4
    MsiOpenDatabaseModeListScript     = 5
    MsiOpenDatabaseModePatchFile      =32
 end
msi.rb
 require 'win32ole'
 require '.\msi_constants.rb'
 
 class MSI
 
    include MSI_Constants
 
    def initialize()
       @openMode = MsiOpenDatabaseModeReadOnly
       @installer = WIN32OLE.new('WindowsInstaller.Installer')
       @database = nil
    end
    
    def openDatabase(file,openMode=MsiOpenDatabaseModeReadOnly)
       @database = @installer.OpenDatabase(file, openMode)
       openMode = @openMode
    end
 
    def each_row(table)
       view = @database.OpenView("SELECT * FROM #{table}")
       view.Execute
       until (record = view.Fetch) == nil
          rowData = Array.new
          (1..record.FieldCount).each{|idx|
             rowData << record.StringData(idx)
          }
          yield(rowData)
       end
    end
 end
 
 # test
 unless ARGV[0].nil?
    msi = MSI.new
    msi.openDatabase(ARGV[0],MSI::MsiOpenDatabaseModeReadOnly)
    
    msi.each_row("Property"){|row|
       p row.join(" ")
    }
 end
msi_tabletest.rb
 require '.\excel_template3.rb'
 require '.\msi.rb'
 
 module XlMsiTables
    # Base
    def insertHeader
       self[1,1] = "test"
    end
    
    def insertBody(row)
    end
    
    def AutoFitColmns(first=1,last=1)
       puts "done."
    end
 end
 
 module FileTable
    # File Table
    def insertHeader
       self[1,1] = "Sequence"
       self[1,2] = "Component"
       self[1,3] = "FileName"
       self[1,4] = "FileSize"
       self.selectRange(1, 1, 1, 4).Font.Bold = true
    end
    
    def insertBody(row)
       # sequence
       self[$x,1] = row[7]
       # Component_
       self[$x,2] = row[1]
       # FileName
       names = row[2].split("|")
       self[$x,3] = (names.size == 1 ? names[0] : names[1])
       # Filesize
       self[$x,4] = row[3]
    end
    
    def AutoFitColmns(first=1,last=1)
       print "Ft "
       super(first,last)
    end
 end
 
 def usage
    puts "#{File.basename($0)} : MsiFile"
 end
 
 if ARGV.size != 1
    usage()
    exit(1)
 end
 
 tables = ["File"]
 
 unless ARGV[0].nil?
    # puts ARGV
    xl = EXCEL.new(true,false)
    book1 = xl.addBook
    
    msi = MSI.new
    msi.openDatabase(ARGV[0],MSI::MsiOpenDatabaseModeReadOnly)
    
    sheet = nil
    
    tables.each{|table|
       print "#{table} "
       sheet = book1.addWorksheet(table)
       
       eval("sheet.extend(#{table}Table, XlMsiTables)")
       sheet.insertHeader
       
       $x = 2
       msi.each_row(table){|row|
          sheet.insertBody(row)
          print "."
          $x += 1
       }
       
       sheet.AutoFitColmns(1,1)
    }
 end

excel_template3.rbは省略次のエントリに。
AutoFitColmnsの部分は今の所予定したコードになっていない(罠というのはこれ。↑ではsuper()をテストするコードが入っている)
今回、初めて知ったのが、superがmoduleでも使えるということ。
msi_tabletest.rbの例だと、sheet.AutoFitColmnsを呼ぶと、FileTable#AutoFitColmnsが呼び出され、その中からXlMsiTables#AutoFitColmnsが呼ばれる。
(sheet.extend(FileTable,XlMsiTables)により、sheetにXlMsiTables内のmethodを追加した後で、FileTable内のmethodを上書き追加する為)。
これにより、スクリプト実行時、標準出力に

File ..........................Ft done.

という行が出力がされる。

_ memo - WIN32OLE.connect

一つ前のエントリに書かなかったexcel_template3.rbはこんな感じ。ここを元にして書いたもの。

excel_template3.rb
 require '.\excel_constants.rb'
 require 'win32ole'
 
 class EXCEL
    attr_accessor(:book)
    def initialize(visibleFlg=true,quitFlg=nil)
       puts "Excel:start"
       @book = Array.new # Excelが開いているbook(Array)
       @excel = exec
       raize "CantExecEXCEL" unless @excel
       #終了フラグの上書き
       @quitFlg = quitFlg unless quitFlg.nil?
       p @quitFlg
       #デストラクタ登録
       ObjectSpace.define_finalizer(self, EXCEL.callback(@excel,@quitFlg))
       sync
       #ウインドウの表示
       show if visibleFlg
    end
 
    def EXCEL.callback(obj,quitFlg)
       proc{
          if obj&&quitFlg
             obj.Quit
          end
       }
    end
 
    def exec #Excelの起動
       @quitFlg = false
       begin
          xl = WIN32OLE.connect('Excel.Application')
       rescue WIN32OLERuntimeError
          errorno = /.*HRESULT error code:(.*)\n/.match($!).to_a[1].hex
          case errorno
             when 0x800401e3
                # "起動していない"から新規で起動(不可視)
                xl = WIN32OLE.new('Excel.Application')
                @quitFlg = true
             when 0x800401e4 # Excelがインストールされていない?
                xl = nil
             else
             # その他(こない?)
             raise "WIN32OLERuntimeError:#{$!}"
          end
       end
       return xl
    end
    def show
       @excel.Visible = true
    end
 
    def setDisplayAlerts(flag)
       @excel.DisplayAlerts = flag
    end
 
    def hide
       @excel.Visible = false
    end
 
    def quit
       @excel.Quit
       @excel=nil
    end
 
    def sync #Excelが開いているbook等とArrayの同期
       self.each_book{|book|
          book.extend(Book)
          @book << book
       }
    end
 
    def each_book
       numBook = @excel.Application.Workbooks.Count
       return false if numBook == 0
       (1 .. numBook).each{|num|
          yield(@excel.Application.Workbooks.Item(num))
       }
    end
 
    def addBook(template=Excel::XlWBATWorksheet)
       book = @excel.Workbooks.Add(template)
       book.extend(Book)
       @book << book
       return book
    end
 
    def open(file)
       book = self.Application.Workbooks.Open(file)
       book.extend(Book)
       @book << book
       return book
    end
 
    def screenUpdating(flag)
       @excel.ScreenUpdating = flag
    end
 
 end
 
 module Book
    def worksheets_size
       count = self.Worksheets.Count
       return count
    end
    
    def addWorksheet(name=nil)
       sheet = self.Worksheets.Add(nil,self.Worksheets.Item(self.worksheets_size),1,Excel::XlWorksheet)
       unless name.nil?
          self.Worksheets.Item(self.worksheets_size).Name = name
       end
       sheet.extend(Worksheet)
       return sheet
    end
 end
 
 module Worksheet
    def [] y,x
       cell = self.Cells.Item(y,x)
       if cell.MergeCells
          cell.MergeArea.Item(1,1).Value
       else
          cell.Value
       end
    end
 
    def []= y,x,value
       cell = self.Cells.Item(y,x)
       if cell.MergeCells
          cell.MergeArea.Item(1,1).Value = value
       else
          cell.Value = value
       end
    end
    
    def select(y,x)
       cell = self.Cells.Item(y,x).select
       return cell
    end
    
    def selectRange(sy, sx, ey ,ex)
       cell = self.Range(self.Cells(sy, sx), self.Cells(ey, ex))
       return cell
    end
 
    def autofit(range)
       self.Columns(range).EntireColumn.AutoFit
    end
    def merge(range)
       range.merge
    end
    def deleteColmns(range)
       range.delete
    end
 end

この中では、Excelを起動させるのにWIN32OLE.connectを使っている。しかし、勉強会中にソースを弄っているときに気付いたのだが、
Excel終わらせた後でexcel_template3.rbを使うスクリプトを実行したとき途中まで動いて、例外吐いて止まるという現象が起きることがあった。落ちかけのExcelが入るときにこのパターンになっているのだろうか?とりあえず、動いているExcelを使うパターンは止めて、WIN32OLE.connectではなく、WIN32OLE.newを使おうと思っている。

_ (o_ _)o

試しに、"File","Component","Directory","Feature","FeatureComponents"を出力するようにして、うちの製品のmsiを食わせてみた。

File:4524

Component:511

Directory:566

Feature:6

FeatureComponents:1185

.....えらい多いな。

FeatureComponentsだけでも図示しようと思って、ぽちぽち手作業やり始めてみたが...10分くらい経っても進んでいる感じがしない。気持ち悪くなってきた気がする。(結局、最後までやってみたが、その先が続かなかった)

やっぱりscript側でなんとかする...、か(^^;

_ ToDo :XREA+

7/29期限。

更新忘れぬよう。

本日のリンク元 | 1 |

2009-06-28

_ 目が覚めたら....

14時。寝たのが3時すぎだった事もあると思うが、寝過ぎ。

_ 整理 - WindowsInstaller/Database Tables

後々の事もあるが、http://msdn.microsoft.com/ja-jp/library/aa368259(en-us,VS.85).aspx を見つつ整理を始めてみた。

とりあえず、分類っぽいのはおわり。

_ 配線

この時期恒例の配線作業。暗くなる前に作業が終わらせられた。

あとはお隣さんに線の引き込みをお願いするのみ。

_

かなりボロボロになってきたので靴屋さんへ。

ついでにサンダルも購入。

_ 夕飯

頑徹にてラーメン。

魚介出汁なラーメンがあったので頼んでみた。

なかなか美味しい。美豚のスープに似た感じだったと思う。

_ ちょっと嬉しい事

わんくま同盟の勉強会MLに先日より参加させていただいているが、もう昨日の感想(どこかに提出するらしい)が流れていた。

WiXは初めて聞いたそうだ、まぁ、そんなもんかも(^^;

興味持ってくれた人がいればいいなー、なんて思う。

そういえば、懇親会でとっちゃんさんのLTの続きがちょっとあったけど、以前、自分が書いたlocalzationが元になっているものがあるとか無いとか。そういうの聞けるのは嬉しい。

久々に引っ張りだして、また調整していきたいな。

本日のツッコミ(全3件) [ツッコミを入れる]

_ やまだ [> 興味持ってくれた人がいればいいなー、なんて思う。 いいなー、どころか、その場でくいついてきた人がいたじゃな..]

_ しらが [>>やまださん ん? えーと...ustの方かしら? ]

_ やまだ [え? あの時、ORCAがどーとかWiXがどーとか、その辺はとっちゃんが詳しいとかしらがさんと話してた人いなかったっ..]


2009-06-27

_ LT

何とか終了。

練習した時は、制限時間5分を余裕で超えだったが、あがって早口になったためかちょっとオーバーで終了。

...最初にやれてよかった。最後のネタ(痛IDE)の破壊力でかすぎw

追記:資料については、自己紹介を削った版を公開予定。

ちなみに、一番時間がかかっているのは....History部分かも(cvs行ったり来たりしてたし)。次が相関図か。

_ リモートデスクトップ接続

AirHにてportforwardかませてサーバにつないでみた。

少々引っかかる感じもあるが、予想より良い感じ。

_ 下準備 - II

 require 'win32ole'
 require '.\excel_constants.rb'
 
 class MSI
    MsiOpenDatabaseModeReadOnly      = 0
    MsiOpenDatabaseModeTransact      = 1
    MsiOpenDatabaseModeDirect         = 2
    MsiOpenDatabaseModeCreate         = 3
    MsiOpenDatabaseModeCreateDirect   = 4
    MsiOpenDatabaseModeListScript      = 5
    MsiOpenDatabaseModePatchFile      =32
    
    def initialize
       @openMode = MsiOpenDatabaseModeReadOnly
       @installer = WIN32OLE.new('WindowsInstaller.Installer')
       @database = nil
    end
    
    def openDatabase(file)
       @database = @installer.OpenDatabase(file, @openMode)
    end
    
    def each_row(query)
       view = @database.OpenView(query)
       view.Execute
       until (record = view.Fetch) == nil
          rowData = Array.new
          (1..record.FieldCount).each{|idx|
             rowData.push(record.StringData(idx))
          }
       yield(rowData)
       end
    end
 end
 
 class EXCEL
    (さっくり省略)
 end
 
 (その他Excel関係もさっくり省略)
 
 def usage
    puts "#{File.basename($0)} : MsiFile"
 end
 
 if ARGV.size != 1
    usage()
    exit(1)
 end
  
 $sheet = nil
 queries = "SELECT * FROM File"
 
 unless ARGV[0].nil?
    puts ARGV
    xl = EXCEL.new(true,false)
    book1 = xl.addBook
    $sheet = book1.addWorksheet
 
    msi = MSI.new
    msi.openDatabase(ARGV[0])
 
    $sheet[1,1] = "Sequence"
    $sheet[1,2] = "Component"
    $sheet[1,3] = "FileName"
    $sheet[1,4] = "FileSize"
    $sheet.selectRange(1, $startx, 1, 4).Font.Bold = true
    x = 2
    
    queries.each{|query|
       msi.each_row(query){|row|
          # sequence
          $sheet[x,1] = row[7]
          # Component_
          $sheet[x,2] = row[1]
          # FileName
          names = row[2].split("|")
          $sheet[x,3] = (names.size == 1 ? names[0] : names[1])
          #Filesize
          $sheet[x,4] = row[3]
          x += 1
       }
    }
 end

LTが終わった勢いで書いてみた。
Excel起動して、FileテーブルのSequence,Component_, FileName, Filesizeを出力するようにしてみた(長いので↑のスクリプトからはExcelいじる部分抜いてます)
相変わらずベタ書き。
諸々考えてないなぁ(エラー処理とか...)。
再整理確定。

本日のリンク元 | 3 | 1 | 1 |

2009-06-26

_ 業務連絡(?)

やまださん、やまださんー。

6/27は新宿出没の予定ありますかー?

ポメラ持っていきましょうかー?

_ LT - 見直し・練習

見直すとやっぱ気になるわけで...間違い修正。

ざっと話したいことを纏めて練習っぽくやってみた....が、時間あふれたorz

_ WiX - Localization

Wix 2.0のHistoryを眺めていたら、こんな記述があるのに気付く。

>>BobArnso: Drop in localizations contributed by Movie Maker team.

自分のと違うのが入ってるなーとおもったが、供出元が判明。

ちょっとヘコみ気味になるが、自分のはまぁ、グダグダになっている所もあるので、入らなかったのは幸せか。

でも、これでLocalization Projectとの関係がますます判らなくなった気がする。

本日のツッコミ(全9件) [ツッコミを入れる]

Before...

_ しらが [やめてー (>_<) ]

_ やまだ [あ、んなの出てますけどどーします? http://www.kingjim.co.jp/news/0901/p-po..]

_ しらが [アップデートについては知ってましたが....期限付きかー。 バグは以下の3点。 気になるのであれば、お手数ですが..]

_ やまだ [> 気になるのであれば いや、私が気にするかどうかでなく、しらがさんが気にするかどうかでしょーが。 > アッ..]

_ しらが [|∇・) ニヤ ]

本日のリンク元 | 1 | 1 | 1 |

2009-06-25

_ LT:資料修正

昨晩、一応資料は出来ていたのだが、提出せずに寝かせてみた。

見直したらやっぱり気になったので、修正。

さらに、背景テンプレートを使うのを忘れていたので、慌てて導入。

必須じゃないらしいけど....まぁ、気分上の問題という事で(^^;

テンプレートにあわせて配置しなおし。

1枚だけテンプレートを使うと見づらくなる物があったので、そこだけ真っ白。

前日ぎりぎりまで直してると、精神的に余裕が無くなるので、すっぱり切って提出。

後で流れてきたメールから考えると、最後の提出だったみたいorz

本日のツッコミ(全1件) [ツッコミを入れる]

_ とっちゃん [おいらの資料は、表仕込みでPPT3枚だからなーwww あと30秒縮められるとスゲー余裕ができるけど。。。無理そうだ..]


2009-06-24

_ LT準備?:パッケージ作成

別にライブコーディングをやるわけでは無いが、久々にパッケージを作ってみた。
題材はMultiTouchJ。以前、IRCでRさんに「WiX中途半端になっちゃってるから、きちんとやりたい」と話していたら「MultiTouchJのWindows版のパッケージングをやってもらおう」と返ってきていたので。
とりあえず、zip版のツリーを再現させるところから。
ファイル数が多いので、1から手でやるのは大変だなぁ。
ということで、heatを試しに使ってみた。

MultiTouchJのトップディレクトリで

heat dir . -gg -out MulitouchJ-hervest.wxs

を実行(-sfragを付けても良かったかも)。出来たwxsからDirectory, Componentを本番のwxsへ移植。-ggでGuidを生成させているので少し楽。File elementを見ると生成されるディレクトリ毎に並んでいない。並列処理でもしているのだろうか?
IdアトリビュートがdirE38BC8CB897F172BBBDBADD291D10421とかcmp019A973EBA0A0B27B455863EC03B7BC0とかfilB91B943826F7E3FF26CCC5890B8F6E67と書かれていて、個人的には分かりづらかったため、ディレクトリ名・ファイル名を元に付けなおす。
<DirectryRef>で平坦にすべきか、子elementを加えていくかでまよったが、ディレクトリ構造が見えにくくなるので、初めは後者の方法にし、場合によって前者を混ぜるようにした。
少々時間を要したが、Directory,Component,Featureの記述完了。数回 candle,lightを行ったり来たりしてビルド完了。行ったり来たりしたのは、Idアトリビュートに使えない文字"-"を使っていたり、Idの重複があったため。
VMWare上のWindows XPにて展開テスト。ディレクトリ構造がやや間違っていたので修正。UIは無いが、取りあえず目的は達成。

うまく動いたので、Directory elementをいくつかに分解。分割後、同じように配置されるか確認しつつ修正した。

次にショートカット作成。WiX.chmの"Create a Shortcut on the Start Menu"を参考に作成。
そういえば、JREやら何やらが必要なのね、ということで、"Create a Shortcut to a Webpage"を参考にショートカット作成。実はこちらを先に参考にしていたのだが...。utilを使うということでWixUtilExtension.dllを使うよう、candle/lightのパラメータを若干変更。

candle MultiTouchJ.wxs -ext WixUtilExtension.dll
light MultiTouchJ.wixobj -ext WixUtilExtension.dll

問題なく作成完了。

<DirectoryRef Id="ApplicationProgramsFolder">
   <Component Id="ApplicationShortcut" Guid="{9FC19C39-D778-1AD5-7762-525535F8711A}">
      <util:InternetShortcut Id="downloadJRE" Directory="ApplicationProgramsFolder" Name="Download JRE" Target="http://www.java.com/download/index.jsp" />
      <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
      <RegistryValue Root="HKCU" Key="Software\MultiTouchJ" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
   </Component>
</DirectoryRef>

一部省いているが、概ねこんな感じ。Directory element内なのにわざわざDirectoryの記述が必要だったりするのがちょっと変な感じ(^^;

さらに、こちらにutilを使わないでショートカットを作成する方法が紹介されていたので試す。さっきのutil:InternetShortcutの部分を

<IniFile Id="downloadJRE" Action="createLine" Name="Download JRE.url" Directory="ApplicationProgramsFolder" Section="InternetShortcut" Key="URL" Value="http://www.java.com/download/index.jsp" />

このように変更。ビルド。生成されるmsiのファイルサイズが先程より小さい。なるほど。

折角なのでpre processorを使って分岐させてみようと思い立つ。しかし...

<?ifdef UseUtil?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
		xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?else?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?endif?>
 :

として

candle -dUseUtil="true" MultiTouchJ.wxs

を試したところ、

MultiTouchJ.wxs(921) : error CNDL0104 : Not a valid source file;
detail: 予期しないファイルの終わりが検出されました。
次の要素が閉じられていません。Wix.
行 921、位置 1 です。

とエラーになってしまった。何度か試してみたが、どうやら上のようにif-else-endifがelementの外と中を跨ぐように置くと駄目らしい。結局、↑の部分の記述はutil用のものを付けたまま、Internet Shortcut部分のみ

<?ifdef UseUtil?>
<util:InternetShortcut Id="downloadJRE" Directory="ApplicationProgramsFolder" Name="Download JRE" Target="http://www.java.com/download/index.jsp" />
<?else?>
<IniFile Id="downloadJRE" Action="createLine" Name="Download JRE.url" Directory="ApplicationProgramsFolder" Section="InternetShortcut" Key="URL" Value="http://www.java.com/download/index.jsp" />
<?endif?>

と記述した。

とりあえず、配置がこれでいいのか、Rさんに見てもらおう。

_ WiX@wiki

LT資料作成で、wixwikiのURIを確認していたら、@wikiのページがひっかかった。
調べてみると、WiXを弄ってみた、な人たちの日本語のページもぼちぼちあるみたい。WiXに触り初めの頃、Programmer's RoadさんのWix Tipsを除けば、MSがオープンソースソフトウェアをリリース、のニュース以外見つけられなかった事を考えれば、かなり増えたなと思った(多くなった、とまでは言えないけれど(^^;)。