【问题标题】:Why does my WiX Custom action throw a System.IO.FileNotFoundException?为什么我的 WiX 自定义操作会引发 System.IO.FileNotFoundException?
【发布时间】:2013-03-06 11:23:47
【问题描述】:

我正在使用 Visual Studio 2010、Windows 7 上的 Votive 插件、.net4 和最新的 WiX 3.7 来创建 msi。

安装相当复杂,当我在我的电脑上测试它时工作正常。

在安装过程中,我运行了一些自定义操作。 其中一个自定义操作需要一个外部 SQLite dll 来进行数据库访问,而这只有自定义操作才需要。

当我在没有我的开发环境的电脑上运行它时,只是普通的 windows 7,我得到一个找不到文件的错误。这似乎很明显是因为这台电脑上没有安装 SQLite。

我得到的错误是:

System.IO.FileNotFoundException:无法加载文件或程序集“System.Data.SQLite.dll”或其依赖项之一。指定的模块无法找到。

我可以从详细日志中看到自定义操作被提取到本地临时文件以运行。这是日志文件的摘录:

(SERVER)     MSI (s) (74:C0) [09:08:07:527]: Executing op: ActionStart(Name=InitializeDbDeferred,,)
(UNKNOWN)    Action 09:08:07: InitializeDbDeferred.
(SERVER)     MSI (s) (74:C0) [09:08:07:528]: Executing op: CustomActionSchedule(Action=InitializeDbDeferred,ActionType=1025,Source=BinaryData,Target=InsertDefaultRepositoryDeferred,CustomActionData=DATA=C:\AXS Standalone NVR;REPOSITORYPATH=C:\AXS Repository - (Available Space: 364 (Gb));QUOTA=25)
(SERVER)     MSI (s) (74:88) [09:08:07:530]: Invoking remote custom action. DLL: C:\Windows\Installer\MSI4252.tmp, Entrypoint: InsertDefaultRepositoryDeferred
(UNKNOWN)     SFXCA: Extracting custom action to temporary directory: C:\Users\Admin\AppData\Local\Temp\MSI4252.tmp-\
(UNKNOWN)     SFXCA: Binding to CLR version v4.0.30319
(UNKNOWN)     Calling custom action CustomAction!CustomAction.CustomAction.InsertDefaultRepositoryDeferred
(UNKNOWN)     Exception thrown by custom action:
(UNKNOWN)     System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.SQLite.dll' or one of its dependencies. The specified module could not be found.
(UNKNOWN)     at CustomAction.CustomAction.InsertDefaultRepositoryDeferred(Session session)
(UNKNOWN)      --- End of inner exception stack trace ---

我的问题是,当 CA 从临时位置运行时,如何让自定义操作在安装期间“查看”SQLite dll?我是否必须以某种方式将 CA 和它的 dll 打包在一起。

我尝试将 SQLite dll 作为文件包含在安装程序中,但临时位置中的 CA 不会“知道”它在哪里。

我只是看不到如何让 CA 找到 SQLite dll。

【问题讨论】:

    标签: c# wix windows-installer


    【解决方案1】:

    无法加载文件或程序集“System.Data.SQLite.dll”或其之一 依赖关系

    DTF 自动获取所有项目内容和程序集引用并将它们压缩到最终的本地 DLL 中。在自定义操作的生命周期内,您应该会在 temp 目录中看到 SQLLite 程序集。

    您会注意到错误消息显示“或其依赖项之一”。我会使用 ILDASM 或 .NET Reflector 查看 DLL 并查看该 DLL 的引用是什么。然后将它们作为项目(内容副本)或引用添加到您的 DTF 项目中。目标是让它们被打包到最终的 DLL 中并放到 temp 目录中。

    【讨论】:

    • 我刚刚在 dotPeek 中打开它,程序集需要 System.Data 和 System.Transactions。另一种方法是创建一个空的Class库,添加SQLite.dll,然后看看它还需要什么。
    • 我将留下这个答案,因为它可能仍然需要,但我已经创建了另一个答案,这是首先要尝试的。
    • 我将此标记为正确答案,因为它导致了我的问题。测试人员试图使用我什至不知道存在的“N”版 Windows。该版本还有许多未完成的更新。 SQLite dll 上的 Dependency Walker 显示以下 dll 丢失; 'MSVCR100.dll、MF.dll、MFPLat.dll、MFReadWrite.dll'。一旦我让他们应用所有未完成的更新,安装程序现在就会运行。无论哪个(曾经)罪魁祸首现在都已解决。故事的寓意,如果某些事情不起作用,不要自动假设所做的事情是错误的!
    • 啊,抱歉,我不知道它有本地依赖,否则我会建议使用 ILDASM 和 Depends。 FWIW,安装开发的核心是依赖分析。识别使系统运行的每一件小事。剩下的就是知道如何让这一切发生在世界上的每一台机器上。
    【解决方案2】:

    我将留下我的另一个答案,因为它对其他场景很有用,但我认为今天的问题更简单。

    当您使用 Votive 添加对 DTF C# 自定义操作项目的引用时,如果程序集名称以单词“System.”开头,它会自动设置 CopyLocal=False。这是为了避免打包 .NET Framework 中常见的 DLL。然而,微软已经养成了将“系统”程序集与其他可再发行组件一起发布的习惯。

    因此,请尝试将该参考的 CopyLocal 更改为 True,看看它是否会变得更好。 Ralph 提到的 System.Data 和 System.Transactions 随框架一起提供。

    【讨论】:

    • 嗨,我已将我在自定义操作中引用的所有 dll 的 Copy Local 标志设置为 true,我可以看到这增加了 CA dll 的大小,所以我猜它们被包含在内.但是,当我尝试安装时,我仍然遇到同样的错误。找不到 SQLite.dll 或依赖项。
    • 我可以提出添加 System.Data 和 System.Transactions 之类的建议并设置 CopyLocal=true 但这只是猜测。你只需要深入挖掘并分析它。
    • @ChristopherPainter - 你会用什么工具来分析它?
    • msdn.microsoft.com/en-us/library/e74a18c4(v=vs.110).aspx 是一个不错的选择。 FileMon 也有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多