C# 终止由特定应用程序启动的excel进程

C# 终止由特定应用程序启动的excel进程,c#,excel-interop,C#,Excel Interop,我有一个控制台应用程序,在其中我打开许多excel应用程序进行一些处理。最后,我想终止此控制台应用程序打开的所有Excel进程。所以,我使用的代码如下: System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses(); for (int i = 0; i < procs.Length; i++) { if (procs[i].ProcessName == "EXCEL") {

我有一个控制台应用程序,在其中我打开许多excel应用程序进行一些处理。最后,我想终止此控制台应用程序打开的所有Excel进程。所以,我使用的代码如下:

System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses();
for (int i = 0; i < procs.Length; i++)
{
    if (procs[i].ProcessName == "EXCEL")
    {
        procs[i].Kill();
    }
}
System.Diagnostics.Process[]procs=System.Diagnostics.Process.getprocesss();
for(int i=0;i
但此代码关闭我计算机中的所有excel应用程序,包括应用程序未打开的应用程序。 我的问题是,如何修改此代码以仅关闭由控制台应用程序打开的excel应用程序

尝试使用()

一旦超出范围,它将自动关闭进程。这将是关闭excel进程的最简单也是最好的做法

否则,您可以手动关闭/处置对象,而不是终止进程


希望这会有所帮助。

我建议在(Excel)
进程上做一些包装,完成后可以调用
Close

public class ExcelProcess
{
    Process m_Process;
    public ExcelProcess(/* parameters of your choice */)
    {
        // instantiate process and assign it to the m_Process variable
    }

    public ExcelProcess(int id)
    {
        // this will instantiate process object and hook to the process with specified process id
        m_Process = Process.GetProcessById(id);
    }

    public void Close()
    {
        m_Process.Kill();
    }

    public override ToString()
    {
        // this will return process id as a string value
        return m_Process.Id.ToString();
    }
}
拥有像上面那样的对象,您可以:
1.通过将“实例”的列表/数组序列化到某个文本文件(如
.ToString()

2.直接控制将由该对象处理的进程(每个
ExcelProcess
都可以有自己的IPC与外部进程通信,您可以将流从进程重定向到进程) 3. 当其他人关闭当前链接到该对象的应用程序时,感到困惑

扩展以上几点,我们假设用户无法关闭连接到
ExcelProcess
的应用程序

您可以创建一个holder对象/字段,然后将其序列化:

List<ExcelProcess> m_ExcelProcesses;
现在假设您想在另一个应用程序中关闭它们:

byte[] nl = new byte[2] { 0x0D, 0x0A }; // new line
using (FileStream fs = File.Create("C:\SomeArbitrary\PathToFile.txt"))
{
    foreach(ExcelProcess proc in m_Processes)
    {  
        byte[] b = BitConverter.GetBytes(int.Parse(proc.ToString()));
        fs.Write(b, 0, b.Length);
        fs.Write(nl, 0, nl.Length);
    }
}
之后,在负责关闭这些文件的新进程中,只需读取所有值并重写(或删除)文件


在任意位置添加一些文本文件(例如“C:\Windows\Temp\meExcelProcesses.txt”),然后在启动终止这些文件的进程时,从该文件中读取进程ID。关闭对象上的Excel而不是终止进程如何?Hi@FatTony我试图关闭所有Excel应用程序、工作簿和工作簿,但我同时打开了15个应用程序,最终我有2个excel进程仍然打开。我打开了类似于foreach excel的应用程序:excelWorkBook2.Close(true);System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkBook2);excelWorkBook2=null;excelApplication.Quit();excelApplication=null;您好@m.rogalski,这是个好主意,但我如何才能获得excel进程id?(例如,我可以在代码中直接使用一个列表或一个表来存储这些idI,我使用的是:excelWorkBook2.Close(true);targetSheet2=null;System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkBook2);excelWorkBook2=null;excelApplication.Quit();excelApplication=null;但它并没有关闭所有文件,我在代码中打开了14个应用程序,最后我有两个应用程序没有关闭,这就是为什么我要直接杀死它们processes@LaalaDjelouah如果它无法关闭,这意味着您正在泄漏您应该清理的内容的引用。如果您清理,它确实会关闭正确设置,但很难正确设置。通常使用第三方库更容易。我支持@Ian的建议。您是否尝试过使用LinqToExcel来代替它。它没有那么混乱。这里有一个链接哦,非常感谢@m.rogalski,这正是我要搜索的!很好的解释
foreach(var process in Process.GetProcessesByName("excel"))
{
    m_ExcelProcesses.Add(new ExcelProcess(process.Id));
} 
byte[] nl = new byte[2] { 0x0D, 0x0A }; // new line
using (FileStream fs = File.Create("C:\SomeArbitrary\PathToFile.txt"))
{
    foreach(ExcelProcess proc in m_Processes)
    {  
        byte[] b = BitConverter.GetBytes(int.Parse(proc.ToString()));
        fs.Write(b, 0, b.Length);
        fs.Write(nl, 0, nl.Length);
    }
}
byte[] pidBytes = new byte[4]; // we stored int which is 4 bytes wide;
using (FileStream fs = File.OpenRead("C:\SomeArbitrary\PathToFile.txt"))
{
    while(fs.CanRead)
    {
        fs.Read(pidBytes, 0, sizeof(int));
        m_Processes.Add(new ExcelProcess(BitConverter.ToInt32(pidBytes, 0)));
        fs.ReadByte(); // CR - 0x0D
        fs.ReadByte(); // LF - 0x0A
    }
}