使用 Win32 执行命令

Posted

技术标签:

【中文标题】使用 Win32 执行命令【英文标题】:Execute command using Win32 【发布时间】:2015-07-22 12:46:38 【问题描述】:

我想执行 shell 命令来更新我的处理器 ATMega 2560 的固件,如下所示:

avrdude.exe -c breakout -P ft0 -p m2560 -U flash:w:\"file.cpp.hex\":a

我可以通过 ShellExecute() 函数来完成:

ShellExecute(0, L"open", L"cmd.exe", L"/C avrdude.exe -c breakout -P ft0 -p     m2560 -U flash:w:\"file.cpp.hex\":a > log.txt", 0, SW_HIDE);

但我想重定向输出缓冲区,所以我认为我应该使用 CreateProcess() 函数。我试过了,但没有成功。

CreateProcess(NULL, L"cmd /C avrdude.exe -c breakout -P ft0 -p m2560 -U flash:w:\"file.cpp.hex\":a", NULL, NULL, 0, 0, NULL, NULL, NULL, NULL);

【问题讨论】:

那么,您的CreateProcess() 会返回什么?假设这是一个错误,GetLastError() 会说什么? 【参考方案1】:

使用CreateProcess() 而不是ShellExecute(),并提供您自己的管道,以便您可以读取进程的输出。 MSDN 有一篇关于该主题的文章:

Creating a Child Process with Redirected Input and Output

例如:

LPWSTR cmdLine[] = L"avrdude.exe -c breakout -P ft0 -p m2560 -U flash:w:\"file.cpp.hex\":a";

SECURITY_ATTRIBUTES sa = 0;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

HANDLE hStdOutRd, hStdOutWr;
HANDLE hStdErrRd, hStdErrWr;

if (!CreatePipe(&hStdOutRd, &hStdOutWr, &sa, 0))

    // error handling...


if (!CreatePipe(&hStdErrRd, &hStdErrWr, &sa, 0))

    // error handling...


SetHandleInformation(hStdOutRd, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(hStdErrRd, HANDLE_FLAG_INHERIT, 0);

STARTUPINFO si = 0;
si.cbSize = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = hStdOutWr;
si.hStdError = hStdErrWr;

PROCESS_INFORMATION pi = 0;

if (!CreateProcessW(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))

    // error handling...

else

    // read from hStdOutRd and hStdErrRd as needed until the process is terminated...

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


CloseHandle(hStdOutRd);
CloseHandle(hStdOutWr);
CloseHandle(hStdErrRd);
CloseHandle(hStdErrWr);

【讨论】:

【参考方案2】:

问题已解决! 完整代码:

STARTUPINFO si =  sizeof(STARTUPINFO) ;
PROCESS_INFORMATION pi;

if (!CreateProcess(L"C:\\Windows\\System32\\cmd.exe",
    L" /C avrdude.exe -c breakout -P ft0 -p m2560 -U flash:w:\"file.cpp.hex\":a",
    NULL, NULL, 0, 0, NULL, NULL, &si, &pi))    

    printf("CreateProcess failed (%d).\n", GetLastError());
    return -1;

【讨论】:

那不好。第二个参数必须是可写的。而且您还会泄漏句柄。 另外,既然可以直接调用avrdude.exe,为什么还要调用cmd.exe @DavidHeffernanL 你不知道他是否在泄漏句柄,因为他没有显示CreateProcess() 成功时运行的代码。 CreateProcess: "lpCommandLine: 如果这个参数是一个常量字符串,函数可能会导致访问冲突。"

以上是关于使用 Win32 执行命令的主要内容,如果未能解决你的问题,请参考以下文章

Windows下载执行命令大全

Windows下载执行命令大全

我的电脑是win7的为啥netstat 命令执行不了啊?

rundll32执行js代码&Win32/Poweeliks

python import win32gui报错

smb(ms17-010)远程命令执行之msf