日々の記録を、のーみそのおもむくままに、だらだらと書きつづるところです。
やまださんのところのコメントを書くにあたって、ポメラのキーボードのキーピッチが気になったので調べた。17mm。
ふむ。
フルキーボードを調べると、だいたい19mmらしい。
ついでなので、手持ちのマシンのキーボードサイズをいろいろ調べた。
いろいろなサイズがあるなー。
最小はZaurus SL-Cシリーズの10.75mmだそうだ。最大はフルサイズキーボード。
常用しているThinkPad s30は18.25mm。X61sは18.5mm。
この微妙な差が(X61sに)慣れない原因か。
MobileGear MC-MKおよびSA1Fは16.5mm。同じサイズなのね。
2009-05-12の続き。個々の曲の感想(?)。
思ったことがなかなか言葉に落ちなくてちょっと苦労。
01 - リズムに気を取られていると主旋律とのズレに足元をすくわれる感じがする。変拍子な気がするのだが、いまいち自信が無い。不思議な世界の入り口という感じがする。
02 - キーキー鳴る音から始まる、ちょっと不思議な広がりを持つ曲。かと思えば、謎の電子音が仲間入りして別のリズムを奏でだすのが面白い。なんか旋律もありそうな感じ。途中までゆったりしているが、リズムが変わったところから急に勢いづいて曲が流れていく。この感じが好き。
03 - 妙に空間の広さを感じさせる曲。「遥かな」の言葉はここから来ているのだろうか? 途中からベースが入り、ちょっと曲の感じが変わる。そして、途中である小節が何度も繰り返される。なんか意味ありそう。溜めに溜めた後、最後にドラムのリズムが変化して最初のパートに戻るところがお気に入り。
04 - 主旋律はのんびりしていて何気ない日常のような様相。一方で最初から最後まで耳に障る音になんとなく非日常性を感じる。途中でテーマがちょっと変化するが、そこの展開がお気に入り。
05 - この曲集のヤマ。太鼓のリズムがお気に入り。徐々に楽器・音が増えていき、ゆっくりながら何か変化を感じさせる。そして徐々に音が減っていき....静かに終わると思いきや、一呼吸の後、目の前がぱっと明るくなるような感じに。コーラスが加わり、ギターと良い感じ。徐々にフェードアウトしていくが、何かが残っている感じ。その感じのまま、エンディングへ。
06 - 風鈴+α曲。M3では風鈴を並べて鳴らしてみた、というような言い方をされていたが、なんか楽しい。風鈴の音以外に聞こえているのはなんだろう?この曲はつかみどころの無い感じと、不思議な余韻を残していると思う。シュレ猫 「curtain call」では何かわからないぽっかり感が残ったが、こちらは微睡みに近いような余韻が残った。
欲をいえば、もうちょっと余韻が欲しかったな....、なんて(^^;
うん、なんか不思議な感想だorz
スクリプトに追加しておきたいこと
- 罫線引き:手は面倒
- リサイズ:ディレクトリツリーのところをどうするかが課題?
- Componentの項にConditionの記載追加(Component Table - Condition)
- Fileの項にVersionとAttributeの項追加。可能ならAttributeは数値ではない方が良いか?
- レジストリ、ショートカットについても出力した方が良い?(Registry Table,Shortcut Table)
- Property Tableの情報の一部も出した方が良い?
注意:思考垂れ流しモードにつき、エントリが長くなることが予想されます(^^;
ここ 経由 ここ
かるあさん、久々だなー
ってのは置いておいて....。
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だと盾アイコン出ているんだよなぁ。
昨日、NTT-Xより宅急便が届いていた。が不在にて受け取れず。
今日帰宅したところ、20時を越えていたが不在通知無し。まだ回れてないってことかな?
ということで、佐川の人の携帯に電話。名字を告げると、一発で素性を当てられてしまった(^^;
というわけで、受け取り完了。
届いたものは、これ→http://nttxstore.jp/_II_QZX0003070
はい、ついカッとなってポチりました(ぉぃ
購入条件がついているので、まずはファースト インプレッションみたいなものをつらつらと並べてみる。
商品の詳細で寸法を書かれていてもピンと来なかったが、箱を見てみると予想外に大きいのでちょっとびっくり。しかし、箱から実物を出したらえらく小さいので驚いた。小さい分だけ配線は簡潔な気もするが、十分だと思う。
意外にも、Kensington ロックの穴が付いていた(ロックを付けてるから盗難に対して安心、という訳では無いようだが)。
本体が小さい分、アダプタがやたら大きく感じる。実際に大きいと思うが(^^;
紙のマニュアルはQuick Startのみ。各言語に対応しているためか、ページ数はぼちぼちあるが、見る場所は1ページ半。電源の入れ方と切り方のみ。CD-ROMが付いていたので、そちらにマニュアルがあるのだろうか?
とりあえず、今夜はここまで。
当面の目的は、MultiTouchJで遊んでみることだったりする(^^;
次は、鏡と赤外線ペンとスクリーン、か。
下準備 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句使えるんだ。
一つ前のエントリに対する、とっちゃんさんのコメント (ありがとうございます)
あと、パラメタライズドクエリーも行けますー
ほへ? ナンデスカソレハ。
ということでふらふら。日本語で見てもピンときた感じがしなかったので、parametarized query, query parameter, parametered queryあたりをうろうろ。何となく朧げながら判ってきた気がする。
明日、時間があったら試してみよう。そのとき参考にする箇所のメモ
SQL Syntaxの"A {marker} is a parameter reference to ...."ってところが該当の説明かな? あ、SELECTはWHERE句かORDER BY句は使えるみたいだけど、他の句は無いみたい。
ちょこっと整理。ただし、罠入り(ぉぃ
* 名前と中身が一致していない箇所がありますので、そのまま読むと混乱すると思います。
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.
という行が出力がされる。
一つ前のエントリに書かなかった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を使おうと思っている。
試しに、"File","Component","Directory","Feature","FeatureComponents"を出力するようにして、うちの製品のmsiを食わせてみた。
File:4524
Component:511
Directory:566
Feature:6
FeatureComponents:1185
.....えらい多いな。
FeatureComponentsだけでも図示しようと思って、ぽちぽち手作業やり始めてみたが...10分くらい経っても進んでいる感じがしない。気持ち悪くなってきた気がする。(結局、最後までやってみたが、その先が続かなかった)
やっぱりscript側でなんとかする...、か(^^;
14時。寝たのが3時すぎだった事もあると思うが、寝過ぎ。
後々の事もあるが、http://msdn.microsoft.com/ja-jp/library/aa368259(en-us,VS.85).aspx を見つつ整理を始めてみた。
とりあえず、分類っぽいのはおわり。
わんくま同盟の勉強会MLに先日より参加させていただいているが、もう昨日の感想(どこかに提出するらしい)が流れていた。
WiXは初めて聞いたそうだ、まぁ、そんなもんかも(^^;
興味持ってくれた人がいればいいなー、なんて思う。
そういえば、懇親会でとっちゃんさんのLTの続きがちょっとあったけど、以前、自分が書いたlocalzationが元になっているものがあるとか無いとか。そういうの聞けるのは嬉しい。
久々に引っ張りだして、また調整していきたいな。
何とか終了。
練習した時は、制限時間5分を余裕で超えだったが、あがって早口になったためかちょっとオーバーで終了。
...最初にやれてよかった。最後のネタ(痛IDE)の破壊力でかすぎw
追記:資料については、自己紹介を削った版を公開予定。
ちなみに、一番時間がかかっているのは....History部分かも(cvs行ったり来たりしてたし)。次が相関図か。
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いじる部分抜いてます)
相変わらずベタ書き。
諸々考えてないなぁ(エラー処理とか...)。
再整理確定。
Wix 2.0のHistoryを眺めていたら、こんな記述があるのに気付く。
>>BobArnso: Drop in localizations contributed by Movie Maker team.
自分のと違うのが入ってるなーとおもったが、供出元が判明。
ちょっとヘコみ気味になるが、自分のはまぁ、グダグダになっている所もあるので、入らなかったのは幸せか。
でも、これでLocalization Projectとの関係がますます判らなくなった気がする。
昨晩、一応資料は出来ていたのだが、提出せずに寝かせてみた。
見直したらやっぱり気になったので、修正。
さらに、背景テンプレートを使うのを忘れていたので、慌てて導入。
必須じゃないらしいけど....まぁ、気分上の問題という事で(^^;
テンプレートにあわせて配置しなおし。
1枚だけテンプレートを使うと見づらくなる物があったので、そこだけ真っ白。
前日ぎりぎりまで直してると、精神的に余裕が無くなるので、すっぱり切って提出。
後で流れてきたメールから考えると、最後の提出だったみたいorz
別にライブコーディングをやるわけでは無いが、久々にパッケージを作ってみた。
題材は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さんに見てもらおう。
_ やまだ [だしょー。 ついつい奥のキーも一緒に押してしまうのよ。 携帯とかのポケットサイズを目指すわけじゃないんだから、ち..]
_ しらが [>>ついつい奥のキーも一緒に押してしまうのよ。 となりを叩くことはあっても、奥を押した経験は無いかな....? ..]