C#操作Execl如何释放进程里占用的Excel.exe
好悲催啊!刚才那个文章刚刚要快写完了,一不小心浏览器崩溃了,呜呜……结果在进来发现刚才写的东西全都没了……蛋疼啊……
提到释放进程我们大家一般都会想到 System.Diagnostics.Process 没错,查了一些MSDN给的解释如下:
============================================================================
提供对本地和远程进程的访问并使您能够启动和停止本地系统进程。
如果未指定 MachineName 属性,则默认为本地计算机(“.”)。
有两个选项可用于将新的 Process 组件与计算机上的进程关联。 第一个选项是使用构造函数创建 Process 组件,设置 StartInfo 属性的相应成员,并调用 Start 使 Process 与新的系统进程关联。 第二个选项是使用 GetProcessById 或 GetProcesses 返回值之一将 Process 与当前运行的系统进程关联。
如果使用 Start 方法的 static 重载来启动新的系统进程,则该方法会创建新的 Process 组件并将其与该进程关联。
当 ProcessStartInfo.UseShellExecute 属性设置为它的默认值 true 时,您可以像使用 Windows 的 Start 菜单的 Run 对话框那样启动应用程序和文档。 当 ProcessStartInfo.UseShellExecute 为 false 时,您只能启动可执行文件。
可从命令行调用的任何可执行文件都可用以下两种方式之一启动:通过设置 StartInfo 属性的适当成员并且不带任何参数调用 Start 方法,或者通过向 staticStart 成员传递适当的参数。
您可以使用构造函数、静态 Start 重载之一或者 GetProcessById、GetProcesses 或 GetProcessesByName 方法中的任何一个来创建 Process 组件。 创建完该组件后,在关联的进程中会加入一个视图。 它不是动态视图,当进程属性在内存中更改后不会自动更新视图本身。 相反,您必须为该组件调用 Refresh 来更新应用程序中的 Process 属性信息。
============================================================================
想获取进程只有三个方法: GetProcessById、GetProcesses 或 GetProcessesByName 根据ID、所有的进程、进程的名字,所有的肯定不行,都杀死了计算机也就关机了,根据名字,如果存在多个同名字的就会误杀,只有根据ID了,在任务管理器里面会看到所有的进程都一个不同的PID。但是又怎样去获取要杀死的那个进程的PID呢?这个似乎真的纠结中……突然间想起了win API 中的GetWindowThreadProcessId,通过句柄来返回进程ID标识o(∩_∩)o 哈哈……似乎有门了!
==============================================================================
百科解释:
1.函数原型
DWORD GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId );
2.参数
hWnd [in] (向函数提供的)被查找窗口的句柄. lpdwProcessId [out] 进程号的存放地址(变量地址) Pointer to a variable that receives the process identifier. If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the process to the variable; otherwise, it does not. (如果参数不为NULL,即提供了存放处--变量,那么本函数把进程标志拷贝到存放处,否则不动作。)
3.返回值
The return value is the identifier of the thread that created the window. 返回线程号,注意, lpdwProcessId 是存放进程号的变量。返回值是线程号, lpdwProcessId 是进程号存放处。 当然可以把答案再放到其它地方。如 DWORD dwPID, dwTID; dwTID = GetWindowThreadProcessId( hWnd, &dwPID );
4.函数相关信息
Header Declared in Winuser.h, include Windows.h Import library User32.lib Minimum operating systems Windows 95, Windows NT 3.1
------------------------------------------------------------------------------------------------------------------------------
c#声明
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
实例
int calcID=0;
int calcTD=0;
calcTD = GetWindowThreadProcessId(FrmMain.mainhWnd, out calcID);
返回值calcTD为线程ID
输出值calcID为进程ID
================================================================================
看看Excel那个API里面有没有什么返回句柄的属性吧……苦心人天不负在Application里面找到了Hwndo(∩_∩)o 哈哈是一把,成功了吼吼……
================================================================================
具体关键代码
引用命名空间:
using System.Runtime.InteropServices;
注册API:
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
Excel.Application objExcel = new Excel.Application();
IntPtr t = new IntPtr(objExcel.Hwnd);
//……对Excel了操作
objExcel.Quit();
objExcel = null;
int id = 0;
GetWindowThreadProcessId(t, out id);
System.Diagnostics.Process P = System.Diagnostics.Process.GetProcessById(id);
P.Kill();