gpt4 book ai didi

c++ - 使用 CreateProcess 运行批处理文件

转载 作者:可可西里 更新时间:2023-11-01 16:30:59 26 4
gpt4 key购买 nike

我正在尝试使用 CreateProcess 启动一个新的环境 block 并在新的环境 block 中运行一个批处理文件。我已经通读了 CreateProcess 的 msdn 示例,并得出了如下所示的代码。

发生了什么,它将打开新的命令提示符,并停在那里。由于某种原因,它不会运行我的 .bat 文件。使用 system("CALL path") 将调用 .bat 文件。

#include <iostream>

#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>

#include <strsafe.h>

#define BUFSIZE 4096

int main()
{
//system("CALL C:\\HFSS\\setup_vars.bat");

//return 0;

LPWCH chNewEnv;
LPTSTR lpszCurrentVariable;
DWORD dwFlags = 0;
TCHAR szAppName[] = TEXT("C:\\windows\\system32\\cmd.exe");
TCHAR cmdArgs[] = TEXT("C:\\HFSS\\setup_var.bat");

STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL fSuccess;

// Copy environment strings into an environment block.
chNewEnv = GetEnvironmentStrings();

lpszCurrentVariable = (LPTSTR)chNewEnv;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MySetting=A"))))
{
printf("String copy failed\n");
return FALSE;
}

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MyVersion=2"))))
{
printf("String copy failed\n");
return FALSE;
}

// Terminate the block with a NULL byte.

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
*lpszCurrentVariable = (TCHAR)0;

// Create the child process, specifying a new environment block.

SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);

#ifdef UNICODE
dwFlags = CREATE_UNICODE_ENVIRONMENT;
#endif

fSuccess = CreateProcess(szAppName, cmdArgs, NULL, NULL, TRUE, dwFlags,
(LPVOID)chNewEnv, // new environment block
NULL, &si, &pi);

if (!fSuccess)
{
printf("CreateProcess failed (%d)\n", GetLastError());
return FALSE;
}

std::cout << "In new environment\n";
WaitForSingleObject(pi.hProcess, INFINITE);

return TRUE;
}

最佳答案

一些问题:

  1. 您需要将/C 选项传递给cmd.exe 以使其执行.bat 文件。
  2. CreateProcess 的第二个参数必须是可修改的字符串。不是字面意思。
  3. 您需要对文字中的反斜杠字符进行转义。
  4. lpszCurrentVariable 指向由 GetEnvironmentStrings 返回的缓冲区。您不能修改该缓冲区。您需要分配一个足够长度的新缓冲区并将环境复制到其中。然后添加您的修改。
  5. 环境 block 以双空终止。标准字符串函数对双空终止字符串没有用处。
  6. 使用像 StringCchCopy 这样的函数而不是 C 运行时函数只会让人感到困惑。不要将 MSDN 示例代码视为风格的典范。
  7. C 字符串是一个可以使用的绑定(bind)。但是你使用 C++,所以使用 std::wstring 和其他标准库类和函数。
  8. 您需要在导入 Windows.h 之前定义 WINDOWS_LEAN_AND_MEAN
  9. 对于 C++,int main(void) 是不正确的。无参数 mainint main()

以下代码向您展示了如何执行此操作:

#include <cstring>
#include <string>
#include <iostream>

#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>

std::wstring GetEnvString()
{
wchar_t* env = GetEnvironmentStrings();
if (!env)
abort();
const wchar_t* var = env;
size_t totallen = 0;
size_t len;
while ((len = wcslen(var)) > 0)
{
totallen += len + 1;
var += len + 1;
}
std::wstring result(env, totallen);
FreeEnvironmentStrings(env);
return result;
}

int main()
{
std::wstring env = GetEnvString();
env += L"myvar=boo";
env.push_back('\0'); // somewhat awkward way to embed a null-terminator

STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;

wchar_t cmdline[] = L"cmd.exe /C C:\\Desktop\\MyBatFile.bat";

if (!CreateProcess(NULL, cmdline, NULL, NULL, false, CREATE_UNICODE_ENVIRONMENT,
(LPVOID)env.c_str(), NULL, &si, &pi))
{
std::cout << GetLastError();
abort();
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

关于c++ - 使用 CreateProcess 运行批处理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25919451/

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