链接多个ShellExecute调用

时间:2010-03-15 16:38:41

标签: c++ winapi shellexecute

考虑以下代码及其可执行文件 - 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,如果这有所不同。

3 个答案:

答案 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;
}
相关问题