如何使用 Vb.NET 或 C # 杀死进程?

我有一个场景,我必须检查用户是否已经打开 MicrosoftWord。如果是这样,那么我必须终止 winword.exe 进程并继续执行我的代码。

是否有人有任何直接的代码来终止使用 vb.net 或 c # 的进程?

173525 次浏览

您需要使用 系统,诊断,处理,杀戮方法 System.Diagnostics. Process.GetProcessesByName .

这里已经发布了一些示例,但是我发现非.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
}
}

您可能不需要处理 NotSupportedException,这表明这个过程是远程的。

下面是一个简单的例子,说明如何杀死所有的 Word 进程。

Process[] procs = Process.GetProcessesByName("winword");


foreach (Process proc in procs)
proc.Kill();

这样的方法会奏效的:

foreach ( Process process in Process.GetProcessesByName( "winword" ) )
{
process.Kill();
process.WaitForExit();
}

完全关闭 Word 进程是可能的(参见其他一些回复) ,但是完全粗鲁和危险: 如果用户在一个打开的文档中有重要的未保存的更改怎么办?更不用说这会留下的陈旧的临时文件。

在这方面,您可能只能做到这一点(VB.NET) :

    Dim proc = Process.GetProcessesByName("winword")
For i As Integer = 0 To proc.Count - 1
proc(i).CloseMainWindow()
Next i

这将有序地关闭所有打开的 Word 窗口(如果适用,提示用户保存他/她的工作)。当然,在这个场景中用户总是可以点击“取消”,所以您也应该能够处理这种情况(最好是通过放置一个“请关闭所有 Word 实例,否则我们无法继续”对话框...)

您可以绕过安全问题,创建一个更加礼貌的应用程序,只需检查 Word 进程是否正在运行,并要求用户关闭它,然后单击应用程序中的“继续”按钮。这是许多安装程序采用的方法。

private bool isWordRunning()
{
return System.Diagnostics.Process.GetProcessesByName("winword").Length > 0;
}

当然,只有当应用程序具有 GUI 时才能这样做

    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;
}

检测进程是否正在运行并告诉用户手动关闭进程是更好的做法、更安全和更礼貌的做法。当然,您也可以添加一个超时并终止进程,如果它们已经消失..。

请看下面的例子

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;
}

在我的托盘应用程序中,我需要清理 Excel 和 Word Interops。

这使用一个通用的异常处理程序,但是可以很容易地为多个异常进行分割,如其他答案中所述。如果我的日志记录产生很多假阳性,我可能会这样做(即不能杀死已经杀死)。但是到目前为止,指导(工作笑话)。

/// <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);
}
}
}

我当时是这么说的:

killProcesses((new List<string>() { "winword", "excel" }));

我打开了一个 Word 文件, 2. 现在我通过 vb.net 运行时程序打开另一个 word 文件。 3. 我想通过编程方式单独终止第二个进程。 4. 不要杀死第一个进程