【问题标题】:Not finding DLL When Ran as a Startup Program作为启动程序运行时找不到 DLL
【发布时间】:2016-07-01 17:33:29
【问题描述】:

我的程序运行良好,除非它作为启动程序启动。当作为启动程序启动时,它无法找到第一方 DLL(或其依赖项之一)。

我得到以下异常:

找不到文件或程序集 X 或其依赖项之一:C:\Windows\SysWow64\X.dll

它在C:\Windows\SysWOW64\ 目录而不是在本地目录C:\Program Files\MyProgram\ 中寻找第一方DLL。

令人困惑的部分是,如果我手动启动程序一切正常。

我该如何寻找这个问题的根源?我尝试使用 Fusion Log,但它只告诉我与异常相同的信息:它试图仅从 C:\Windows\SysWOW64 加载。

我了解到,当您的应用程序使用 Assembly.Load 时,可能会发生这种情况 - 罪魁祸首程序确实使用了 Assembly.LoadFrom - 但同样,这工作正常,除非在启动时完成。

此外,罪魁祸首程序确实有一些[DllImport] 属性。

【问题讨论】:

  • 总是,总是,指定文件的完整路径名。不是“baz.dll”,它必须是“c:\foo\bar\baz.dll”。 Environment.CurrentDirectory 是最糟糕的全局变量。当然,当您使用 Run 注册表项时,它并没有设置在您希望的位置。使用 Application.StartupPath 或 Assembly.GetEntryAssembly().Location 格式化该路径。
  • @HansPassant ... 很好的答案,但是既然您已经将它放在评论中,那么我们其他人会在哪里? :-) 。我们可以让问题保持开放(呃),或者将完全相同的信息放入答案框中(呃)。您是否希望它以重复的形式关闭?
  • 我没有指定路径,只是给出了 DLL 的名称,因为Assembly.LoadFrom 文档说它接受相对路径。我尝试过使用绝对路径,这很有效。为什么Assembly.LoadFrom在程序是启动程序时不使用应用程序库我不知道。
  • @Paul-Jan:Hans Passant 经常这样做。也许他没有足够的时间并且无论如何都达到了代表上限。它也有点不完整,因为它错过了官方来源。您可以添加答案,感谢 Hans 并通过链接到 MSDN 等来丰富基本陈述。
  • @Paul-Jan:如果您不想从这样的答案中获得声誉,您可以将其标记为社区 wiki。恕我直言,获得声誉也可以,因为您花费了一些额外的精力来改善答案。

标签: c# .net dll


【解决方案1】:

问题与使用 Assembly.LoadFrom 和启动时的当前目录有关。

Assembly.LoadFrom 声明它:

assemblyFile 可以是绝对的或相对于当前目录,并且程序集被加载到调用者的域中。

当程序设置为启动程序时,当前目录为 C:\Windows\SysWOW64 无论出于何种原因。

正如您可以通过输出 Directory.GetCurrentDirectory() 来演示的那样。

我使用Assembly.Load,而不是使用不遵循正常探测的Assembly.LoadFrom,因为它会搜索包含DLL的正常目录。

  • 加载上下文包含通过探测找到的程序集:在 GAC 中,在托管运行时的主机程序集存储中,或在应用程序域的 ApplicationBase 和 PrivateBinPath 中。 Load 方法的大多数重载都将程序集加载到此上下文中。

  • 加载源上下文包含用户为其提供的路径未包含在通过探测搜索的目录中的程序集。 LoadFrom、CreateInstanceFrom 和 ExecuteAssembly 是按路径加载的方法示例。

这也解释了为什么 Fusion 告诉我它只在 C:\Windows\SysWOW64 中搜索 DLL - 正如 LoadFrom 所做的那样,只在给定目录中搜​​索。在我的例子中是当前目录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多