gpt4 book ai didi

CreateProcess() 似乎不受 lpCurrentDirectory 的影响

转载 作者:可可西里 更新时间:2023-11-01 09:25:08 29 4
gpt4 key购买 nike

我目前正在尝试使用 CreateProcess() API 启动一个进程: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

我遇到的主要问题是子进程似乎是在父进程的工作目录下启动的,不管 lpCurrentDirectory 参数中指示的是什么.

提供更多细节:lpCurrentDirectory 似乎适用于简单的命令行程序,但对于更复杂的程序(想想 GUI),它似乎没有被考虑在内,因为所有资源依赖项都是从调用目录进程中搜索的。

我可以尝试来回切换调用进程的工作目录,但第二个问题是被调用进程不在目标目录中。目前,它位于与调用进程相同的目录中,尽管将来可能会发生变化。当我试图调用与父进程位于不同目录中的子进程时,由于某种原因,它失败了。我已经多次检查目录结构,到目前为止没有结果。

我一直在四处寻找(包括 S.O.),虽然有些人似乎提示同样的问题,但我目前还没有找到可用的解决方法。请注意,例如,我不能改用 ShellExec,它必须是 CreateProcess()。

以防万一,我当前的测试系统是 Windows Seven 64 位。该软件应该可以在更广泛的操作系统上运行,从 XP 到 7、32 和 64 位(我猜 W8 目前不在范围内)。

[编辑] 我已经找到了在调用进程工作目录之外调用子进程的解决方案。我为此使用了 lpApplicationName,这很好,但显然不需要引用,即使是包含空格字符的复杂名称也是如此。

这让我可以测试修改调用进程的工作目录的想法(使用 SetCurrentDirectory() )调用 CreateProcess() 之前。令我惊讶的是,它不起作用:工作目录实际上是在 lpApplicationName 的完整路径中指定的目录,无论通过 SetCurrentDirectory() 为父工作目录设置了什么(并使用 GetCurrentDirectory() 验证)

这对我来说是个问题,因为我希望进程运行到另一个选定的目录(都在 lpCurrentDirectory 参数中指定,并在 CreateProcess() 之前调用 SetCurrentDirectory())。

最佳答案

我相信你的问题是你假设子进程应该尝试从当前目录加载它的资源(如你第三段中所建议的那样),而实际上一个进程从加载它的资源更为常见它从中启动的目录。换句话说,您所描述的行为在大多数情况下都符合预期。

当应用程序通过双击文档或使用拖放操作启动时,当前目录被设置为包含文档的目录,因此如果应用程序从当前目录加载资源,它会'工作。

这个简单的测试应用程序演示了 lpCurrentDirectory 的工作原理,因为子进程的当前目录设置为指定的目录:

#include <Windows.h>

void showcd(wchar_t * caption)
{
wchar_t buffer[512];

if (GetCurrentDirectory(512, buffer) == 0)
{
DWORD err = GetLastError();
MessageBox(NULL, L"GetCurrentDirectory failed", caption, MB_OK);
ExitProcess(err);
}

buffer[511] = L'\0';
MessageBox(NULL, buffer, caption, MB_OK);
}

void parent(wchar_t * cd)
{
wchar_t cmd[512];
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;

GetStartupInfo(&sinfo);

showcd(L"Parent Process");

if (GetModuleFileName(NULL, cmd, 512) == 0)
{
MessageBox(NULL, L"GetModuleFileName failed", L"Parent Process", MB_OK);
ExitProcess(GetLastError());
}

cmd[511] = L'\0';

if (!CreateProcess(
cmd, NULL, NULL, NULL, FALSE, 0, NULL, cd, &sinfo, &pinfo
))
{
DWORD err = GetLastError();
MessageBox(NULL, L"CreateProcess failed", L"Oops", MB_OK);
ExitProcess(err);
}
}

int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
wchar_t * cmdline;
for (cmdline = GetCommandLine(); *cmdline; cmdline++)
{
if (*cmdline == L'*')
{
parent(cmdline + 1);
return 0;
}
}

showcd(L"Child Process");
return 0;
}

要测试应用程序,请使用如下命令行运行它:

currentdirectorytest *c:\Users\Public

来自父进程的第一个对话框显示了父进程的当前目录。第二个对话框来自子进程,显示子进程当前目录,应该是命令行中给出的目录。 (注意指定的目录必须存在,否则创建子进程会失败。)

关于CreateProcess() 似乎不受 lpCurrentDirectory 的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17395385/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com