在安装时检测目录是否存在

发布于 2024-10-16 11:49:34 字数 1464 浏览 1 评论 0原文

在 WiX 中,DirectorySearch 可用于确定目标计算机上是否存在特定目录。但我不明白是否有一致的方法来确定目录不存在存在。

例如:

<Property Id="INSTALLDIR" Secure="yes">
  <RegistrySearch Id='InstallDir' Type='directory'
    Root='HKLM' Key='Software\Company\Product\Install' Name='InstallPath'/>
</Property>
<Property Id='IS_INSTALLED' Secure='yes'>
  <DirectorySearch Id='IsInstalled' Path='[INSTALLDIR]' />
</Property>

当注册表项和目录都存在时,IS_INSTALLED 属性将设置为 DirectorySearch 返回的路径。

当目录不存在时,IS_INSTALLED 显示为“C:\”。

是否存在类似以下情况的条件:

<Condition>NOT (IS_INSTALLED = "C:\")</Condition>

检测是否已找到目录的可靠方法?有更好的办法吗?

答案:这是基于我接受的mrnxs答案的WiX代码

<Property Id="PRODUCT_IS_INSTALLED" Secure="yes">
  <RegistrySearch Id='RegistrySearch1' Type='directory'
    Root='HKLM' Key='Software\Company\Product\Version\Install' Name='Path'>
    <DirectorySearch Id='DirectorySearch1' Path='[PRODUCT_IS_INSTALLED]'/>
  </RegistrySearch>
</Property>

<CustomAction Id='SET_INSTALLDIR'
              Property='INSTALLDIR'
              Value='[PRODUCT_IS_INSTALLED]'/>

<InstallExecuteSequence>
  <Custom Action='SET_INSTALLDIR' After='AppSearch'></Custom>
</InstallExecuteSequence>

In WiX DirectorySearch can be used to determine if a specific directory exists on the target computer. But I don't understand if there's a consistent way to determine that a directory does not exist.

For example:

<Property Id="INSTALLDIR" Secure="yes">
  <RegistrySearch Id='InstallDir' Type='directory'
    Root='HKLM' Key='Software\Company\Product\Install' Name='InstallPath'/>
</Property>
<Property Id='IS_INSTALLED' Secure='yes'>
  <DirectorySearch Id='IsInstalled' Path='[INSTALLDIR]' />
</Property>

When both the registry key and the directory exist, the IS_INSTALLED property is set to the path returned by DirectorySearch.

When the directory does not exist, IS_INSTALLED appears to be set to "C:\".

Is a condition like:

<Condition>NOT (IS_INSTALLED = "C:\")</Condition>

a reliable way to detect that the directory was found? Is there a better way?

Answer: Here is WiX code based on mrnxs answer that I accepted

<Property Id="PRODUCT_IS_INSTALLED" Secure="yes">
  <RegistrySearch Id='RegistrySearch1' Type='directory'
    Root='HKLM' Key='Software\Company\Product\Version\Install' Name='Path'>
    <DirectorySearch Id='DirectorySearch1' Path='[PRODUCT_IS_INSTALLED]'/>
  </RegistrySearch>
</Property>

<CustomAction Id='SET_INSTALLDIR'
              Property='INSTALLDIR'
              Value='[PRODUCT_IS_INSTALLED]'/>

<InstallExecuteSequence>
  <Custom Action='SET_INSTALLDIR' After='AppSearch'></Custom>
</InstallExecuteSequence>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

给不了的爱 2024-10-23 11:49:34

通常,当属性用作基于属性的文件夹时,会发生这种情况。在这种情况下,CostFinalize 操作会自动将该属性设置为有效路径(例如“C:\”),以便 Windows Installer 可以使用该文件夹。

由于此路径是自动生成的,因此您无法确定它在所有客户端计算机上都是“C:\”,因此您不应在您的情况下使用此值。相反,您可以尝试以下操作:

  • 为文件夹使用自定义属性,
  • 使用类型 51 自定义操作(使用格式化文本设置的属性)将此属性设置为有效的默认路径(例如“[ProgramFilesFolder]MyCompany\MyProduct”)
  • 使用另一个属性进行搜索
  • 使用另一个类型 51 自定义将文件夹属性设置为搜索属性的操作

例如,如果您的搜索是 IS_INSTALLED,则您的文件夹可以使用 IS_INSTALLED_PATH。 IS_INSTALLED_PATH 可以设置为默认路径,并且在 AppSearch 操作之后,如果搜索发现某些内容,您可以将其设置为 IS_INSTALLED。

您可以通过这种方式进行调理:

IS_INSTALLED

NOT IS_INSTALLED

Usually this happens when the property is used as a property-based folder. In this case the CostFinalize action automatically sets the property to a valid path (for example "C:\") so the folder can be used by Windows Installer.

Since this path is generated automatically, you cannot be sure that it will be "C:\" on all your client machines, so you shouldn't use this value in your condition. Instead, you can try this:

  • use a custom property for your folder
  • use a type 51 custom action (property set with formatted text) to set this property to a valid default path (for example "[ProgramFilesFolder]MyCompany\MyProduct")
  • use another property for the search
  • use another type 51 custom action to set the folder property to your search property

For example, if your search is IS_INSTALLED your folder can use IS_INSTALLED_PATH. IS_INSTALLED_PATH can be set to a default path and after AppSearch action you can set it to IS_INSTALLED if the search found something.

This way you can use for conditioning:

IS_INSTALLED

or

NOT IS_INSTALLED
相思碎 2024-10-23 11:49:34

理解 AppSearch 的 RegLocator 和 DrLocator 模式可能有点棘手。我建议暂时忽略该条件并记录安装以验证 AppSearch 是否正确设置了您想要的属性。首先解决您在那一端发现的问题。当它起作用时,该属性将被设置为注册表的值或目录的路径。

那么你应该能够使用:

<Condition>IS_INSTALLED/>   <!-- it's not important what the value is, just that it exists -->
<Condition>Not IS_INSTALLED/>

顺便说一句,我会避免使用属性 INSTALLDIR。在我的安装程序(InstallShield)中,它作为安装的主要焦点具有特殊的意义。

Understaing AppSearch's RegLocator and DrLocator patterns can be a little tricky. I reccomend ignoring the condition for a moment and logging the install to verify that AppSearch is properly setting the properties you want. Fix the problems you find on that end first. When it works the property will be set to the value of the registry or the path to the directory.

Then you should be able to use:

<Condition>IS_INSTALLED/>   <!-- it's not important what the value is, just that it exists -->
<Condition>Not IS_INSTALLED/>

Btw, I would avoid using the property INSTALLDIR. In my installers ( InstallShield ) that has special meaning as the main focal point of the installation.

舟遥客 2024-10-23 11:49:34

另一种方法可能是这样,如果您想将 InstallDir 设置为其他任何位置,并且 SystemDir 和 RegisteryDir 不同,您可以继续安装顺序

<Property Id="RegisteryDir" Secure="yes">
<RegistrySearch Id='InstallDir' Type='directory'
Root='HKLM' Key='Software\Company\Product\Install' Name='InstallPath'/>
</Property>
<Property Id='SystemDir' Secure='yes'>
<DirectorySearch Id='IsInstalled' Path='[RegisteryDir]' />
</Property>
<CustomAction Id="SET_INSTALL_DIR" Property="INSTALLDIR" Value="[SystemDir] />

<InstallExecuteSequence>
<Custom Action='SET_INSTALLDIR' After='AppSearch'>
SystemDir AND SystemDir=RegisteryDir
</Custom>
</InstallExecuteSequence> 

Another approach could be this, in this you can continue the Install Sequence if you want to set the InstallDir to anywhere else, if the SystemDir and RegisteryDir is not same

<Property Id="RegisteryDir" Secure="yes">
<RegistrySearch Id='InstallDir' Type='directory'
Root='HKLM' Key='Software\Company\Product\Install' Name='InstallPath'/>
</Property>
<Property Id='SystemDir' Secure='yes'>
<DirectorySearch Id='IsInstalled' Path='[RegisteryDir]' />
</Property>
<CustomAction Id="SET_INSTALL_DIR" Property="INSTALLDIR" Value="[SystemDir] />

<InstallExecuteSequence>
<Custom Action='SET_INSTALLDIR' After='AppSearch'>
SystemDir AND SystemDir=RegisteryDir
</Custom>
</InstallExecuteSequence> 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文