Wix自定义操作-从XML文件读取参数

本文关键字:文件 读取 参数 XML 自定义 操作 Wix | 更新日期: 2023-09-27 18:04:40

如何编写从XML文件导入参数值以供安装期间使用的Wix安装程序?

Wix自定义操作-从XML文件读取参数

这不是一个完美的解决方案,但我花了两天时间让它工作,并想分享。毫无疑问会有一些错误,但我已经在有限的时间内尽力做好了:

  1. 添加新项目并选择Windows Installer Xml Setup Project
  2. 添加新项目并选择Windows Installer Xml c#自定义动作项目
  3. 在你的安装项目中:

    • 添加一些要安装的东西,例如文件'网站等(参见其他教程如何做到这一点)
    • 在你的产品中设置一些属性。wxs。

      <Property Id="MyProperty1" />
      <Property Id="MyProperty2" />
      
    • 在您的Product.wxs:

      中引用您新创建的自定义操作(如下)
      <Product> .....
          <Binary Id='VantageInstallerCustomActions.CA.dll' src='..'VantageInstallerCustomActions'bin'$(var.Configuration)'VantageInstallerCustomActions.CA.dll' />
          <InstallExecuteSequence>
              <Custom Action="SetInstallerProperties" Before="CostFinalize"  />
          </InstallExecuteSequence>
      </Product>
      <Fragment>
          <CustomAction Id='SetInstallerProperties' BinaryKey='VantageInstallerCustomActions.CA.dll' DllEntry='SetInstallerProperties' Return='check' Execute='immediate' />
      </Fragment>
      
  4. 将以下代码添加到您的自定义动作项目或类似的代码中:

添加CustomAction类:

    public class CustomActions
    {
     private static readonly InstallerPropertiesFileManager InstallerPropertiesFileManager = new InstallerPropertiesFileManager();
    [CustomAction]
    public static ActionResult SetInstallerProperties(Session session)
    {
        session.Log("Begin SetInstallerProperties");
        try
        {
            var doc = XDocument.Load(@"C:'temp'Parameters.xml");
            session.Log("Parameters Loaded:" + (doc.Root != null));
            session.Log("Parameter Count:" + doc.Descendants("Parameter").Count());
            var parameters = doc.Descendants("Parameter").ToDictionary(n => n.Attribute("Name").Value, v => v.Attribute("Value").Value);
            if (parameters.Any())
            {
                session.Log("Parameters loaded into Dictionary Count: " + parameters.Count());
                //Set the Wix Properties in the Session object from the XML file
                foreach (var parameter in parameters)
                {
                    session[parameter.Key] = parameter.Value;
                }
            }                
            else
            {
                session.Log("No Parameters loaded");
            }
        }
        catch (Exception ex)
        {
            session.Log("ERROR in custom action SetInstallerProperties {0}", ex.ToString());
            return ActionResult.Failure;
        }
        session.Log("End SetInstallerProperties");
        return ActionResult.Success;
    }
    }

创建C:'temp'Parameters.xml文件存储到磁盘

    <?xml version="1.0" encoding="utf-8"?>
    <Parameters>
        <Environment ComputerName="Mycomputer" Description="Installation Parameters for Mycomputer" />
        <Category Name="WebServices">
            <Parameter Name="MyProperty1" Value="http://myserver/webservice" />
            <Parameter Name="MyProperty2" Value="myconfigSetting" />
        </Category>
    </Parameters>

注意:您不需要从安装项目中引用自定义操作项目。您也不应该在安装周期的后期设置属性,这些属性在早期是必需的,例如那些用于安装文件的文件路径。我倾向于避免这些。

在产品中使用您的属性。要做点什么!例如,我正在使用检索到的属性来更新已安装的web.config

中的web服务端点
<Fragment>
    <DirectoryRef Id ="INSTALLFOLDER">
      <Component Id="WebConfig" Guid="36768416-7661-4805-8D8D-E7329F4F3AB7">
        <CreateFolder />
        <util:XmlFile Id="WebServiceEnpointUrl" Action="setValue" ElementPath="//configuration/system.serviceModel/client/endpoint['[]@contract='UserService.V1_0.GetUser.ClientProxy.Raw.IGetUserService'[']]/@address" Value="[MyProperty1]" File="[INSTALLFOLDER]web.config" SelectionLanguage="XPath" />
      </Component>
    </DirectoryRef>
  </Fragment>
与Wix安装程序一样,第一次没有任何工作。重新构建您的Wix SetupProject,并使用以下命令行在本地运行msi以打开登录:
msiexec /i "myInstaller.msi" /l*v "log.log"

运行后,打开日志文件,您应该看到以下事件:

MSI (s) (C4:3C) [11:00:11:655]: Doing action: SetInstallerProperties
Action start 11:00:11: SetInstallerProperties.
MSI (s) (C4:A8) [11:00:11:702]: Invoking remote custom action. DLL: C:'WINDOWS'Installer'MSICD83.tmp, Entrypoint: SetInstallerProperties
MSI (s) (C4:A8) [11:00:11:702]: Generating random cookie.
MSI (s) (C4:A8) [11:00:11:702]: Created Custom Action Server with PID 496 (0x1F0).
MSI (s) (C4:CC) [11:00:11:733]: Running as a service.
MSI (s) (C4:CC) [11:00:11:733]: Hello, I'm your 32bit Impersonated custom action server.
SFXCA: Extracting custom action to temporary directory: C:'Users'ak9763'AppData'Local'Temp'MSICD83.tmp-'
SFXCA: Binding to CLR version v4.0.30319
Calling custom action VantageInstallerCustomActions!VantageInstallerCustomActions.CustomActions.SetInstallerProperties
Begin SetInstallerProperties
Parameters loaded into Dictionary: 2
MSI (s) (C4!C0) [11:00:11:858]: PROPERTY CHANGE: Adding MyProperty1 property. Its value is 'http://myserver/webservice'.
MSI (s) (C4!C0) [11:00:11:858]: PROPERTY CHANGE: Adding MyProperty2 property. Its value is 'myConfigSetting'.
End SetInstallerProperties
Action ended 11:00:11: SetInstallerProperties. Return value 1.

本文参考资料:

在c#中创建WiX自定义动作和传递参数

从MSI到WiX,第5部分-自定义操作:介绍

创建MSI日志文件

一个解决方案是使用"Community MSI Extensions"

您需要的自定义操作可能是Xml_SelectNodeValue(有一个关于如何使用它的示例)。