Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以编程方式构建MSI_C#_Visual Studio 2008_Installation - Fatal编程技术网

C# 以编程方式构建MSI

C# 以编程方式构建MSI,c#,visual-studio-2008,installation,C#,Visual Studio 2008,Installation,我想创建一个C#程序,该程序基于多个参数创建MSI。例如,根据用户设置,将包括某些文件,或设置运行时参数 有没有人能给我指一些可能有用的文档,或者给我一个从哪里开始的想法?我想看看。它有一个相当陡峭的学习曲线,但它将产生msi作为项目构建周期的一部分。如果你真的想在代码中这样做,你会想看看。但是,它构建了一个很好的托管工具集,这将使使用XML语言编写MSI更加容易。他们还将许多Windows Installer API包装在托管包装中,但要充分发挥Windows Installer的功能,您需要

我想创建一个C#程序,该程序基于多个参数创建MSI。例如,根据用户设置,将包括某些文件,或设置运行时参数


有没有人能给我指一些可能有用的文档,或者给我一个从哪里开始的想法?我想看看。它有一个相当陡峭的学习曲线,但它将产生msi作为项目构建周期的一部分。

如果你真的想在代码中这样做,你会想看看。但是,它构建了一个很好的托管工具集,这将使使用XML语言编写MSI更加容易。他们还将许多Windows Installer API包装在托管包装中,但要充分发挥Windows Installer的功能,您需要查看API文档。

签出-一组C库,允许您用C代码表达安装。然后将其转换为WiX(XML)文件,然后对其进行编译和链接,以创建标准MSI(Windows Installer)文件。

我一直在使用WixSharp(WiX#),原因如下所述。我发现XML驱动的安装程序太难看和不直观,无法处理,也就是说,将编辑XML文件作为构建安装程序的一种方式。我深入研究了基于C语言的WiX,认为它是一种更为平易近人的选择。在我的例子中,我需要生成一个MSI来在服务器上安装一个.NETDLL(不在GAC中),然后为COM互操作注册它

更多信息请访问Wix的CodePlex主页:

对于OP描述的安装类型,“功能”的MSI/WiX概念似乎适用,例如,用户可以选中一个框来安装或省略某些功能(“功能”可以是一组文件/程序、一组注册表项等)

在WiX安装程序中,您可以在C安装程序代码的顶部声明一个带有“ID”的“功能”,例如二进制文件、文档、注册表项等,然后在声明其他安装程序组件时引用该功能ID。(请参阅Wix安装附带的“示例”文件夹中的“AllInOne”Wix代码)

请注意,功能ID“binaries”如何成为声明文件和FileShortcut组件的第一个参数,即“new File(binaries…)并将这些组件链接到功能ID“binaries”中

此外,MSI安装程序允许您在命令行上指定功能ID,例如

msiexec/i install.msi ADDLOCAL=二进制文件

另请参见本帖:

虽然WiX可以查看目标系统并确定要安装什么,但我没有看到看起来直观的WiX示例,只有使用自定义操作(WiX支持)的潜在例外。使安装程序的行为适应目标系统的一种方法是使用自定义操作设置属性,如WiX示例中所示。”Wix部署中的“有条件安装”

                //setting property to be used in install condition
                new Property("INSTALLDESKTOPSHORTCUT", "no"),
                new ManagedAction(@"MyAction", Return.ignore, When.Before, Step.LaunchConditions, Condition.NOT_Installed, Sequence.InstallUISequence));
在Wix#安装程序的前面链接回此代码:

                 new Dir(@"%Desktop%",
                    new ExeFileShortcut("MyApp", "[INSTALLDIR]MyApp.exe", "")
                    {
                        Condition = new Condition("INSTALLDESKTOPSHORTCUT=\"yes\"") //property based condition
                    }),
请注意,大括号中的“条件”被设置为测试属性“INSTALLDESKTOPSHORTCUT”的值“yes”,该值被设置为自定义操作的结果

