【问题标题】:Custom Action in Wix to manipulate string and set propertyWix 中的自定义操作来操作字符串和设置属性
【发布时间】:2019-03-01 01:35:27
【问题描述】:

您好,我正在使用 Wix 创建一个安装程序,该安装程序必须使用安装程序在用户系统上复制的文件的路径写入注册表值。问题是注册表项要写成这种格式

file:///C:/Program Files/....

在 Wix 代码项目中,我有指向

的 INSTALLFOLDER 目录 ID
C:\Program Files\....

我真的很难将后一种表示法转换为前一种。我创建了一个自定义操作,希望设置一个属性以便我可以使用它。以下是代码

自定义操作(现在是单独的 DLL,可以内联吗?)

 public class CustomActions
    {
        [CustomAction]
        public static ActionResult CustomAction1(Session session)
        {
            session.Log("Begin CustomAction1");
            string origValue = session["INSTALLFOLDER"];
            MessageBox.Show(origValue);
            string retVal = origValue.Replace("\\", "//");
            MessageBox.Show(retVal);
            session["Custom_Prop"] = retVal;
            return ActionResult.Success;
        }
    }

还有 Product.wxs

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <Product Id="*" Name="SetupProject1" Language="1033" Version="1.2.0.0" Manufacturer="nik" UpgradeCode="4a74ff86-49a9-4011-9794-e1c18077172f">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

    <Feature Id="ProductFeature" Title="SetupProject1" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>

    <InstallExecuteSequence>
      <Custom Action='FooAction' Before='InstallFinalize'>NOT Installed</Custom>
    </InstallExecuteSequence>

  </Product>

  <Fragment>
    <CustomAction Id='FooAction' BinaryKey='FooBinary' DllEntry='CustomAction1' Execute='immediate'
                  Return='check'/>

    <Binary Id='FooBinary' SourceFile='MyCustomAction.CA.dll'/>
  </Fragment>


  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="SetupProject1" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <Property Id="Custom_Prop" Value="[ProgramFilesFolder]"></Property>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
      <!-- <Component Id="ProductComponent"> -->
      <!-- TODO: Insert files, registry keys, and other resources here. -->
      <!-- </Component> -->
      <Component Id="cmp_Add_Mainfest_To_Registry" Guid="955A3A76-F010-4FCB-BCAF-B297AFD1C05B">

        <RegistryKey Root="HKCU" Key="SOFTWARE\company">

          <RegistryValue Name="LoadBehavior" Value="3" Type="integer" Action="write" />

          <RegistryValue Name="Manifest" Value="[Custom_Prop]" Type="string" Action="write"  KeyPath="yes"/>
        </RegistryKey>
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

但是,当我运行此设置时,注册表中写入的值是文字字符串 [ProgramFolder],而不是其对 C:\ 或 C:/ 的评估

有人可以帮忙吗?

