安装 C#/WPF 应用程序 (WiX) 的冒险

Bet*_*ker 6 windows-installer wix

我有一个 C#/WPF 应用程序,它比简单的应用程序更高级 - 它有主应用程序、几个库,然后是一些 NuGet 包。如果我查看项目的 bin/release/netcoreapp3.1 目录,会发现有一个 EXE、几个 JSON 和一堆 DLL(其中一些具有 PDB)。没什么太疯狂的。客户想要一个听起来不像不合理要求的安装程序。

我首先尝试了 Visual Studio 2019 附带的安装程序,但惊讶地发现它是多么无用。删除后,我上网查了一下,发现WiX似乎比较流行。好吧,我说,我会尝试一下。

安装WiX Toolset Build Tools(听起来有点多余)和WiX Toolset Visual Studio Extension并重新启动 Visual Studio 后,看起来不错。我右键单击我的解决方案,选择“添加”和“新项目”,然后看到“Setup Project for WiX v3”,看起来不错。我单击“下一步”,将其命名为“安装程序”,然后我得到:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="Installer" Language="1033" Version="1.0.0.0" Manufacturer="" UpgradeCode="2995de5a-87ef-443d-a25a-450d39720349">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

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

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

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

    <Fragment>
        <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> -->
        </ComponentGroup>
    </Fragment>
</Wix>
Run Code Online (Sandbox Code Playgroud)

这看起来很有希望。如果我尝试构建它,则会出现错误“Product/@Manufacturer 属性的值不能是空字符串”,这是错误消息应该是什么样子的教科书示例。精确,准确地告诉我发生了什么,并为我指明需要做什么的方向。我喜欢这个!我在“制造商”属性中添加了一些文本“重建”,它显示“构建:1 成功”,并且我有一个安装程序。它确实给了我警告“媒体表没有条目”,这是完全有道理的,因为我没有告诉它安装任何文件。

我开始阅读官方 WiX教程,它冗长得令人痛苦。它实际上不是一个教程,而是一篇关于 WiX 为何如此的论文。我现在并不关心这一点,我只是想让这该死的事情发挥作用。我想要一个教程,而不是公司的整个历史。最终我找到了“入门”的链接,我感觉好多了。但同样,我并没有开始,而是得到了系统内部工作原理的冗长解释。在这一点上我不在乎。我想要一个基本的安装程序,然后你可以向我提供一些详细信息。在作者认为他或她是一位大学教授的演讲中,又看了几页之后,我终于得到了一些 XML - 它是用于我可能需要或可能不需要的媒体标签,它一点也不清楚。而且,由于为我生成的 WXS 文件中没有媒体标记,所以我不知道它去了哪里。

放弃教程,我在 Google 上搜索“wix“Visual Studio”项目”,并找到此页面,其中包含“创建简单设置”的链接,这是完美的。它实际上引导我一步步完成我需要的事情。我按照说明进行操作,点击“构建”,它显示“构建:1 成功”。我找到 MSI 文件,运行它,没有看起来很奇怪的 UI,但我可以忍受,它在我的“Program Files (x86)”文件夹中创建一个文件夹,其中包含我的项目的主 DLL。进步!

因此,现在我需要包含从我的库项目构建的 DLL,以及从 NuGet 包包含的所有 DLL。如果我可以告诉 WiX“请包含我的各种 NuGet 数据包所需的所有文件”,那就太酷了,但是在网络上浏览,看起来 WiX 不知道如何做到这一点,但这没关系,实际上我所需要的只是安装程序包含最终位于我的 bin/release/netcoreapp3.1 目录中的所有 DLL。

尝试明显的通配符方法:

<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
   <Component Id="ProductComponent">
      <File Source="$(var.MyApplication.TargetPath)" />
      <File Source="$(var.MyApplication.TargetDir)/*" />
   </Component> 
</ComponentGroup>
Run Code Online (Sandbox Code Playgroud)

只是给出了一个不像第一个错误那么容易阅读的错误,但似乎表明星号是不行的。如果我在 Google 上搜索“wix 添加目录中的所有文件”,会返回一大堆不同的建议,所有这些建议都很复杂,对于这样一个基本的事情来说,这似乎很奇怪。但按照本页中的说明进行操作,我最终得到了一个几乎可以工作的安装程序。我收到错误“未定义的预处理器变量 $(var.HarvestPath)”。 这个页面恰好有这个问题的答案,我又有了一个可以工作的安装程序。但现在它包含了该文件夹中的所有内容,而我只需要 DLL。在谷歌上搜索“wix heatdirectory except files”没有给出答案,看来这个功能是相对脑死亡的。

这是我当前的 WIXPROJ:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <DefineConstants>HarvestPath=...\Deploy</DefineConstants>
    <HeatDefinitions>MySourcePath=..\src\Your.App\bin\Release</HeatDefinitions>
  </PropertyGroup>
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.10</ProductVersion>
    <ProjectGuid>4ece284d-9247-4f7a-84a7-34820606a003</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>Installer</OutputName>
    <OutputType>Package</OutputType>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>Debug</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Product.wxs" />
      <!-- This will be your default one -->
      <Compile Include="HeatGeneratedFileList.wxs" />
      <!-- This is the Heat created one -->
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\MyApplication\MyApplication.csproj">
      <Name>MyApplication</Name>
      <Project>{6064dca8-d649-4592-bed5-34039bb3d30d}</Project>
      <Private>True</Private>
      <DoNotHarvest>True</DoNotHarvest>
      <RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
      <RefTargetDir>INSTALLFOLDER</RefTargetDir>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
  <Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
    <Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
  </Target>
  <Target Name="BeforeBuild">
    <HeatDirectory Directory="..\MyApplication\bin\$(Configuration)\netcoreapp3.1"
      PreprocessorVariable="var.MyApplication.ProjectDir"
      OutputFile="HeatGeneratedFileList.wxs"
      ComponentGroupName="HeatGenerated"
      DirectoryRefId="INSTALLFOLDER"
      AutogenerateGuids="true"
      ToolPath="$(WixToolPath)"
      SuppressFragments="true"
      SuppressRegistry="true"
      SuppressRootDirectory="true" />
  </Target>
  <!--
    To modify your build process, add your task inside one of the targets below and uncomment it.
    Other similar extension points exist, see Wix.targets.
    <Target Name="BeforeBuild">
    </Target>
    <Target Name="AfterBuild">
    </Target>
    -->
</Project>
Run Code Online (Sandbox Code Playgroud)

我想要的只是一个复制 EXE 和相关 DLL 的简单安装程序。为什么这么难?WiX 可以满足我的需要吗?或者我需要不同的安装程序工具包吗?

归档时间:

查看次数:

3791 次

最近记录:

4 年,2 月 前