gpt4 book ai didi

c - 如何在 Visual Studios 中使用 CreateProcess 函数

转载 作者:太空宇宙 更新时间:2023-11-04 03:21:31 25 4
gpt4 key购买 nike

我在 Stack Overflow 上看到了 CreateProcess() 函数的一些示例,但我无法让这些示例起作用。我正在使用 Visual Studio,但直接用 C 编程。这是我最近的尝试。我可以让它编译和执行,但我无法让它启动应用程序:

PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));

StartupInfo.cb = sizeof StartupInfo ;

hr = CreateProcess((NULL, (LPTSTR) "C:\\Windows\\System32\\notepad.exe"), NULL,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo);

int error_1 = 0;
if(!hr)
{
error_1 = GetLastError();
}

当我读取“error_1”时,它返回一个“2”,它基于系统错误代码表示“系统找不到指定的文件。”。但是,我确定路径是正确的,因为我可以使用命令行中的路径来启动“记事本”。我看不出我做错了什么。

最佳答案

您需要去掉传递的前 2 个参数值周围的额外括号。

但是,更重要的是,您需要摆脱 LPTSTR 类型转换。如果您的项目配置为针对 Unicode 进行编译,CreateProcess() 将映射到 CreateProcessW(),而 LPTSTR 将映射到 wchar_t *,因此您会将一个窄的 const char[] 文字类型转换为 wchar_t* 指针,并最终将垃圾传递给 CreateProcessW( ),这很容易解释您所看到的错误。创建 TCHAR[] 字符串文字的正确方法是使用 TEXT()宏而不是类型转换(有关详细信息,请参阅 MSDN 上的 Working with Strings):

hr = CreateProcess(NULL, TEXT("C:\\Windows\\System32\\notepad.exe"), NULL,  
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);

但是要注意CreateProcess() documentation :

lpCommandLine [in, out, optional]
The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

您可以执行以下操作来避免这种情况:

TCHAR szCmdLine[] = TEXT("C:\\Windows\\System32\\notepad.exe");
hr = CreateProcess(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);

或者:

WCHAR szCmdLine[] = L"C:\\Windows\\System32\\notepad.exe";
hr = CreateProcessW(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);

否则,直接使用 CreateProcess() 的 ANSI 版本,您可以安全地将字符串文字传递给:

hr = CreateProcessA(NULL, "C:\\Windows\\System32\\notepad.exe", NULL,  
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);

附带说明一下,您不需要指定 notepad.exe 的完整路径,因为 Windows 知道它所在的位置。您可以单独使用 "notepad.exe"

但是,如果您确实指定了完整路径,则必须考虑应用的位数。如果您的应用是为 32 位编译的,并在 64 位系统上运行,C:\Windows\System32\notepad.exe 将重定向到 C:\Windows\SysWOW64\notepad.exe,这是记事本的 32 位版本。如果您想运行 64 位版本的记事本,则必须使用 C:\Windows\Sysnative\notepad.exe,根据 WOW64 文档:

File System Redirector

The %windir%\System32 directory is reserved for 64-bit applications. Most DLL file names were not changed when 64-bit versions of the DLLs were created, so 32-bit versions of the DLLs are stored in a different directory. WOW64 hides this difference by using a file system redirector.

In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64. Access to %windir%\lastgood\system32 is redirected to %windir%\lastgood\SysWOW64. Access to %windir%\regedit.exe is redirected to %windir%\SysWOW64\regedit.exe.

...

32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.

Sysnative 仅适用于在 WOW64 模拟器中运行的 32 位应用程序。您可以在 32 位系统上运行的 32 位应用程序和 64 位系统上运行的 64 位应用程序中使用 System32:

TCHAR szCmdLine[MAX_PATH];

#ifndef _WIN64
BOOL bIsWow64Process = FALSE;
if (IsWow64Process(GetCurrentProcess(), &bIsWow64Process) && bIsWow64Process)
lstrcpy(szCmdLine, TEXT("C:\\Windows\\Sysnative\\notepad.exe"));
else
#endif
lstrcpy(szCmdLine, TEXT("C:\\Windows\\System32\\notepad.exe"));

hr = CreateProcess(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);

但是,您应该考虑到并不是每个人都将 Windows 安装在 C:\Windows 文件夹中,因此您应该询问 Windows System 文件夹的实际位置:

TCHAR szSysDir[MAX_PATH];

#ifndef _WIN64
BOOL bIsWow64Process = FALSE;
if (IsWow64Process(GetCurrentProcess(), &bIsWow64Process) && bIsWow64Process)
{
TCHAR szWinDir[MAX_PATH];
GetWindowsDirectory(szWinDir, MAX_PATH);
PathCombine(szSysDir, szWinDir, TEXT("Sysnative");
}
else
#endif
GetSystemDirectory(szSysDir, MAX_PATH);

TCHAR szCmdLine[MAX_PATH];
PathCombine(szCmdLine, szSysDir, TEXT("notepad.exe");

hr = CreateProcess(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);

关于c - 如何在 Visual Studios 中使用 CreateProcess 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45553733/

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