【问题标题】:Wix Custom Actions - Reading Parameters from an XML fileWix 自定义操作 - 从 XML 文件中读取参数
【发布时间】:2014-07-11 10:17:00
【问题描述】:

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

【问题讨论】:

    标签: c# wix


    【解决方案1】:

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

    1. 添加新项目并选择 Windows Installer Xml 安装项目
    2. 添加新项目并选择 Windows Installer Xml C# 自定义操作项目
    3. 在您的设置项目中:

      • 添加要安装的内容,例如文件\网站等(请参阅其他教程了解如何执行此操作)
      • 在您的 Product.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>
    

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

    使用您在 Product.wxs 中的属性来做一些事情!例如我正在使用检索到的属性来更新已安装的 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.
    

    这篇文章的参考资料:

    Creating WiX Custom Actions in C# and Passing Parameters

    From MSI to WiX, Part 5 - Custom actions: Introduction

    Create an MSI log file

    【讨论】:

    • 嗨沙林。非常有趣的想法!我可能会将它用于我的情况。唯一的问题是 - 如何从 MSI 文件所在的本地文件夹中获取带有参数的 .xml 文件,而不是硬编码 C:\temp\Parameters.xml 的路径?自定义操作的 C# 代码中是否有任何方法可以获取调用它的 MSI 文件的位置?
    • 如果您想获取相对于 msi 运行位置的文件路径,请参阅this article
    • 嗨沙林。感谢您的回答。不幸的是,我不是 C# 开发人员,所以我很难找到通往 MSI 的道路。我可能会在单独的属性中指定 .xml 文件的路径,如 here 所述
    • 很好的详细解释。谢谢!您可以使用 引用您的 dll。如果你这样做,你需要添加对项目的引用。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多