代码之家  ›  专栏  ›  技术社区  ›  IVlad

链接多个ShellExecute调用

  •  0
  • IVlad  · 技术社区  · 16 年前

    考虑下面的代码及其可执行文件 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;
    }
    

    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 14

    3 回复  |  直到 16 年前
        1
  •  3
  •   interjay    16 年前

    这行中有一个bug:

    Params += argv[i] + ' ';
    

    argv[i] ,这不是你想要的。可以将其分为两行:

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

    或使用:

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

    如果每个参数包含空格,还可以在其周围添加引号。


    我也会 fMask SEE_MASK_NOASYNC ,因为MSDN声明:

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

        2
  •  1
  •   R Samuel Klatchko    16 年前

    问题是这条线:

    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];
    }
    
        3
  •  1
  •   R Samuel Klatchko    16 年前

    我认为问题在于如何为下一个调用创建命令行参数:

     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;
    }
    
    推荐文章