我有一个支持插件的主应用程序TheApp
。默认情况下,应用程序A安装在$(ProgramFiles)\TheApp
,但黄金所有者希望这是用户可自定义的,因此其位置可能会因安装时的用户输入而异。
通过将插件复制到安装目录下的子目录Packages
来安装插件。具体来说,不需要为要加载的包设置注册表设置,我试图尽可能地远离注册表。当然,如果用户在安装TheApp
时更改了安装目录,插件也必须更改其安装位置以匹配。
这是如何最好地完成的?我没有使用WiX编写MSI安装程序,但我的第一次尝试可能是在安装TheApp
时创建一个注册表项,保存其安装位置,然后让插件搜索注册表项。这迫使我创建注册表值,这是我试图尽可能避免的。但是,我觉得安装程序应该能够利用Windows Installer数据库找到TheApp
的安装目录。这将消除对注册表项的需求。
对于如何进行安装程序间通信,特别是安装目录,是否存在“最佳实践”?考虑到两个安装程序都是用WiX编写的,通信怎么样?
答案 0 :(得分:3)
是的,您可以使用Windows Installer数据库,在某些情况下,无需自定义操作!
标准表和操作支持搜索已安装的组件。因此,如果您的应用程序目录中安装了某个组件(例如,您的应用程序.exe),并且您提供了固定的GUID,那么您的插件安装程序就可以找到它。
由于您需要在所有项目中使用“MainComponentGuid”,因此请将其作为define
文件中的Include
提取出来。
插件创作:
<?include ../MainSetup/MainComponentGuid.wxi?>
<Property Id="MAINDIR">
<ComponentSearch Id="MainComponentSearch" Type="file" Guid="$(var.MainComponentGuid)">
<DirectorySearch Id="MainComponentDirectorySearch" AssignToProperty="yes" Depth="0" />
</ComponentSearch>
</Property>
<CustomAction Id="SetInstallFolder" Directory="INSTALLFOLDER" Value="[MAINDIR]" />
<InstallExecuteSequence>
<Custom Action="SetInstallFolder" After="CostFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
在您的目录结构中,您将Packages
设为INSTALLFOLDER
的孩子。除非安装了主要产品,否则您还可以在MAINDIR
中使用LaunchCondition
来阻止安装插件。
答案 1 :(得分:1)
在安装期间编写注册表项然后找到它是simple using WIX。
您可以使用以下方法创建密钥:
<Component Id="RegistryEntries" Guid="PUT-GUID-HERE">
<RegistryKey Root="HKCU"
Key="Software\MyApplicationName"
Action="createAndRemoveOnUninstall">
<RegistryValue Action="write" Name="InstallDir" Type="string" Value="[INSTALLDIR]" />
</RegistryKey>
</Component>
此处InstallDir
是一个WIX属性,其中设置了用户选择的软件目标路径。完成此密钥设置后,您可以在插件安装程序中查找(假设插件有单独的安装程序),使用以下示例:
<Property Id="AnyNameYouLike">
<RegistrySearch Id="YourRegistrySearchId"
Root="HKCU"
Key="Software\MyApplicationName"
Name="InstallDir"
Type="raw" />
</Property>
此代码会将属性AnyNameYouLike
的值设置为InstallDir
中存储的路径。在打算使用路径之前,您可以将此代码放在某处。
或者,您可以在Windows ProgramData\YourApp
或Users
文件夹中创建一个文件来存储安装位置,如果您真的想避免使用注册表内容。
答案 2 :(得分:0)
1)检查主产品是否在HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall \
中写入InstallLocation密钥2)如果没有这样的密钥,请设置ARPINSTALLLOCATION property
3)如果密钥是由主产品编写的 - 只需使用RegistryLocator读取该值并设置TARGETDIR。