使用CreateProcess函数

时间:2016-04-20 20:09:38

标签: c++ windows winapi

我尝试在c ++中使用Microsoft Visual Studio Express 2013 for Windows桌面创建类似于cmd的内容,我的一个函数应该通过键入" skype.exe&#34启动类似open skype的过程;。我在互联网上搜索并找到了应该为我工作的CreateProcess函数。当我创建一个函数,它接收我创建的一个名为Line的类值(类的名称,但它并没有真正满足),并以下面显示的方式使用CreateProcess函数,我必须输入我的cmd "启动skype.exe"但我想通过只写#34; skype.exe"就像在常规cmd中一样工作,我该怎么办呢? (l.parameter只是一个包含单词skype的字符串)

void execute(Line l){

STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPSTR s = const_cast<char *>(l.parameter.c_str());
if (!CreateProcess(NULL, s, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
    printf("CreateProcess failed (%d).\n", GetLastError());
    return;
}

// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);

// Close process and thread handles. 
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);}

2 个答案:

答案 0 :(得分:3)

首先是:

LPSTR s = const_cast<char *>(l.parameter.c_str());

是个坏主意,CreateFile接受lpCommandLine非const缓冲区有一个原因 - 它可能会修改它:

  

系统在命令行字符串中添加一个终止空字符,以将文件名与参数分开。这会将原始字符串分为两个字符串以进行内部处理。

所以你应该传递一个数组,例如:

TCHAR szCmd[MAX_PATH] = {0};

然后问你的问题,如果&#34;启动skype.exe&#34;适合你,你想在命令行只输入skype.exe - 那么为什么不连接字符串?例如:

_tcscat(szCmd, _T("start "));
_tcscat(szCmd, parameter.c_str());

并将szCmd传递给CreateProcess

问题是你是否使用UNICODE构建,如果是,那么确保参数是std :: wstring,否则如果你使用非UNICODE构建(看起来那样是真的)那么std :: string就可以了。

答案 1 :(得分:3)

start不是可执行文件,它是cmd.exe的一项功能,因此要通过start skype.exe调用CreateProcess(),您必须指定cmd.exe为命令和/C start skype.exe作为参数。

Line l;
line.parameter = "cmd.exe /C start skype.exe";
execute(l);

但是在这种情况下这是过度的,因为尽管你声称的是start,但实际上并不需要skype.exe。完全有效,最好直接调用skype.exe作为命令。

但是,您必须向start提供完整路径(如果您要调用CreateProcess(),则相同),否则App Paths将无法使用找到它,因为Skype没有在注册表的Phone密钥中注册其.exe文件路径,或者在系统的{skype.exe子文件夹(%PATH%所在的路径)中注册{1}}环境变量。

例如:

Line l;
line.parameter = "C:\\Program Files (x86)\\Skype\\Phone\\Skype.exe";
execute(l);

幸运的是,Skype确实在注册表中存储了skype.exe的完整路径,特别是在以下密钥中:

HKEY_CURRENT_USER\Software\Skype\Phone

它存储在名为REG_SZ的{​​{1}}值中。

"SkypePath"