如果在同一个树中多次使用WiX DirectorySearch/@ Depth,则会被忽略

Kri*_*erA 5 windows-installer wix wix3.7

我有一个WiX安装程序,可以将一堆扩展文件安装到另一个应用程序的app目录中.为了确保文件最终位于正确的位置,我使用一堆嵌套的DirectorySearch来查找app目录.

该应用程序通常安装在此模式之后的路径中:

\Program Files (x86)\CompanyName\ProductName\[version]\[environment]\[optional intermediate folder]\AppFolderName
Run Code Online (Sandbox Code Playgroud)

换句话说,常见的安装文件夹包括:

\Program Files (x86)\CompanyName\ProductName\1.0\Prod\AppFolderName
\Program Files (x86)\CompanyName\ProductName\1.1\Prod\OptionalFolderName\AppFolderName
\Program Files (x86)\CompanyName\ProductName\1.2\Test\AppFolderName
\Program Files (x86)\CompanyName\ProductName\1.2\Test\OptionalFolderName\AppFolderName
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我使用一组嵌套的DirectorySearch元素来分配Property的路径.如果存在可选文件夹(OptionalFolderName),则以下内容有效:

<Property Id="SOMEAPPFOLDER">
  <DirectorySearch Id="ProgramFilesFolder" Path="[ProgramFilesFolder]">
    <DirectorySearch Id="CompanyNameFolder" Path="CompanyName">
      <DirectorySearch Id="ProductFolder" Path="ProductName">
          <DirectorySearch Id="EnvironmentFolder" Path="$(var.ENVIRONMENTNAME)" Depth="2">
            <DirectorySearch Id="OptionalIntermediateFolder" Path="OptionalFolderName">
              <DirectorySearch Id="AppFolder" Path="AppFolderName" AssignToProperty="yes">
                <FileSearch Id="AppNameExe" Name="AppName.exe" MinVersion="$(var.MIN_VERSION).0" MaxVersion="$(var.MAX_VERSION).999" />
              </DirectorySearch>
            </DirectorySearch>
        </DirectorySearch>
      </DirectorySearch>
    </DirectorySearch>
  </DirectorySearch>
</Property>
Run Code Online (Sandbox Code Playgroud)

但是,由于OptionalFolderName是可选的,我想使用DirectorySearch来确定app文件夹是直接位于环境文件夹下还是一个级别.为了做到这一点,我将搜索树更改为:

<Property Id="SOMEAPPFOLDER">
  <DirectorySearch Id="ProgramFilesFolder" Path="[ProgramFilesFolder]">
    <DirectorySearch Id="CompanyNameFolder" Path="CompanyName">
      <DirectorySearch Id="ProductFolder" Path="ProductName">
        <DirectorySearch Id="EnvironmentFolder" Path="$(var.ENVIRONMENTNAME)" Depth="2">
          <DirectorySearch Id="AppFolder" Path="AppFolderName" Depth="2" AssignToProperty="yes">
            <FileSearch Id="AppNameExe" Name="AppName.exe" MinVersion="$(var.MIN_VERSION).0" MaxVersion="$(var.MAX_VERSION).999" />
          </DirectorySearch>
        </DirectorySearch>
      </DirectorySearch>
    </DirectorySearch>
  </DirectorySearch>
</Property>
Run Code Online (Sandbox Code Playgroud)

后来的版本但是也没有如果可选的文件夹是目前的工作,但它的工作,如果它不存在.换句话说,就好像其中一个Depth属性是isgnored; 我的猜测是因为我在树中的不同级别使用了两次Depth属性.

关于我如何解决这个问题的任何建议?


更新 - 从msiexec/i添加日志片段摘录[msiname]/l*v [logfile]:

