4

我正在制作一个自定义安装程序。我添加Utility.CA.dll执行自定义操作的位置。在这种情况下,我想访问相对于setup.msi文件路径的本地文件。自定义操作方法可以使用直接路径e:\utility\myfile.txt,但我找不到路径 '..\utility\myfile.txt'。经过一些实验,我得到了那个Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)ShowsC:\Users\current_username\AppData\Local\Temp\MSIF384.tmp-文件夹。

我能做些什么?需要 wix 代码示例。

4

4 回答 4

3

首先,我应该提到引用与 .MSI 的源相关的文件是非常具有挑战性的,因为稍后(修复、修补、卸载).MSI 文件将在安装程序缓存之外执行,而松散的文件(如myfile.txt)将不可用。您需要非常仔细地编写自定义操作来处理该事实。

您正在寻找的是Directorywith identifier SourceDirSourceDir您可以通过调用来获取 的值:

 string sourceDir = session["SourceDir"];

注意:我假设您正在使用 DTF,其中将session对象提供给您的托管自定义操作。

现在,复杂性在于该SourceDir属性仅在 Windows Installer 完成后才设置ResolveSource。在初始安装时,双击 .MSI 文件的位置将解析源(因为它是初始安装并且需要文件)。后续安装可能不需要源(例如卸载不需要您将 CD 放回驱动器即可成功)。因此,您要么必须在 .MSI 安装序列中调用操作(这将提示用户再次提供原始 .MSI 文件),要么编写自定义操作代码,使其在所有情况下ResolveSource都不需要。SourceDir

您可以在这里阅读更多信息SourceDirhttp ://robmensching.com/blog/posts/2010/1/26/stackoverflow-what-does-namesourcedir-refer-to

于 2013-04-03T12:17:01.880 回答
1

这对我有用;在 Product.wxs 中:

<Binary 
    Id="WixMyCustomActions"         
    SourceFile="..\WixMyCustomActions\bin\WixMyCustomActions.CA.dll" />

<CustomAction 
    Id="MyMethod" 
    BinaryKey="WixMyCustomActions" 
    DllEntry="MyMethod" 
    Execute="immediate" 
    Return="check" />

WixMyCustomActions.CA.dll 是与 Wix 项目相同的解决方案中的 C# 类库。在 WixMyCustomActions.CA.dll 项目属性 Build Events 中,我有一个构建后事件将 WixMyCustomActions.CA.dll 和 WixMyCustomActions.CA.pdb 从 bin\Debug 或 bin\Release 复制到 bin:

copy "$(TargetDir)*.dll" "$(ProjectDir)bin" /Y
copy "$(TargetDir)*.pdb" "$(ProjectDir)bin" /Y

通过复制 dll,我的 Product.wxs 将引用最后构建的任何配置(调试或发布)。

编辑:要获取与您的 CA dll 相关的文件,请使用它来查找 CA 程序集的目录:

using System.IO;
using System.Reflection;

// etc

string assemblyDirectory = 
    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

您现在可以找到与此目录相关的文件。

于 2013-04-03T09:45:06.383 回答
1

如果您需要获取 msi 文件所在文件夹的路径,可以使用此代码段来检索它:

Path.GetDirectoryName(session["OriginalDatabase"])

OriginalDatabase属性可用于 InstallUISequence 和 InstallExecuteSequence。

要访问与您的 msi 相关的文件,您将使用

Path.Combine(Path.GetDirectoryName(session["OriginalDatabase"]), "myfile.txt")
于 2015-05-11T17:15:41.527 回答
0

有一个可以从 MSI 读取的属性 - SourceDir

您可以通过以下方式在您的 c# 代码中引用此属性string sourceDir = session["SourceDir"];

但是,在尝试获取源之前,您必须先解析源。那是您的 MSI 不知道它是从哪里运行的。因此,在您InstallExecuteSequence.

<ResolveSource After="CostInitialize"/>

请注意,你应该把它放在之前CostFinalize和之后CostInitialize,否则会给出错误ICE27: 'ResolveSource' Action in InstallExecuteSequence table in wrong place。当前:选择,正确:成本核算

您的自定义操作应在ResolveSource元素之后引用。

<InstallExecuteSequence>
      <ResolveSource After="CostInitialize"/>
      <Custom Action="CustomActionThatNeedsRelativePath" After="CostFinalize"/>
</InstallExecuteSequence>
于 2018-07-03T13:52:09.410 回答