2017-07-24 94 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 –