2010-03-15 33 views
0

考慮下面的代碼和它的可執行 - runner.exe連鎖多種ShellExecute的調用

#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 

現在,考慮這個批處理文件:

這個應該運行runner.exe並將notepad.exe作爲其命令行參數之一發送,不是嗎?然後,runner.exe的第二個實例應該運行notepad.exe - 這不會發生,我得到一個「Windows無法找到'am'。請確保您輸入了正確的名稱,然後再次嘗試」錯誤。如果我打印argc參數,它的第二個runner.exe實例是,它們都是奇怪的東西,如Files \ Microsoft,SQL,Files \ Common等。我無法弄清楚爲什麼會發生這種情況。我希望能夠儘可能多地使用命令行參數來執行儘可能多的runner.exe調用,或者至少2.我該怎麼做?

我正在使用Windows 7,如果這有所作爲。

+0

工作目錄是什麼? – lunixbochs 2010-03-15 16:41:30

+0

您可以嘗試在調用ShellExecute函數之前打印出SHELLEXECUTEINFO結構的值嗎? – dirkgently 2010-03-15 16:42:42

+0

@lunixbochs - bat文件和runner.exe文件都在同一個目錄中。 notepad.exe是在別的地方,但它應該重要,因爲'runner.exe notepad.exe'工作正常嗎?可以'shExecInfo.lpDirectory = NULL;'是問題嗎?我不確定我是否回答了你的問題,對不起,如果我沒有... – IVlad 2010-03-15 16:44:38

回答

3

你有一個錯誤在這一行:

Params += argv[i] + ' '; 

這將增加32至指針argv[i],這是不是你想要的。你可以把它分開,兩行:

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

或使用:

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

您可能還需要在增加的情況下圍繞每個參數報價包含空格。


我還設置fMaskSEE_MASK_NOASYNC,因爲MSDN指出:

應用該出口調用的ShellExecuteEx應指定該標誌後即可。

+0

這樣做了,謝謝!我忘記了argv [i]是一個指針。 – IVlad 2010-03-15 17:54:18

1

問題是這樣的線:

Params += argv[i] + ' ' 

argv[i]由於是char *類型的,添加32〜argv[i]所以會給你一個指向隨機存儲器的中間。

我會重寫到:

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

或者,如果你想成爲真正的好,你可以修改爲僅增加一個空間時,它的真正necesssary:

for (int i = 2; i < argc; ++i) 
{ 
    if (!Params.empty()) 
     Params += ' '; 
    Params += argv[i]; 
} 
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; 
} 
+0

@dirkgently - 希望你不介意,但是我修改了你的代碼,使其完全啓用了tchar,以便它可以用Unicode或MBCS模式編譯。 – 2010-03-15 18:06:31

+0

@RSK:好的,謝謝。 – dirkgently 2010-03-15 18:07:58