考虑以下代码及其可执行文件 - runner.exe
:
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
SHELLEXECUTEINFO shExecInfo;
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = NULL;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = "open";
shExecInfo.lpFile = argv[1];
string Params = "";
for ( int i = 2; i < argc; ++i )
Params += argv[i] + ' ';
shExecInfo.lpParameters = Params.c_str();
shExecInfo.lpDirectory = NULL;
shExecInfo.nShow = SW_SHOWNORMAL;
shExecInfo.hInstApp = NULL;
ShellExecuteEx(&shExecInfo);
return 0;
}
这两个批处理文件都执行它们应该执行的操作,运行notepad.exe并运行notepad.exe并告诉它尝试打开test.txt:
1.
runner.exe notepad.exe
2.
runner.exe notepad.exe test.txt
现在,考虑一下这个批处理文件:
3.
runner.exe runner.exe notepad.exe
这个应该运行runner.exe并发送notepad.exe作为其命令行参数之一,不应该吗?然后,runner.exe的第二个实例应该运行notepad.exe - 这不会发生,我得到一个“Windows无法找到'am'。请确保您正确键入名称,然后再试一次”错误。如果我打印argc
参数,它对于第二个runner.exe实例来说是 14 ,它们都是奇怪的东西,比如Files \ Microsoft,SQL,Files \ Common等等。我无法弄清楚为什么会这样。我希望能够使用命令行参数尽可能多地编写runner.exe调用,或者至少2.我该怎么做?
我正在使用Windows 7,如果这有所不同。
答案 0 :(得分:3)
这行有一个错误:
Params += argv[i] + ' ';
这将向指针argv[i]
添加32,这不是你想要的。您可以将其分为两行:
Params += argv[i];
Params += ' ';
或使用:
Params += string(argv[i]) + ' ';
如果每个参数都包含空格,您可能还想在每个参数周围添加引号。
我还将fMask
设置为SEE_MASK_NOASYNC
,因为MSDN声明:
调用ShellExecuteEx后立即退出的应用程序应指定此标志。
答案 1 :(得分:1)
问题在于这一行:
Params += argv[i] + ' '
由于argv[i]
的类型为char *
,因此将{32}添加到argv[i]
,因此会为您提供指向随机内存中间的指针。
我会把它重写为:
Params += std::string(argv[i]) + ' ';
或者,如果你想真正做好,你可以修改它只在真正需要的时候添加一个空格:
for ( int i = 2; i < argc; ++i )
{
if (!Params.empty())
Params += ' ';
Params += argv[i];
}
答案 2 :(得分:1)
我认为问题在于如何为下次调用创建命令行参数:
Params += argv[i] + ' ';
无法按预期工作。尝试以下方法:
#include <windows.h>
#include <fstream>
#include <iostream>
#include <tchar.h>
using namespace std;
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif
int _tmain(int argc, TCHAR *argv[])
{
{
std::ofstream f("C:\\output.txt", std::ios::app);
f << "app called" << std::endl;
}
SHELLEXECUTEINFO shExecInfo;
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = NULL;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = _T("open");
shExecInfo.lpFile = argv[1];
tstring Params(_T(""));
for ( int i = 2; i < argc; ++i )
{
Params += argv[i];
Params += _T(' ');
}
shExecInfo.lpParameters = Params.c_str();
shExecInfo.lpDirectory = NULL;
shExecInfo.nShow = SW_SHOWNORMAL;
shExecInfo.hInstApp = NULL;
ShellExecuteEx(&shExecInfo);
return 0;
}