- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在尝试使用 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/
我想启动一个进程(exe 文件),如果我将完整路径附加到我的命令行(lpCommandLine 参数),一切都很好,但如果我将 lpCurrentDirectory 设置为 [STARTDIR],系统
我目前正在尝试使用 CreateProcess() API 启动一个进程: http://msdn.microsoft.com/en-us/library/windows/desktop/ms6824
我正在尝试使用 CreateProcess 从 C++ 应用程序执行外部进程。 启动的应用程序在查找其目录中存在的 dll 时失败。 使用 Process Explorer(来自 sysinterna
我是一名优秀的程序员,十分优秀!