天天看點

C#中Process類啟動可執行程式導緻可執行程式崩潰

問題說明

  項目組開發的程式(簡稱程式A)要調用另外一個可執行程式(簡稱程式B),而在程式B中又通過動态加載的方式調用了一個動态連結庫中的函數(簡稱函數C)。程式A和程式B都是用C#語言開發的,調用方式是在程式A中使用Process類通過帶參數的方式啟動程式B,如下圖所示,調用的代碼大緻如下:

Process myProcess = new Process();
myProcess.StartInfo.FileName = programAFileAddress;
myProcess.StartInfo.Arguments = programAArguments;
myProcess.Start();
           
C#中Process類啟動可執行程式導緻可執行程式崩潰

  程式B獨立運作時可以正常啟動,也能夠正常加載動态連結庫并調用其中的函數C。但是如果在程式A中通過帶參數的Process類調用程式B,則在調用動态連結庫中的函數C時報錯,外在表現是作業系統給出一個應用系統崩潰(APPCRASH)的提示,指明崩潰的程式是程式B,調試到程式B中後發現是在調用動态連結庫中的函數C時報錯,錯誤資訊大緻為記憶體損壞無法讀取等等。

解決方法

  程式A和程式B并沒有在同一個目錄下,通過百度以及咨詢經驗豐富的同僚後,認為可能是在程式A中調用程式B後,程式B啟動後繼承了程式A的某些資訊(純屬個人猜測),于是在MSDN中查找Process類中是否有屬性或方法可以設定通過Process類啟動的程式能夠獨立運作或者是不使用調用程式的資訊等,最終發現Process類中好像是沒有這種屬性或方法。不過在找的過程中在Process的StartInfo中找到了一個屬性WorkingDirectory,該屬性用于擷取或設定包含要啟動的程序的目錄(詳細屬性介紹請參見參考文獻1),于是猜測會不會是程式B啟動時預設的目錄用的程式A的目錄(不懂原理,純屬猜測),然後抱着試試的态度将WorkingDirectory設定為程式B的目錄,代碼如下,再從程式A中啟動程式B後,在程式B中就可以正常調用動态連結庫中的函數C了。

Process myProcess = new Process();
myProcess.StartInfo.FileName = programAFileAddress;
myProcess.StartInfo.Arguments = programAArguments;
myProcess.StartInfo.WorkingDirectory = programADir;
myProcess.Start();
           

參考文獻:

[1]https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.processstartinfo.workingdirectory?view=netframework-4.8