我正在创建一个MSI安装程序,需要在PATH
环境变量中添加多个条目。根据{{3}}:
每行只能包含一个值。例如,条目
Value;Value;[~]
不止一个值,因此不会使用,因为它会导致不可预测的结果。条目Value;[~]
只是一个值。
我的安装程序源代码目前看起来像这样(注意,这是每台计算机的安装),这违反了上述文档:
<!-- NOTE: These two features are mutually exclusive -->
<Feature Id="Feature1" Level="1000" Absent="allow" AllowAdvertise="no" InstallDefault="local" TypicalDefault="install">
<Component Directory="INSTALLFOLDER">
<RegistryValue Action="write" Type="int" Root="HKLM" Key="SOFTWARE\MyProduct" Name="MyPathEntry1" Value="1" KeyPath="yes" />
<Environment Id="AddPathEntry1" Name="PATH" Value="[INSTALLFOLDER]SubDir1" Action="set" Permanent="yes" Part="last" System="yes" />
</Component>
</Feature>
<Feature Id="Feature2" Level="1000" Absent="allow" AllowAdvertise="no" InstallDefault="local" TypicalDefault="install">
<Component Directory="INSTALLFOLDER">
<RegistryValue Action="write" Type="int" Root="HKLM" Key="SOFTWARE\MyProduct" Name="MyPathEntry2" Value="1" KeyPath="yes" />
<Environment Id="AddPathEntry2" Name="PATH" Value="[INSTALLFOLDER]SubDir1;[INSTALLFOLDER]SubDir2;[INSTALLFOLDER]SubDir3" Action="set" Permanent="yes" Part="last" System="yes" />
</Component>
</Feature>
现在即使上面的“技术上”违反了MSDN文档,它似乎也有效。我测试了新安装,修改安装和升级。一切似乎没有任何障碍。但是我在MSI学到的一件事就是尽可能地遵循规则以避免弄乱人们的机器。
添加仅包含单个路径组件的独立(即非互斥)功能的自然解决方案将不起作用,因为使用MSI,您无法保证安装功能和/或组件的顺序。但是,在这种情况下,路径组件添加到PATH
环境变量的顺序很重要,因为在查找不合格的可执行文件时如何使用PATH
变量。
可能会浮现的另一个问题是,为什么我要使用功能?我想通过标准的“添加/删除程序”或“程序和功能控制面板”小程序,为产品的安装人员提供更改安装选项的选项。
那么,如何在遵循MSDN推荐的指导的同时,以确定的顺序向PATH
环境变量添加多个路径条目?或者MSDN的指导是否过时,我目前正在做的事情是完全正常的?
答案 0 :(得分:0)
我想办法做到这一点,不违反MSDN对我特定情况的指导。
确切的情况是我有一个主程序可执行文件,安装程序可能希望也可能不希望能够从Windows命令外壳程序运行。此外,还有其他实用程序,安装程序可能也可能不希望从Windows命令行管理程序运行。
最初建模的方式是使用单选按钮决定如何更新系统PATH
环境变量的一组3个互斥功能。 3个功能归结为:
PATH
环境变量(即只能在任何目录位置键入可执行文件的名称,无法从Windows命令行管理程序运行程序和可选工具。)PATH
环境变量,以便只能在任何给定路径上从Windows命令行管理程序运行主可执行文件。PATH
环境变量以添加其他实用程序工具路径。我意识到这里实际上只有两个特征,它们甚至不是相互排斥的,而是一个依赖于另一个。上面列出的第一个单选按钮实际上不是一个功能 - 它是一个无操作;它没有安装任何东西!第二个单选按钮表示“主要”功能,因为主要可执行文件的目录已添加到系统的PATH
中。第三个单选按钮取决于第二个:如果主要可执行文件已添加到PATH
,那么您还可以向PATH
添加其他实用程序。
这会产生更简单的用户界面。使用复选框代替单选按钮,除非选中第一个复选框,否则将禁用第二个复选框。这也导致更简单的实现,以确保所选功能的组合(例如,对于命令行安装)有效。
简而言之,这就是WiX XML在我的特定情况下可以归结为什么。我确信这可以推广(或修改)以适应其他类似场景。
<Feature Id="AddExeToPath" Level="1" Absent="allow" AllowAdvertise="no" InstallDefault="local" TypicalDefault="install">
<Component Id="ExePath" Guid="{YOURGUID-HERE-0000-0000-00000000}" Directory="INSTALLFOLDER">
<CreateFolder />
<Environment Id="ExePath" Name="MY_PATHS" Value="[INSTALLFOLDER]SubDir1" Action="set" Part="first" System="yes" />
</Component>
<Component Directory="INSTALLFOLDER">
<RegistryValue Action="write" Type="integer" Root="HKLM" Key="SOFTWARE\MyProduct" Name="AddExeToPath" Value="1" KeyPath="yes" />
<Environment Id="AddToPath" Name="PATH" Value="%MY_PATHS%" Action="set" Part="last" System="yes" />
</Component>
<Component Id="RemoveExeFromPathOnUninstall" Guid="{YOURGUID-HERE-0000-0000-00000000}" Directory="INSTALLFOLDER">
<Condition>REMOVE><AddExeToPath OR REMOVE="ALL"</Condition>
<Environment Id="RemoveFromPath" Name="PATH" Value="%MY_PATHS%" Action="remove" />
</Component>
</Feature>
<Feature Id="AddToolsToPath" Level="1000" Absent="allow" AllowAdvertise="no" InstallDefaut="local" TypicalDefault="install">
<Component Id="SubDir2" Guid="{YOURGUID-HERE-0000-0000-00000000}" Directory="INSTALLFOLDER">
<CreateFolder />
<Environment Id="SubDir2" Name="MY_TOOLS" Value="[INSTALLFOLDER]SubDir2" Action="set" Part="first" System="yes" />
</Component>
<Component Id="SubDir3" Guid="{YOURGUID-HERE-0000-0000-00000000}" Directory="INSTALLFOLDER">
<CreateFolder />
<Environment Id="SubDir3" Name="MY_TOOLS" Value="[INSTALLFOLDER]SubDir3" Action="set" Part="last" System="yes" />
</Component>
<Component Directory="INSTALLFOLDER">
<RegistryValue Action="write" Type="integer" Root="HKLM" Key="SOFTWARE\MyProduct" Name="AddToolsToPath" Value="1" KeyPath="yes" />
<Environment Id="AddToolsToPath" Name="MY_PATHS" Value="%MY_TOOLS%" Action="set" Part="last" System="yes" />
</Component>
</Feature>
<CustomAction Id="InvalidPathFeatureSelection" Error="25000" Execute="firstSequence" />
<InstallExecuteSequence>
<Custom Action="InvalidPathFeatureSelection" Before="InstallValidate">
<![CDATA[NOT (REMOVE="ALL" OR (&AddToolsToPath >= 3 IMP &AddExeToPath >= 3))]]>
</Custom>
</InstallExecuteSequence>
这组功能和组件产生以下结果:
如果选择要安装的功能 AddExeToPath ,则会导致该功能的以下组件出现:
MY_PATHS
的环境变量,其中包含主可执行文件的路径。PATH
,将%MY_PATHS%
放在最后的当前值。如果选择了 AddToolsToPath 功能,则会安装3个组件:
MY_TOOLS
,并将[INSTALLFOLDER]SubDir2
放在前面 变量的现有值(如果有) MY_TOOLS
,并将[INSTALLFOLDER]SubDir3
放在结束 变量的现有值(如果有)中。 注意强>
这两个组件定义了它们确保添加到MY_TOOLS
的路径以适当顺序添加的方式。
MY_PATHS
已更新,%MY_TOOLS%
位于现有变量的 结束 ;再次,这保留了正确的路径排序。所以你最终得到的是:
MY_TOOLS
= [INSTALLFOLDER]SubDir2;[INSTALLFOLDER]SubDir3
MY_PATHS
= [INSTALLFOLDER]SubDir1;%MY_TOOLS%
PATH
= <existing_PATH_value>;%MY_PATHS%