假如有個外部程序名爲A.exe,放在目錄E:\temp\下,然後我們用C++或者C#寫一個程序調用這個A.exe的話(假設這個調用者所在的路徑在D:\invoke),通常會採用下面的代碼:
// C# code string exeName = @"E:\temp\A.exe"; Process g = new Process(); g.StartInfo.UseShellExecute = false; g.StartInfo.RedirectStandardOutput = false; g.StartInfo.FileName = exeName; g.StartInfo.CreateNoWindow = false; g.StartInfo.Arguments = "-R"; // Supposing there is a "-R" parameter g.Start(); g.WaitForExit();
// C++ code SHELLEXECUTEINFO ShExecInfo = {0}; ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = TEXT("open"); ShExecInfo.lpFile = TEXT("E:\\temp\\A.exe"); ShExecInfo.lpParameters = TEXT("-R"); ShExecInfo.nShow = SW_HIDE; ShExecInfo.hInstApp = NULL; ShellExecuteEx(&ShExecInfo); WaitCursorBegin(); WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
但是當我們的A.exe程序中使用相對路徑創建或者打開文件時,就會發現用上面程序調用A.exe時,會提示無法創建文件或者無法打開文件,其原因是:
- A.exe的調用者和A.exe不在同一個目錄下;
- 當異地調用A.exe時,A.exe程序裏的相對路徑都是相對於其調用者所在的目錄而言(都是相對於D:\invoke)
解決辦法很簡單:
- C#代碼中,加入g.StartInfo.WorkingDirectory = @"E:\temp";
- C++代碼中,加入ShExecInfo.lpDirectory = TEXT("E:\\temp\\");
- 上面兩行代碼的作用是指定A.exe運行的目錄,這樣就保證了A.exe裏面使用的相對於路徑是相對於A.exe所在的目錄,即E:\temp