在Windows系統做網絡開發,很多時候都是使用Windows服務的模式,但在調度階段,我們更多的是使用控制台的模式。在開發程序的時候,我們在Program的Main入口進行判斷。最初開始使用Environment.UserInteractive屬性,在系統不系統服務的交互模式時,程序運行是正常的,但試過有Win7下,系統允許交互模式,結果在服務啟動的時候,跳轉到控制台的模式了,服務啟動不起來。只能在服務的調用方式下帶參數,然后在Main的參數中判斷是否為服務方式。這在一般的情況下是可以解決問題的。
后來有好幾個項目,使用了開源的Socket框架,框架本身是通過配置來啟動服務的,這樣,就沒有經過用戶的Main方法了,啟動帶參數的方法不行了,如果為了判斷啟動模式而加單獨的配置,不是很好的做法,通過Program加全局標識是可以解決程序自身啟動同框架啟動的判斷,但服務如果是通過自身的Main啟動,又只能靠加參數的方法了,整個實現感覺都是有點別扭。
在幾次的服務程序開發中,遇到一個寫文件的路徑問題,即取路徑總是不對,通過分析,Windows服務啟動時的環境默認路徑是從System32目錄,可能是Windows服務的宿主程序是從這開始的吧,這就有了解決如何判斷啟動模式的方法了。主要是通過宿主程序是程序集所在的目錄來判斷。具體如下 :
string curPath = System.Environment.CurrentDirectory;
string basePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
bool isRunWinService = (curPath != basePath);
如果兩個路徑不相同,我就認為是啟動Windows服務了。我們只要在程序的開始做判斷,這樣Environment.CurrentDirectory的路徑還是宿主程序,一般來說,開發人員很少去改動Environment.CurrentDirectory的。這樣我們做好的Exe程序支持用戶啟動,服務啟動,或框架自動的服務管理等模式了。