使用 CreateProcess 启动子程序时,不会在父程序的工作目录中搜索 DLL
Posted
技术标签:
【中文标题】使用 CreateProcess 启动子程序时,不会在父程序的工作目录中搜索 DLL【英文标题】:Parent program's working directory is not searched for DLLs when child program is started with CreateProcess 【发布时间】:2013-05-28 14:50:24 【问题描述】:我有一个非常奇怪的问题。我正在 Windows 下开发一个将数据写入临时目录的 C 程序。它使用GetTempFileName 生成唯一名称。数据实际上是一个exe,在将数据写入临时文件后,我以CreateProcess 开头。对于lpCurrentDirectory
参数,我使用NULL
,因此使用父程序的当前工作目录成为子程序的工作目录。有所有需要的 DLL。
在大多数计算机(XP、2003、7、8)上,一切正常。但是在一个特定的 Windows 7 上,当子程序启动时,我得到了异常。很奇怪,但如果我将所有需要的 DLL 移动到 temp 目录,一切都会按预期工作。
嗯,为什么不搜索父程序的工作目录?
非常感谢。
【问题讨论】:
它不一定是“当前目录”。您说的事实是问题是缺少依赖项。 Windows 使用 DLL Search Order 来定位 DLL。这是您检查依赖项是否在搜索路径上的地方。当前目录是您可以跟踪/记录的内容,并确保它们是您所期望的。 @RomanR.,是的,我知道我缺少一个 DLL。问题是为什么Windows不在父程序工作目录中搜索?! 我的猜测是因为您希望当前目录是父应用程序的直接目录,而实际上它是不同的目录。 @RomanR.,我将lpCurrentDirectory
设置为 NULL
并且文档说在这种情况下,子进程的工作目录设置为父进程的工作目录。奇怪的。而且这种行为只在一台机器上。其余所有工作正常。很奇怪。
NULL
获取您父母的当前目录,而不是父母的应用程序二进制目录 - 这是我的观点。
【参考方案1】:
您最初的问题是为什么子进程不继承父进程的工作目录。好吧,如果您将 NULL 传递给 CreateProcess,那么新进程将在调用 CreateProcess 时继承父进程的工作目录。文档清楚地说明了这一点,这里没有任何意外。 CreateProcess 的行为与宣传的完全一样。
编辑后的问题集中在 DLL 搜索上。从这些信息中回答这个问题的新观点并不容易。最好的办法是在 Dependency Walker 的 profile 模式下运行程序。这应该揭示出了什么问题。您可能会发现问题根本不是您所期望的。
为了将来参考,我建议您在提问时提供任何错误的完整详细信息。您说引发了异常,但实际上您需要提供任何异常的完整详细信息。
【讨论】:
嗨,大卫,感谢您的宝贵时间。如果您第二次阅读我的问题,您会看到我已经描述了当我将所有 DLL 移动到临时目录时,子程序会正常启动。为什么(并且仅在这台特定的 Windows 7 机器上)不搜索当前目录?当前目录(运行父程序的目录)包含所有必需的 DLL。 我不需要再读一遍了。当 dll 与它在同一目录中时,exe 会找到它们,即您的临时目录。 对不起,我不想冒犯你。当前工作目录不是也搜索到了吗? 请查看此页面msdn.microsoft.com/en-us/library/windows/desktop/…。即使使用 SafeDllSearchMode 也会搜索当前目录。 可能会首先找到其他版本的 DLL。依赖工作目录进行 DLL 搜索是很疯狂的。我回答的问题是:嗯,所以子程序的当前工作目录没有设置为父程序的工作目录?!您现在似乎在问另一个问题。以上是关于使用 CreateProcess 启动子程序时,不会在父程序的工作目录中搜索 DLL的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 CreateProcess 在 cmd 中执行命令?
无法启动应用程序(CreateProcess 错误=87),不能使用缩短类路径解决方法