如何使用 Vb.NET 或 C# 终止进程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/116090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I kill a process using Vb.NET or C#?
提问by bugBurger
I have a scenario where I have to check whether user has already opened Microsoft Word. If he has, then I have to kill the winword.exe process and continue to execute my code.
我有一个场景,我必须检查用户是否已经打开了 Microsoft Word。如果他有,那么我必须杀死 winword.exe 进程并继续执行我的代码。
Does any one have any straight-forward code for killing a process using vb.net or c#?
有没有人有使用 vb.net 或 c# 杀死进程的任何直接代码?
采纳答案by Blair Conrad
You'll want to use the System.Diagnostics.Process.Killmethod. You can obtain the process you want using System.Diagnostics.Proccess.GetProcessesByName.
您需要使用System.Diagnostics.Process.Kill方法。您可以使用System.Diagnostics.Proccess.GetProcessesByName获取所需的进程 。
Examples have already been posted here, but I found that the non-.exe version worked better, so something like:
示例已经在此处发布,但我发现非 .exe 版本效果更好,例如:
foreach ( Process p in System.Diagnostics.Process.GetProcessesByName("winword") )
{
try
{
p.Kill();
p.WaitForExit(); // possibly with a timeout
}
catch ( Win32Exception winException )
{
// process was terminating or can't be terminated - deal with it
}
catch ( InvalidOperationException invalidException )
{
// process has already exited - might be able to let this one go
}
}
You probably don't have to deal with NotSupportedException
, which suggests that the process is remote.
您可能不必处理NotSupportedException
,这表明该过程是远程的。
回答by Nick Berardi
Here is an easy example of how to kill all Word Processes.
这是一个如何杀死所有字进程的简单示例。
Process[] procs = Process.GetProcessesByName("winword");
foreach (Process proc in procs)
proc.Kill();
回答by Tomer Gabel
Something like this will work:
像这样的事情会起作用:
foreach ( Process process in Process.GetProcessesByName( "winword" ) )
{
process.Kill();
process.WaitForExit();
}
回答by mdb
Killing the Word process outright is possible (see some of the other replies), but outright rude and dangerous: what if the user has important unsaved changes in an open document? Not to mention the stale temporary files this will leave behind...
彻底杀死 Word 进程是可能的(请参阅其他一些回复),但这是非常粗鲁和危险的:如果用户在打开的文档中有重要的未保存更改怎么办?更不用说这将留下的陈旧临时文件......
This is probably as far as you can go in this regard (VB.NET):
这可能是你在这方面所能做的(VB.NET):
Dim proc = Process.GetProcessesByName("winword")
For i As Integer = 0 To proc.Count - 1
proc(i).CloseMainWindow()
Next i
This will close all open Word windows in an orderly fashion (prompting the user to save his/her work if applicable). Of course, the user can always click 'Cancel' in this scenario, so you should be able to handle this case as well (preferably by putting up a "please close all Word instances, otherwise we can't continue" dialog...)
这将以有序的方式关闭所有打开的 Word 窗口(如果适用,提示用户保存他/她的工作)。当然,在这种情况下,用户始终可以单击“取消”,因此您也应该能够处理这种情况(最好通过放置“请关闭所有 Word 实例,否则我们无法继续”对话框... )
回答by Chris Lawlor
You can bypass the security concerns, and create a much politer application by simply checking if the Word process is running, and asking the user to close it, then click a 'Continue' button in your app. This is the approach taken by many installers.
您可以绕过安全问题,通过简单地检查 Word 进程是否正在运行,并要求用户关闭它,然后在您的应用程序中单击“继续”按钮来创建一个更礼貌的应用程序。这是许多安装人员采用的方法。
private bool isWordRunning()
{
return System.Diagnostics.Process.GetProcessesByName("winword").Length > 0;
}
Of course, you can only do this if your app has a GUI
当然,只有在您的应用程序具有 GUI 时才能执行此操作
回答by Vova Popov
public bool FindAndKillProcess(string name)
{
//here we're going to get a list of all running processes on
//the computer
foreach (Process clsProcess in Process.GetProcesses()) {
//now we're going to see if any of the running processes
//match the currently running processes by using the StartsWith Method,
//this prevents us from incluing the .EXE for the process we're looking for.
//. Be sure to not
//add the .exe to the name you provide, i.e: NOTEPAD,
//not NOTEPAD.EXE or false is always returned even if
//notepad is running
if (clsProcess.ProcessName.StartsWith(name))
{
//since we found the proccess we now need to use the
//Kill Method to kill the process. Remember, if you have
//the process running more than once, say IE open 4
//times the loop thr way it is now will close all 4,
//if you want it to just close the first one it finds
//then add a return; after the Kill
try
{
clsProcess.Kill();
}
catch
{
return false;
}
//process killed, return true
return true;
}
}
//process not found, return false
return false;
}
回答by MrVB.NET
It's better practise, safer and more polite to detect if the process is running and tell the user to close it manually. Of course you could also add a timeout and kill the process if they've gone away...
检测进程是否正在运行并告诉用户手动关闭它是更好的做法,更安全,更礼貌。当然,如果它们已经消失,您也可以添加超时并终止进程......
回答by Ashok
Please see the example below
请看下面的例子
public partial class Form1 : Form
{
[ThreadStatic()]
static Microsoft.Office.Interop.Word.Application wordObj = null;
public Form1()
{
InitializeComponent();
}
public bool OpenDoc(string documentName)
{
bool bSuccss = false;
System.Threading.Thread newThread;
int iRetryCount;
int iWait;
int pid = 0;
int iMaxRetry = 3;
try
{
iRetryCount = 1;
TRY_OPEN_DOCUMENT:
iWait = 0;
newThread = new Thread(() => OpenDocument(documentName, pid));
newThread.Start();
WAIT_FOR_WORD:
Thread.Sleep(1000);
iWait = iWait + 1;
if (iWait < 60) //1 minute wait
goto WAIT_FOR_WORD;
else
{
iRetryCount = iRetryCount + 1;
newThread.Abort();
//'-----------------------------------------
//'killing unresponsive word instance
if ((wordObj != null))
{
try
{
Process.GetProcessById(pid).Kill();
Marshal.ReleaseComObject(wordObj);
wordObj = null;
}
catch (Exception ex)
{
}
}
//'----------------------------------------
if (iMaxRetry >= iRetryCount)
goto TRY_OPEN_DOCUMENT;
else
goto WORD_SUCCESS;
}
}
catch (Exception ex)
{
bSuccss = false;
}
WORD_SUCCESS:
return bSuccss;
}
private bool OpenDocument(string docName, int pid)
{
bool bSuccess = false;
Microsoft.Office.Interop.Word.Application tWord;
DateTime sTime;
DateTime eTime;
try
{
tWord = new Microsoft.Office.Interop.Word.Application();
sTime = DateTime.Now;
wordObj = new Microsoft.Office.Interop.Word.Application();
eTime = DateTime.Now;
tWord.Quit(false);
Marshal.ReleaseComObject(tWord);
tWord = null;
wordObj.Visible = false;
pid = GETPID(sTime, eTime);
//now do stuff
wordObj.Documents.OpenNoRepairDialog(docName);
//other code
if (wordObj != null)
{
wordObj.Quit(false);
Marshal.ReleaseComObject(wordObj);
wordObj = null;
}
bSuccess = true;
}
catch
{ }
return bSuccess;
}
private int GETPID(System.DateTime startTime, System.DateTime endTime)
{
int pid = 0;
try
{
foreach (Process p in Process.GetProcessesByName("WINWORD"))
{
if (string.IsNullOrEmpty(string.Empty + p.MainWindowTitle) & p.HasExited == false && (p.StartTime.Ticks >= startTime.Ticks & p.StartTime.Ticks <= endTime.Ticks))
{
pid = p.Id;
break;
}
}
}
catch
{
}
return pid;
}
回答by tyler_mitchell
In my tray app, I needed to clean Excel and Word Interops. So This simple method kills processes generically.
在我的托盘应用程序中,我需要清理 Excel 和 Word Interops。所以这个简单的方法通常会杀死进程。
This uses a general exception handler, but could be easily split for multiple exceptions like stated in other answers. I may do this if my logging produces alot of false positives (ie can't kill already killed). But so far so guid (work joke).
这使用通用异常处理程序,但可以很容易地拆分为多个异常,如其他答案中所述。如果我的日志记录产生大量误报(即不能杀死已经被杀死),我可能会这样做。但到目前为止还好(工作笑话)。
/// <summary>
/// Kills Processes By Name
/// </summary>
/// <param name="names">List of Process Names</param>
private void killProcesses(List<string> names)
{
var processes = new List<Process>();
foreach (var name in names)
processes.AddRange(Process.GetProcessesByName(name).ToList());
foreach (Process p in processes)
{
try
{
p.Kill();
p.WaitForExit();
}
catch (Exception ex)
{
// Logging
RunProcess.insertFeedback("Clean Processes Failed", ex);
}
}
}
This is how i called it then:
我当时是这样称呼它的:
killProcesses((new List<string>() { "winword", "excel" }));