无法找到目标计算机上肯定存在的私有程序集

发布于 2025-01-08 02:50:47 字数 2526 浏览 0 评论 0 原文

我们将 Visual C++ 运行时作为私有程序集进行分发 (即,将 msvcp90.dll、msvcm90.dll、msvcr90.dll 和 Microsoft.VC90.CRT.manifest 放入Microsoft.VC90.CRT 文件夹与我们应用程序的可执行文件位于同一目录中)。到目前为止,在每台非开发机器(数百台)上,这都很好。然而,我一直在追踪一台完全无法找到这些组件的特定问题机器。

他们运行的是 XP,因此当他们尝试启动我们的应用程序时,他们会得到 消息

此应用程序无法启动,因为该应用程序 配置不正确。重新安装应用程序可能会解决此问题 问题。

我让他们在我们应用程序的 exe 上运行Dependency Walker,它表明它找不到 msvcp90.dll 或 msvcr90.dll。然后我让他们追踪我们应用程序的目录内容,这表明那些“丢失”的 DLL 实际上位于它们应该所在的位置(在与 exe 相邻的 Microsoft.VC90.CRT 目录内),但尽管如此,应用程序只是在启动时找不到它们。

作为最后的手段,我让他们直接安装可再发行组件 ,但这主要只是为了故障排除,因为我们更愿意继续分发 DLL,而无需额外的安装程序(我们的应用程序无需任何安装即可运行)。


我可能还应该包括我们应用程序自己的清单:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="OurApp.Name" type="win32"/>
  <description>Our App Description</description>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

编辑:我之前提到过没有 dependentAssembly,但我意识到它正在生成,因此上面的清单反映了它创建的实际清单。


什么会导致程序根本找不到这些依赖项?它在许多其他计算机上发现它们都很好,其中大多数计算机以前从未见过这些运行时。我可能搞砸了一些基本的东西(很可能在我的清单中),但到目前为止它在 99% 的客户端计算机上运行良好。

作为奖励,这篇文章 是对私有程序集的一个很好的总结,但到目前为止它还没有帮助我解决问题。

更新:将 DLL 移至与 EXE 相同的目录后,它仍然无法启动。然后,在安装可再发行组件后,它启动正常。所以看起来它要么没有在本地目录中查找,要么由于某种原因认为本地 DLL 不可接受。

We're distributing the Visual C++ runtimes as private assemblies (i.e., putting msvcp90.dll, msvcm90.dll, msvcr90.dll, and Microsoft.VC90.CRT.manifest into a Microsoft.VC90.CRT folder that exists in the same directory as our app's executable). So far, on every non-dev machine (several hundreds), this has been fine. However, I have been tracking down one particular problem machine that is completely unable to find these assemblies.

They're running XP, so when they try to launch our app, they get the message:

This application has failed to start because the application
configuration is incorrect. Reinstalling the application may fix this
problem.

I had them run Dependency Walker on our app's exe, and it indicated that it could not find msvcp90.dll or msvcr90.dll. I then had them trace out the directory contents of our app, which revealed that those "missing" DLLs were in fact where they were supposed to be (inside the Microsoft.VC90.CRT directory adjacent to the exe), but nevertheless, the app just isn't finding them when it starts up.

As a last resort, I am having them install the redistributables directly, but this is mainly just for troubleshooting, as we'd prefer to continue to distribute the DLLs without having an additional installer (our app can simply get run without any installation).


I should probably also include our app's own manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="OurApp.Name" type="win32"/>
  <description>Our App Description</description>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Edit: I previously mentioned that there wasn't a dependentAssembly, but I realized it was being generated, so the above manifest reflects the actual manifest it creates.


What can cause a program to simply not find these dependencies? It finds them just fine on many other computers, most of which have never seen these runtimes before. I'm probably messing up something basic (most likely in my manifest), but it runs fine on 99% of client computers so far.

As a bonus, this article is a nice summary of private assemblies, but so far it hasn't helped resolve things for me.

Update: After moving the DLLs into the same directory as the EXE, it still failed to launch. Then, after installing the redistributables, it launched fine. So it seems like it either wasn't looking in the local directories, or for some reason deemed the local DLLs unacceptable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攒一口袋星星 2025-01-15 02:50:48

当前是否在同一台 Windows 计算机上安装了任何版本的 Visual Studio?

您还可以仔细查看 http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx。此链接包含有关操作系统如何搜索 DLL 的信息。有一些注册表项可能会改变该行为。

消除这种依赖性的其他选项是在项目中使用 MFC/ATL 的静态链接。您的二进制文件会更大,但您可以完全消除这个问题。

Is there any version of Visual Studio currently installed in that same Windows machine?

You may also take a close look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx. This link contains information about how the operating system searches for the DLLs. There are a few registry keys that might change that behaviour.

Other option to eliminate this dependency is to use static link with MFC/ATL in your project. Your binaries will be larger, but you eliminate this issue all together..

挽你眉间 2025-01-15 02:50:48

我本想早点回到这个话题,但它被搁置了,等待测试用例。事实证明这是一个非常简单的问题:它正在寻找错误的 DLL 版本。 VS 生成的清单未设置为使用我从 VS 提取的相同版本的可再发行组件。通过禁用清单的自动生成并仅在我自己的清单中设置版本以匹配我重新分发的 DLL 的版本,它就可以工作。

I meant to get back to this sooner, but it was on the back burner waiting for a test case. It turns out it was a remarkably simple problem: it was looking for the wrong DLL version. The manifests that were generated by VS were not set to use the same version of the redistributables that I had extracted from VS. By disabling autogeneration of the manifests and just setting the version in my own manifest to match the version of the DLLs I'm redistributing, it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文