寻找一种将所有文件包含在我的 MSI 中的项目 BIN 文件夹中的简单方法

Looking for a simple way to include all files in a project's BIN folder in my MSI

我的项目的输出 BIN 文件夹中有很多文件(数百个)。我只需要一个安装程序来将文件包含在 MSI 安装程序的 bin 文件夹中。

在我的 WIX 安装程序项目中,我有以下目标来使用收获工具并生成 bin 文件夹中所有文件的列表,稍后,我在我的 WIX 定义中引用它们:

  <Target Name="GenerateHeat">
    <HeatDirectory Directory="..\MyApp\bin\Debug" 
       PreprocessorVariable="var.HeatPath" OutputFile="HarvestedFiles.wxs"
       ComponentGroupName="HarvestedFiles" DirectoryRefId="FOLDER1" 
       AutogenerateGuids="true" ToolPath="$(WixToolPath)" 
       SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" />
  </Target>

有什么方法可以简单地将所有文件包含在一个bin文件夹中,并将它们包含在MSI中而不生成中间文件列表?我更喜欢指定 BIN 文件夹名称,WIX 将它们包含在 <ComponentGroup> 中,因此我可以在我的 <Product>

中引用它

更新和澄清

这个问题不是关于 MSI 是如何工作的。这是关于 WIX 如何将文件夹的内容复制到 MSI 中,而无需在 <Component><File> 三明治中指定每个文件名。

这将违背 Windows Installer 的整体设计理念。

Windows 安装程序管理组件的 health/installation 状态。它在安装的所有产品的所有版本中执行此操作。为了使这个可行,有 “Components Rules。”为了使规则在组件生命周期内易于管理,组件应该是原子的:一个文件(或多文件 .NET 程序集)and/or 注册表项。

(如果您有选择,如果您不喜欢它的设计,则不必使用 Windows 安装程序。)

此外,您应该考虑是否、如何以及在何处安装 bin 文件夹中的任何内容。它的基本目的是就地调试。它可能包含以下内容:1) 您未获得重新分发的许可,2) 您仅获得以特定方式重新分发的许可,3) 可能已经是目标系统的一部分,4) 可能最好使用其原始安装程序从vendor 5) 你实际上并不想交付给用户,......对于这些问题,您可以缩小收获范围或过滤掉特定结果。

提示:如果您想模块化安装,您可以将组件集构建到不同的 MSI 文件中,然后使用 WiX 的引导程序将它们安装在一起。

Is there any way to simply include all files in a bin folder and include them in the MSI without generating the intermediate file list?

免费版 WiX 的内置功能无法做到这一点。作为 Stein Åsmul ,WiX 的 商业分支可能有类似的东西。

如果商业 WiX 不是一个选项,并且您准备投入 大量 时间在 C# 开发中,主要使用未记录的 API,您可以编写一个 WiX 编译器扩展根据给定的源目录路径向 FileComponent table 添加条目。它还可以生成组件组,可以在其他地方引用。

我过去也确实这样做过,但这肯定不是一项微不足道的任务。在执行诸如生成组件 GUID 之类的事情之前,通常还应该对组件规则和 MSI 有很好的了解。您会在下面找到一些伪代码。在沿着这条路走下去之前,如果其他人已经创建了这样的开源 WiX 扩展,那么值得四处看看。

这是可以使用此类编译器扩展实现的创作类型:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:ex="MyExtensionUri">
  <Product ... >
    <Feature Id="ProductFeature" Title="MyFeature" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>
  </Product>

  <Fragment>
    <ex:ComponentGroupFromFiles Id="ProductComponents"
      Directory="INSTALLFOLDER"
      Source="MyApp\bin"
      Wildcard="*"/>
  </Fragment>
</Wix>

这里是编译器扩展的一些伪代码。这主要是为了作为探索WiX源“Compiler.cs”的关键字。

重写 Wix.CompilerExtension.ParseElement() 以解析扩展元素的属性。

创建组件组并按产品引用:

Wix.Row compGroupRow = Core.CreateRow(sourceLineNumbers, "WixComponentGroup");
compGroupRow[0] = myComponentGroupId;

Core.CreateWixGroupRow( sourceLineNumbers, Wix.ComplexReferenceParentType.Product, Core.ActiveSection.Id, Wix.ComplexReferenceChildType.ComponentGroup, myComponentGroupId );

每个 component/file:

// Add record to the Component table
Wix.Row compRow = Core.CreateRow( sourceLineNumbers, "Component" );
// TODO: Assign data to compRow[0..5] according to MSI "Component" table documentation

// Add this component to the component group.
Core.CreateComplexReference( sourceLineNumbers, Wix.ComplexReferenceParentType.ComponentGroup, myComponentGroupId, "", Wix.ComplexReferenceChildType.Component, myComponentId, false );

// Add record to the File table.
Wix.Row fileRow = Core.CreateRow( sourceLineNumbers, "File" );
// TODO: Assign data to fileRow[0..2] and [6] according to MSI "File" table documentation. Columns 3, 4, 5, 7 are written by the WiX binder at a later time! Set them to null (if nullable) or 0.

// Create required metadata for WiX
Wix.WixFileRow wixFileRow = (Wix.WixFileRow) Core.CreateRow(sourceLineNumbers, "WixFile");
// TODO: Assign wixFileRow.File, wixFileRow.Directory, wixFileRow.DiskId, wixFileRow.Source
//       Set wixFileRow.Attributes to 1 if you have generated a short file name.

// Add reference to the Media table
Core.CreateWixSimpleReferenceRow( sourceLineNumbers, "Media", diskId );

生成组件/文件的有用实用程序table列数据:

Core.GenerateIdentifier()
Core.GenerateShortName()

如何将组件添加到合并模块?这留作 reader 的练习。只需在 WiX 的“Compiler.cs”中找到代码即可。

FireGiant:我相信WiX的商业分支(FireGiant), has a module for this. HeatWave Harvesting - or something like that. It is part of the WiX expansion pack如果我没记错的话。它允许高级收割创建 MSI 文件和我不知道的其他格式。除此之外我对该模块几乎一无所知。哦,它还支持从 64 位 COM 文件中提取 COM - 这在 heat.exe 此刻。

Tallow:在 WiX2 时代,有一个叫 Tallow 的工具,它是由我不记得名字的人开发的.它生成 WiX 标记以从给定的输入文件夹安装文件,甚至使组件 GUID 保持同步(据我所知)。我在 github.com 上看到了它的一些副本,但我下载的存储库有几个恶意软件命中,所以没有 link。

Paraffin:我从未使用过的工具是 Paraffin - 据说是更好的 Tallow - https://github.com/Wintellect/Paraffin。我不能说太多,因为我还没有尝试过。快看一下?老实说,我不确定它是否得到维护,但它肯定比从头开始推出自己的解决方案要好。

除非你谈论的是网络应用程序/网站(考虑 node.js 目录结构)我建议不要这样做。

有些包管理器为我编写了所有这些数千个文件的故事 (^^^) 然后使用 Heat。

对于所有其他正常场景,我创建了 IsWiX。它帮助我降低了 authoring/maintaining 安装程序的复杂性和摩擦,同时让我控制 does/doesn 未发布的内容以及何时安装或未安装某些内容(功能)。

https://iswix.com/2007/06/20/dealing-with-very-large-number-of-files/

https://github.com/iswix-llc/iswix-tutorials