c#怎麼判斷一個程序運行後關閉?

本人初學,想用c#做檢測「一個程序運行後關閉」的檢測。判斷程序運行還好,但是運行後關閉怎麼判斷呢?

我想的是:

Timer事件{

如果程序運行

bool yx=true

if(yx==true){

檢測是否沒運行

bool yx=false

彈出信息框

}

}

可是感覺好複雜,還有重複。求問高人應該怎麼寫,最好有源代碼,謝謝


CreateProcess之後也可以WaitForSingleObject,C#的Process類應該也有一樣的做法,直接卡在哪裡就好了,簡直不需要操心。當然這樣就浪費了一個線程,顯得有點愚蠢,你再bing一下很快就能找到轉await的方法。


這個需求有兩種情況:

一。監控已經在運行的程序

二。由你的程序運行一個程序然後監控

先說第二種情況,這在.Net里很好實現,因為基礎庫提供了該功能,並且沒有@易天 說的那樣複雜,思路其實與輪子哥說的一樣,參考:Process.Exited Event 前提條件是設置EnableRaisingEvents 為true即可。

至於第一種情況,也分如下幾類:

一。無許可權的

二。已經設置EnableRaisingEvents屬性的

三。未設置EnableRaisingEvents屬性的

從這三種情況來看,無許可權的你就不要想了。已經設置的,直接訂閱退出事件就好,未設置的,設置了再訂閱,設置失敗的,你就不用想了。

另:sysinternals的procexp工具可以看到每個進程的運行情況,不知道那是怎麼實現的,對Windows機制不太熟,不了解。


輪子哥不是已經說了么。如果用C#寫界面的話一定繞不開線程和進程,所以你先看看多線程這一塊吧。打好基礎就很簡單了,套兩個Task,第一個阻塞,第二個等第一個完了之後就知道程序已經結束了。

private void Button_Click(object sender, RoutedEventArgs e)
{
var inputString = InputBox.Text;
if (string.IsNullOrWhiteSpace(inputString))
{
return;
}
var words = inputString.Split( );
var processName = words[0];
var processArgs = string.Join(" ", words.Skip(1));
Task.Run(() =&>
{
var process = Process.Start(processName, processArgs);
process.WaitForExit();
return process.ExitCode;
}).ContinueWith(result =&> { MessageBox.Show("程序已停止","程序已停止"); });
}

當然如果你需要操作界面的話上面的方法就不行了,因為對界面組件的調用都必須在圖形界面的線程中做。如果在上面的任務中調用了界面的組件的話,就拋出異常了。這時候點擊函數就必須聲明為非同步await的。比方說我現在要判斷程序的結束碼,如果是0(正常結束),就把主界面染成綠色;如果非正常結束,就染成紅色。所以這部分代碼必須通怪非同步調用,放到點擊函數裡面,不能放到其他地方。

當然其實可以不用非同步,把點擊函數阻塞了也行。不過這時候你的程序就卡死了,滑鼠會一直轉圈,直到外部程序結束為止。所以我們順帶明白了,那些動不動就卡死的程序,多線程一定沒做好,把有些阻塞操作放到主線程中了。

private async void Button_Click(object sender, RoutedEventArgs e)
{
var inputString = InputBox.Text;
if (string.IsNullOrWhiteSpace(inputString))
{
return;
}
var words = inputString.Split( );
var processName = words[0];
var processArgs = string.Join(" ", words.Skip(1));
var exitCode = await Task.Run(() =&>
{
var process = Process.Start(processName, processArgs);
process.WaitForExit();
return process.ExitCode;
});

if (exitCode == 0)
{
ParentGrid.Background = Brushes.LawnGreen;
}
else
{
ParentGrid.Background = Brushes.Red;
}
}

如果覺得哪裡看不懂,說明你基礎知識不過關。還是先看看多線程啥的,搞明白了圖形界面就好弄了。不然各種稀奇古怪的錯誤就出來了,你都不知道啥原因。

看了各位的評論,原來還可以註冊一個完成事件,這下連多餘的線程也不用開了。

private void Button_Click(object sender, RoutedEventArgs e)
{
var inputString = InputBox.Text;
if (string.IsNullOrWhiteSpace(inputString))
{
return;
}
var words = inputString.Split( );
var processName = words[0];
var processArgs = string.Join(" ", words.Skip(1));

var process = new Process();
process.StartInfo.FileName = processName;
process.StartInfo.Arguments = processArgs;
process.EnableRaisingEvents = true;
process.Exited += Process_Finish;
process.Start();
}

private void Process_Finish(object sender, EventArgs e)
{
{
MessageBox.Show("程序已停止", "程序已停止");
}
}

如果要判斷其他程序是否運行,我不清楚你其他程序在哪裡定義的。如果只是要判斷是否在運行到時也好辦。Process類也提供了相應方法,調用一下就行了。

private void Button_Click(object sender, RoutedEventArgs e)
{
var inputString = InputBox.Text;
int pid = Convert.ToInt32(inputString);

try
{
var process = Process.GetProcessById(pid);
if (process.HasExited)
{
MessageBox.Show("程序已停止", "程序已停止");
}
else
{
MessageBox.Show("程序還在運行", "程序還在運行");
}
}
catch (Exception ex)
{
MessageBox.Show("不存在該程序", "不存在該程序");
}
}


推薦閱讀:

父子關係結構梳理(Golang實現)
推薦三個很贊的英語學習網站
用 ConstraintLayout 和 ConstraintSet 實現 Android 關鍵幀動畫
Flyme 6 同時基於安卓 5.1 和安卓 6.0 在編程方面不會更難嗎?

TAG:編程 | C#編程 | 電腦技術 |