public class CustomActions
{
    [CustomAction]
    public static ActionResult MyAction(Session session)
    {
        if (DialogResult.Yes == MessageBox.Show("Do you want to install desktop shortcut", "Installation", MessageBoxButtons.YesNo))
            session["INSTALLDESKTOPSHORTCUT"] = "yes";

        return ActionResult.Success;
    }
}
对于C#skillset来说,另一种方法是在msi安装程序的前端安装一个C#程序,该程序执行以下操作:

  • 查看目标系统用户设置,确定哪些功能适合安装在该系统上
  • 汇编并格式化msiexec命令行和选定功能的功能参数
  • 执行MSIExec命令行
可能还有其他“更整洁”的地方“实现这一点的方法,例如,涉及自定义操作等。然而,从C#技能集来看,这种方法是可接近的,并且有助于Windows Installer/WiX学习曲线。我在从事Wix安装程序的工作时发现,它帮助我逐步学习了一些Wix和Windows安装程序。我经常寻找如何在WiX中执行特定的部署任务,然后将WiX方法转换为WiX,以使WiX在它生成的.wxs文件中生成所需的XML

在那些我不知道如何让Wix完成某项部署任务的情况下,我通常可以简单地将Wix XML语句包含在Wix生成的.wxs文件中,例如,通过手动编辑.wxs文件

例如,WiX和WiX#,提供不属于“受支持”目的地之一的特定驱动器和路径的方式是不直观的。我发现从Wix#将这个xml片段添加到生成的.wxs文件中,然后手动运行Candle和Light,对我来说成功了

我记得曾经遇到过一些例子,说明如何让Wix#C#代码以编程方式在.wxs语句中包含XML,然后编译.wxs以生成msi。如果我再次发现Wix示例,我将更新此答案

更新我确实找到了示例代码。。。Wix附带的Wix#examples文件夹中的Wix#代码示例中有几个。然而,它们并没有按照我希望的方式工作,还涉及到我还不熟悉的其他Wix类和对象。我想使用“标准”XMLC工具集,而不是特定于Wix的类,将Wix输出作为XML文本处理。因此,我尝试解析.wxs文档XML,但未能使用XPath导航到要插入其他WIXXML语句的位置。(也许我会发布一个SO问题来寻求帮助)。然而,通过使用WIXXML的文本替换(被视为文本字符串),我确实实现了我想要的。下面是我成功工作的原因

代码所做的是为Compiler.WixSourceSaved事件分配一个委托,当在Wix代码中调用“Compiler.BuildMsi”方法时,会触发此事件。在读取创建的.wxs文件之后(但在从wxs构建MSI文件之前),我将文件中的文本更新为
public class CustomActions
{
    [CustomAction]
    public static ActionResult MyAction(Session session)
    {
        if (DialogResult.Yes == MessageBox.Show("Do you want to install desktop shortcut", "Installation", MessageBoxButtons.YesNo))
            session["INSTALLDESKTOPSHORTCUT"] = "yes";

        return ActionResult.Success;
    }
}
 // ...
internal class Script
    static string myWIX_SET_DIRECTORY_STATEMENT = "    <SetDirectory Id=\"INSTALLDIR\" Value=\"D:\\Program Files\\DOL\\WA.DOL.HQSYS.ExecECL\" />";
    static string myWIX_INSERT_AFTER_TEXT = "    <InstallExecuteSequence >";
    public static void Main()
    {
    // ... (your other Wix# code goes here...)
        // Hook an event to Wix# save of .wxs file to post-process the .wxs
        Compiler.WixSourceSaved += PostProcessWxsXMLOutput;

        // Trigger the MSI file build
        Compiler.BuildMsi(project);
    }

    /// <summary>
    /// Post-process the Wix .wxs file before compiling it into an MSI
    /// </summary>
    /// <param name="wxsFileName"></param>
    private static void PostProcessWxsXMLOutput(string wxsFileName)
    {
        StreamReader sr = new StreamReader(wxsFileName);
        string myWixDocument = sr.ReadToEnd();
        sr.Close();
        string myProcessedWixDocument = WiXHelpers.InsertFragmentInWiXDocument(myWixDocument, myWIX_INSERT_AFTER_TEXT, myWIX_SET_DIRECTORY_STATEMENT);
        StreamWriter sw = new StreamWriter(wxsFileName);
        sw.Write(myProcessedWixDocument);
        sw.Close();
    }
Compiler.BuildWxs(Project)