C# WIX:使用DTF以编程方式向msi安装程序添加和读取CAB文件,以允许安装程序的动态自定义
我们使用WIX工具集创建了MSI安装程序。我们需要根据用户特定的文件(如主题和对话)动态定制安装程序。 我们使用此链接添加 但我不能读。 我们想知道读取CAB文件及其文件(自定义文件)的最佳位置。 我们应该在定制活动中这样做,还是在什么地方这样做最好? 此外,我们需要一个样本代码,我们可以按照实现这项任务?C# WIX:使用DTF以编程方式向msi安装程序添加和读取CAB文件,以允许安装程序的动态自定义,c#,.net,wix,windows-installer,dtf,C#,.net,Wix,Windows Installer,Dtf,我们使用WIX工具集创建了MSI安装程序。我们需要根据用户特定的文件(如主题和对话)动态定制安装程序。 我们使用此链接添加 但我不能读。 我们想知道读取CAB文件及其文件(自定义文件)的最佳位置。 我们应该在定制活动中这样做,还是在什么地方这样做最好? 此外,我们需要一个样本代码,我们可以按照实现这项任务? 注意:-我们的CAB文件将包含大量文件(txt文件、图像等)我假设,由于您遵循了该链接(尽管我自己的问题如此),您现在将这些文件作为带有MediaID的新CAB文件嵌入到msi中 警告:此回
注意:-我们的CAB文件将包含大量文件(txt文件、图像等)我假设,由于您遵循了该链接(尽管我自己的问题如此),您现在将这些文件作为带有MediaID的新CAB文件嵌入到msi中 警告:此回复中的代码目前尚未测试 请注意,msi基本上只是一个数据库,可以使用类似SQL的语句查询它。cab文件嵌入在数据库的_Streams表中,可以提取为原始cab文件格式 您可以使用ORCA和7zip验证这一点 您提到的问题的解决方案旨在“替换”文件。 因此,在msi构建中使用了一个虚拟文件,并且在wix中配置了位置。然后在构建msi之后,修改文件表,将wix生成的原始cab文件的引用更改为新的cab文件。这样,虚拟文件将成为孤立文件,但仍嵌入到msi中 如果知道将为每个用户自定义哪些文件,并且所有用户都将具有相同的文件夹/文件结构(独立于自定义),那么这种方法就可以了 我假设每个用户有不同数量的文件,或者每个用户有不同的文件夹结构,因为您不只是复制该解决方案。要实现这一点,需要对msi表进行几次编辑。 目录表: 如果wix配置尚未定义目录,则需要在此表中创建目录 类似这样的内容应该允许您插入新目录:
string query = "INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) ";
query += "VALUES ('" + The_Directory_ID + "', '" + The_Parents_ID + "', '" + FolderName + ")";
pkg.Execute(query);
从现在开始,必须对新cab文件中的所有文件重复所有操作 **组件表** 您需要创建一个控制文件的组件,以便msiexec可以安装/卸载该文件
string query = "INSERT INTO `Component` (`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) ";
query += "VALUES ('" + The_new_files_name_or_Similar + "', '{" + FileGUID + "}', '" + The_Directory_ID + "0, \"\", "+ A_FILE_ID +" )";
pkg.Execute(query);
其中:
- 可以使用
生成文件GuidGuid.NewGuid()
- _FILE_ID可以是文件名,如果wix生成MSI,所有其他文件通常由“FileID###”引用,因此它可能适合您,否则您需要确定您可以使用的文件表中不存在的文件ID
- 文件:文件ID
- 组件:新文件名或类似文件名
- 文件名:文件名(安装时)
- 文件大小:它是文件大小,以字节为单位
- 版本:如果文件有版本号,请添加版本号,否则留空。如何检索文件版本取决于文件类型
- 语言:这是文件语言版本,通常为1033,但如果您不知道,可以将其保留为空
- 属性:这取决于媒体文件(文件柜)是嵌入的、外部的还是外部的,等等。。使用与msi中其他所有内容相同的数字,您通常会没事。在构建后嵌入CAB文件时,我总是使用512
- 序列:您需要获取文件表中已找到的最高序列值,并将其递增
- 功能安装此组件的功能。你可以做一个新的,也可以不做。我建议您使用现有的一个李>
- 组件新文件名或类似文件
IList<int> sequences = pkg.ExecuteIntegerQuery("SELECT `LastSequence` FROM `Media` ORDER BY `LastSequence`");
lastIndex = sequences.Count - 1;
int LastSequence = sequences.ElementAt(lastIndex) + numberOfFilesToAdd;
query = "INSERT INTO `Media` (`DiskId`, `LastSequence`, `Cabinet`) VALUES (" + DiskId.ToString() + "," + LastSequence.ToString() + ",'#" + mediaCabinet + "')";
pkg.Execute(query);
IList sequences=pkg.ExecuteIntegerQuery(“通过`LastSequence``从`Media`顺序中选择`LastSequence`”);
lastIndex=序列。计数-1;
int LastSequence=sequences.ElementAt(lastIndex)+要添加的文件数;
query=“插入到`Media`(`DiskId`、`LastSequence`、`Cabinet`)值(“+DiskId.ToString()+”、“+LastSequence.ToString()+”、'#“+mediacainet+”)”;
pkg.Execute(查询);
所以这应该已经为您设置好了。。
如果其他人偶然发现了这个答案,我会在这里复制相关的代码片段,以展示如何为新的cab文件生成seuquence编号
因此,文件表的序列号大于msi中已有的序列号,但低于已添加的新介质中的序列号
注意:cab文件中的文件与序列号的顺序相同非常重要,否则msiexec可能会抛出无法找到文件的错误。