0

考虑以下代码及其可执行文件 - 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。

4

3 回答 3

3

您在这一行中有一个错误:

Params += argv[i] + ' ';

这会将 32 添加到指针argv[i],这不是您想要的。您可以将其分为两行:

Params += argv[i];
Params += ' ';

或使用:

Params += string(argv[i]) + ' ';

您可能还想在每个参数周围添加引号,以防它包含空格。


我也设置fMaskSEE_MASK_NOASYNC,因为 MSDN 声明:

在调用 ShellExecuteEx 后立即退出的应用程序应指定此标志。

于 2010-03-15T17:42:42.117 回答
1

问题是这一行:

Params += argv[i] + ' '

因为是添加 32argv[i]的类型,所以会给你一个指向随机内存中间的指针。char *argv[i]

我会将其重写为:

Params += std::string(argv[i]) + ' ';

或者,如果您想变得非常好,您可以修改它以仅在真正需要时添加一个空格:

for ( int i = 2; i < argc; ++i )
{
    if (!Params.empty())
        Params += ' ';
    Params += argv[i];
}
于 2010-03-15T17:44:05.973 回答
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;
}
于 2010-03-15T17:52:49.373 回答