2017-07-24 92 views
1

我有一个控制台应用程序,其中我打开许多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(); 
    } 
} 

但是这个代码将关闭所有擅长在我的电脑,包括未通过我的应用程序打开那些应用程序。 我的问题是,我怎样才能修改这段代码来关闭我的控制台应用程序打开的excel应用程序?

+0

一些任意位置添加一些文本文件(如“C:\ WINDOWS \ TEMP \ meExcelProcesses.txt”。)然后在启动过程中,杀死那些,从那个文件只是读进程ID。 –

+2

如何关闭对象的Excel而不是杀死进程? – FatTony

+0

嗨@FatTony我试图关闭所有我的Excel应用程序,工作簿和工作簿,但是我打开了15个应用程序,同时最终还是打开了2个Excel过程。我有这样的excel应用程序打开foreach: excelWorkBook2.Close(true); System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkBook2); excelWorkBook2 = null; excelApplication.Quit(); excelApplication = null; –

回答

1

我会建议在(Excel)Process上做一些包装,当你完成它时你可以调用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相关的应用程序。

您可以创建一个持有者对象/字段,然后就可以serialzed:

List<ExcelProcess> m_ExcelProcesses; 

任何过程添加到它。

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 
    } 
} 
+0

哦,非常感谢你m.rogalski,这正是我要搜索的内容对于!很好的解释 –

2

尝试使用()。

using(var newExcelObject = ...){ 
       // your code here 
    } 
    // closes the object you intialised above 

一旦超出范围,它将自动关闭该过程。这将是关闭Excel过程的最简单和最好的做法。

否则,您可以手动关闭/处理对象而不是杀死进程。

希望这会有所帮助。

+0

我使用这个: excelWorkBook2.Close(true); targetSheet2 = null; System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkBook2 ); excelWorkBook2 = NULL; excelApplication.Quit(); excelApplication = NULL; 但它不关闭所有文件,我打开我的代码中14个应用程序,在最后我有2个应用程序未关闭,这就是为什么我直接试图杀死这些进程 –

+1

@LaalaDjelouah如果它没有关闭,这意味着你泄漏了你应该清理的东西的引用。如果你清理正确,它会关闭,但很难得到它通常使用第三方库更容易。 – Ian

+1

我第二@Ian建议。您是否尝试过使用LinqToExcel代替。它更不杂乱。继承人链接https://www.codeproject.com/Articles/659643/Csharp-Query-Excel-and-CSV-Files-Using-LinqToExcel –