【问题讨论】:

    标签: c# wix


    【解决方案1】:

    我的代码不起作用的原因是这一行

     <InstallExecuteSequence>
          <Custom Action='FooAction' Before='InstallFinalize'>NOT Installed</Custom>
        </InstallExecuteSequence>
    

    如下改变 Before 属性的值使这项工作生效

    <InstallExecuteSequence>
          <Custom Action='FooAction' Before='CostFinalize'>NOT Installed</Custom>
        </InstallExecuteSequence>
    

    但是,鉴于我的需求非常简单,我决定不为 CustomAction 提供单独的 DLL,而是在 Wix 项目中的 vbscript 中使用自定义操作。所以现在代码看起来像

    <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    
      <Product Id="*" Name="SetupProject1" Language="1033" Version="1.3.1.0" Manufacturer="nik" UpgradeCode="4a74ff86-49a9-4011-9794-e1c18077172f">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
    
        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate />
    
        <Feature Id="ProductFeature" Title="SetupProject1" Level="1">
          <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    
         <InstallExecuteSequence>
          <Custom Action="VBScriptCommand" After="CostFinalize">NOT REMOVE</Custom>
        </InstallExecuteSequence>
    
      </Product>
    
      <Fragment>
    
    
        <CustomAction Id="VBScriptCommand" Script="vbscript">
          <![CDATA[         
        value = Session.Property("INSTALLFOLDER")
        origPath=Session.Property("INSTALLFOLDER")
        If Right(webdir, 1) = "\" Then
          value = Left(value, Len(value) - 1) 
        End If
    
        Session.Property("SOME_PROPERTY") = Replace(origPath,"\","//")      
      ]]>
        </CustomAction>
    
       </Fragment>
    
      <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
          <Directory Id="ProgramFilesFolder">
            <Directory Id="INSTALLFOLDER" Name="SetupProject1" />
          </Directory>
        </Directory>
      </Fragment>
    
      <Fragment>
        <Property Id="Custom_Prop" Value="[ProgramFilesFolder]"></Property>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
    
          <Component Id="cmp_Add_Mainfest_To_Registry" Guid="955A3A76-F010-4FCB-BCAF-B297AFD1C05B">
    
            <RegistryKey Root="HKCU" Key="SOFTWARE\something">
    
              <RegistryValue Name="LoadBehavior" Value="3" Type="integer" Action="write" />
              <!--<RegistryValue Name="Manifest" Value="[#FILE_VstoManifest]|vstolocal" Type="string" Action="write" />-->
              <RegistryValue Name="Manifest" Value="file:///[SOME_PROPERTY]" Type="string" Action="write"  KeyPath="yes"/>
            </RegistryKey>
          </Component>
        </ComponentGroup>
      </Fragment>
    </Wix>
    

    也许纯粹主义者不会喜欢这样,但为什么要用霰弹枪杀死苍蝇呢?

    【讨论】:

      【解决方案2】:

      Nikhil 帮助我回答了问题。我的安装全部转到子文件夹,所以当我找到一个旧组件时,我需要父文件夹进行安装,所以我来here 寻求答案。
      结合这个get parent 我找到了如何获取父文件夹,因为我有一个已知的固定安装子路径。

          <!-- Set INSTALLFOLDER from SERVERINSTALLFOLDER without the \Server\ -->
          <CustomAction Id="VBScriptInstallFolderFromFoundServer" Script="vbscript">
            <![CDATA[         
              pathvalue = Session.Property("SERVERINSTALLFOLDER")
              if pathvalue <> "" Then
                Session.Property("INSTALLFOLDER") = Left(pathvalue,Len(pathvalue)-Len("\Server\"))
              End If
            ]]>
          </CustomAction>
      

      结合Locate Installation directory of another product

          <Property Id="SERVERINSTALLFOLDER">
            <!-- Id="C_SERVER_SERVERHOST.EXE" Guid="{xxx GUID OF my exe component xxx}" -->
            <ComponentSearch Id="ServerComponentSearch" Type="file" Guid="{xxx GUID OF my exe component xxx}">
              <DirectorySearch Id="ServerComponentDirectorySearch" Depth="0" AssignToProperty="yes" />
            </ComponentSearch>
          </Property>
      

      还有Wix remember property pattern 将 INSTALLFOLDER 路径存储在注册表中。
      我现在可以更新旧版本,或安装新版本,并根据建议获取先前安装的正确安装路径。
      不是这个问题的答案,但是当我被带到这里得到这个答案时,我的答案将帮助其他人在同一条道路上......
      我的 InstallUISequence 和 InstallExecuteSequence :

            <!-- Save INSTALLFOLDER parameter to CMDLINE_INSTALLFOLDER -->
            <Custom Action='SaveCmdLineValue' Before='AppSearch' />
            <!-- Set INSTALLFOLDER from SERVERINSTALLFOLDER without the \Server\ -->
            <Custom Action="VBScriptInstallFolderFromFoundServer" After="AppSearch">
              SERVERINSTALLFOLDER
            </Custom>
            <!-- Set INSTALLFOLDER from parameter CMDLINE_INSTALLFOLDER -->
            <Custom Action='SetFromCmdLineValue' After='VBScriptInstallFolderFromFoundServer'>
              CMDLINE_INSTALLFOLDER
            </Custom>
      

      最后......在产品 I 中指代我放入这些的片段:

          <!-- Install to previous install path From parameter, OR from found installation OR from registry -->
          <CustomActionRef Id='SaveCmdLineValue' />
          <PropertyRef Id='INSTALLFOLDER'/><!-- include Fragment -->
          <PropertyRef Id='SERVERINSTALLFOLDER'/><!-- include Fragment -->
          <CustomActionRef Id='VBScriptInstallFolderFromFoundServer' /><!-- include Fragment -->
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多