Action 14:38:47: AppSearch. Searching for installed applications
Action start 14:38:47: AppSearch.
AppSearch: Property: SOMEAPPFOLDER, Signature: AppFolder
MSI (c) (00:90) [14:38:47:065]: Note: 1: 1322 2:  
MSI (c) (00:90) [14:38:47:065]: Note: 1: 1322 2:  
MSI (c) (00:90) [14:38:47:065]: Note: 1: 1324 2: [environmentname] 3: 1 
MSI (c) (00:90) [14:38:47:065]: Note: 1: 1325 2: CompanyName 
Action ended 14:38:47: AppSearch. Return value 1.
MSI (c) (00:90) [14:38:47:066]: Doing action: LaunchConditions
MSI (c) (00:90) [14:38:47:067]: Note: 1: 2205 2:  3: ActionText 
Action 14:38:47: LaunchConditions. Evaluating launch conditions
Action start 14:38:47: LaunchConditions.
MSI (c) (00:A8) [14:38:47:069]: Font created.  Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg

Couldn't find the AppFolderName app folder for [environment/version].
MSI (c) (00:90) [14:38:48:543]: Note: 1: 2205 2:  3: Error 
MSI (c) (00:90) [14:38:48:543]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1709 
MSI (c) (00:90) [14:38:48:543]: Product: [productname] -- Couldn't find the AppFolderName app folder for [environment/version].

Action ended 14:38:48: LaunchConditions. Return value 3.
Run Code Online (Sandbox Code Playgroud)

Abd*_*ahC 6

使用Depthwhen的行为FileSearch

DepthFileSearch它的直系后代时,它的工作方式不同DirectorySearch.

在正常情况下,Depth指定指定路径上方的最大文件夹级别数.但是,如果FileSearch是直接后代,则Depth指定在指定路径查找文件的最大文件夹级别数.

换句话说,没有办法指定作为文件的直接父级的目录的深度.

我们来看看你粘贴的代码:

<Property Id="SOMEAPPFOLDER">
  <DirectorySearch Id="ProgramFilesFolder" Path="[ProgramFilesFolder]">
    <DirectorySearch Id="CompanyNameFolder" Path="CompanyName">
      <DirectorySearch Id="ProductFolder" Path="ProductName">
        <DirectorySearch Id="EnvironmentFolder" Path="$(var.ENVIRONMENTNAME)" Depth="2">
          <DirectorySearch Id="AppFolder" Path="AppFolderName" Depth="2" AssignToProperty="yes">
            <FileSearch Id="AppNameExe" Name="AppName.exe" MinVersion="$(var.MIN_VERSION).0" MaxVersion="$(var.MAX_VERSION).999" />
          </DirectorySearch>
        </DirectorySearch>
      </DirectorySearch>
    </DirectorySearch>
  </DirectorySearch>
</Property>
Run Code Online (Sandbox Code Playgroud)

在上面,第一次使用Depth允许ProductFolder和EnvironmentFolder之间的两个目录级别,但第二次使用时Depth指的是AppFolder和之间的级别数AppNameExe.

解决方法

以下xml使用两个搜索来解决此问题:

<!-- Locate the parent directory first -->
<Property Id="SOMEAPPFOLDER">
  <DirectorySearch Id="ProgramFilesFolder" Path="[ProgramFilesFolder]">
    <DirectorySearch Id="CompanyNameFolder" Path="CompanyName">
      <DirectorySearch Id="ProductFolder" Path="ProductName">
        <DirectorySearch Id="EnvironmentFolder" Path="$(var.ENVIRONMENTNAME)" Depth="1">
          <DirectorySearch Id="AppFolder" Path="AppFolderName" Depth="1" />
        </DirectorySearch>
      </DirectorySearch>
    </DirectorySearch>
  </DirectorySearch>
</Property>

<!-- Now, look for the file in the above directory -->
<Property Id="APPFILEEXISTS">
  <DirectorySearch Id="AppFolder" Path="SOMEAPPFOLDER">
    <FileSearch Id="AppNameExe" Name="AppName.exe" MinVersion="$(var.MIN_VERSION).0"
      MaxVersion="$(var.MAX_VERSION).999" />
  </DirectorySearch>
</Property>
Run Code Online (Sandbox Code Playgroud)