我創建了用於在客戶機器上部署我的.net winform應用程序的WiX安裝程序項目。該應用程序只掃描文件並將圖像保存到服務器上的數據庫。該掃描儀是相當具體的,只有一個在公司,但有約。可偶爾使用它的四個用戶=>應用程序將只安裝在專用於掃描的單個工作站上 - 大多數情況下它將免費,任何這些用戶都可以訪問,掃描文檔並繼續他的工作。當新用戶首次使用每臺機器安裝時,WiX3 - util:XmlFile元素再次執行
=>我在做一個按機器安裝:ALLUSERS是硬編碼爲1
因爲在生產數據庫服務器不是由我控制,我真的不知道,該數據庫將被存儲,我無法將正確的ConnectionStrings.config文件打包到MSI存檔中。取而代之的是,安裝程序根據用戶在安裝過程中提供的參數值修改此配置。爲了更新連接字符串,我使用util:XmlFile元素。 connectionstrings.config文件與app二進制文件一起存儲在安裝目錄中。
一切似乎工作正常,直到我模擬兩個用戶使用這種每機器安裝。我已經在我自己的帳戶下執行了我的wix安裝項目,XML配置文件已經正確更新,然後我啓動了應用程序並測試了連接字符串。一切都很好。
然後我切換到另一個用戶帳戶。快捷鍵已經出現在程序菜單中 - 就像我預料的那樣,因爲安裝是每臺機器。所以我點擊快捷方式,然後(意外地爲我)進度條窗口「等到產品XY的配置完成。」出現了。 (請注意,我的機器語言環境不是英語,在英語語言環境工作站上的消息可能略有不同)。幾秒鐘後窗口消失,我的應用程序啓動。不幸的是,它無法連接到數據庫,因爲connectionStrings.config文件已被重寫 - 連接字符串已使用默認(=不正確)屬性值更新。
我一直在調查爲什麼安裝程序會在新用戶帳戶嘗試使用它時再次啓動。這是因爲快捷方式元素(快捷方式放在'ProgramMenuFolder'中,有一個卸載操作的請求,AFAIK需要一個父組件,這個組件需要一個KeyPath,它必須是HKCU下的一個註冊表鍵)。當我從WXS中刪除所有程序菜單快捷方式時,MSI在切換用戶上下文後不會再次啓動。
結果是我有安裝程序,它可以根據輸入參數配置與數據庫的連接。但是,稍後嘗試從第二個用戶帳戶使用該應用程序只需將此配置發送到梳妝檯。在生產環境中,這意味着管理員必須在每次新用戶嘗試使用該應用程序時手動更改連接字符串,這當然是不可接受的行爲。
這簡化了我的WiX源的版本:
<?define ProductID = "11111111-1111-1111-1111-111111111111" ?>
<?define ProductName = "MyProduct" ?>
<?define ProductLocalName = "MyLocalLanguageProductName" ?>
<!-- application's root registry path, where it stores its settings -->
<?define ApplicationRootRegistryKey = "Software\MyCompany\MyProject\MyBuildConfiguration" ?>
<Product Id="$(var.ProductID)" UpgradeCode="{11111111-1111-1111-1111-111111111112}"
Name="$(var.ProductName)" Version="1.10.1103"
Manufacturer="MyCompany"Language="1029" Codepage="1250">
<Package Id="*" InstallerVersion="200" Compressed="yes"
Description="$(var.ProductName) Installer" Languages="1029"
SummaryCodepage="1250" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<!-- always install the app for all users -->
<Property Id="ALLUSERS" Value="1"/>
<!-- initialize properties used for adjusting connection strings.
The user will provide valid property values through command-line -->
<Property Id="DB_SERVER_NAME" Value="please-specify-db-server-name"/>
<Property Id="DB_NAME" Value="please-specify-db-name"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="CompanyProgramFilesFolder" Name="CompanyName" >
<Directory Id="INSTALLDIR" Name="ProjectName">
<Directory Id="InstallDirApp" Name="Bin" />
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="AppProgramMenuDir" Name="$(var.ProductLocalName)">
<Component Id="ProgramMenuDir" Guid="*">
<RemoveFolder Id='AppProgramMenuDir' On='uninstall'/>
<RegistryValue Root='HKCU' Key='$(var.ApplicationRootRegistryKey)' Type='string' Value='' KeyPath='yes' />
</Component>
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="InstallDirApp">
<Component Id="Executable" Guid="*">
<File KeyPath="yes" Source="$(var.MyProject.TargetPath)">
<Shortcut Id="ProgramMenuShortcut" Name="$(var.ProductLocalName)"
Directory="AppProgramMenuDir" Advertise="yes"
WorkingDirectory="InstallDirApp" Icon="AppIcon.ico" IconIndex="0"/>
</File>
</Component>
<!-- ConnectionStrings config file deployment and settings adjustment -->
<Component Id="ConnectionStrings.config" Guid="*">
<File KeyPath="yes" Source="$(var.Csob.ChequesScanning.SmartShell.TargetDir)ConnectionStrings.config" />
<!--</Component>
<Component Id="xml01" Guid="*">-->
<!--<Condition><![CDATA[NOT Installed]]></Condition>-->
<!-- this sets the connection strings according to provided parameters -->
<util:XmlFile Id="SetConnectionString" Action="bulkSetValue"
File="[#ConnectionStrings.config]"
ElementPath="//add" Name="connectionString"
Value="Data Source=[DB_SERVER_NAME];Initial Catalog=[DB_NAME];Integrated Security=True;Pooling=True"
Permanent="yes" />
</Component>
</DirectoryRef>
<Icon Id="AppIcon.ico" SourceFile="$(var.MyProject.ProjectDir)Resources\AppIcon.ico" />
<Feature Id="ProductFeature" Title="MyProjectName" Level="1">
<ComponentRef Id="Executable" />
<ComponentRef Id="ConnectionStrings.config"/>
<ComponentRef Id="ProgramMenuDir" />
</Feature>
</Product>
</Wix>
我曾嘗試以下步驟來解決這個問題,但沒有任何幫助我:
1)我已經分離和獨立的部件。
2)我試過在這些組件下添加一個NOT INSTALL。
3)我已經嘗試在安裝過程中向HKLM寫入註冊表值。我已經爲該註冊表值添加了一個RegistrySearch和Property,然後使用該值作爲條件(實際上只是替換之前的「NOT Installed」)
任何人都可以提供幫助嗎?我究竟做錯了什麼? HKMU
(See reference)下
感謝諮詢
馬立克
如何在「HKLM」下生根註冊表項?這是否解決了這個問題? – 2010-11-06 17:54:43
嗨Frédéric,是的,這可能會解決問題,但是WiX不允許這樣做 - 「ProgramMenuDir被認爲屬於用戶配置文件(即使爲所有用戶安裝),並且WiX需要該目錄的keypath根植於HKCU :-( – Marzena 2010-11-07 19:22:11
更新爲上一個:在HKLM下生成註冊表值時,會生成ICE38編譯錯誤:「ICE38:Component ProgramMenuDir安裝到用戶配置文件,它的KeyPath註冊表項必須屬於HKCU。」 – Marzena 2010-11-08 09:51:04