Моя функция MyMainFunction() выполняется.
Если неожиданное принудительное завершение (сбой) происходит сразу после выполнения excelApp = new Microsoft.Office.Interop.Excel.Application();, есть ли способ завершить этот процесс excelApp?
Я использовал подход, при котором я буду получать PID каждый раз, когда создаю экземпляр Excel.
Я буду сохранять этот PID, чтобы позже завершить все оставшиеся процессы.
Однако проблема этого метода заключается в том, что если принудительное завершение (сбой) происходит до того, как я смогу зарегистрировать PID, у меня нет возможности завершить потерянный процесс Excel, который остается запущенным.
Код: Выделить всё
public class TestClass
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
System.Collections.Concurrent.ConcurrentDictionary pidDictionary = new System.Collections.Concurrent.ConcurrentDictionary();
public TestClass()
{
}
~TestClass()
{
KillRemainingProcesses();
}
private void RegistPID(uint pid)
{
pidDictionary.TryAdd(pid, 0);
}
private void KillExcelAndRemove(uint processId)
{
try
{
var process = Process.GetProcessById((int)processId);
if (process != null && !process.HasExited && process.ProcessName.Equals("EXCEL", StringComparison.OrdinalIgnoreCase))
{
process.Kill();
pidDictionary.TryRemove(processId, out byte notUse);
}
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message}, Kill Error");
}
}
private void KillRemainingProcesses()
{
foreach (var processId in pidDictionary.Keys)
{
try
{
Process process = Process.GetProcessById((int)processId);
if (process != null && !process.HasExited && process.ProcessName.Equals("EXCEL", StringComparison.OrdinalIgnoreCase))
{
process.Kill();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
public void MyMainFunction()
{
Microsoft.Office.Interop.Excel.Application excelApp = null;
Microsoft.Office.Interop.Excel.Workbook workbook = null;
Microsoft.Office.Interop.Excel.Worksheet worksheet = null;
uint processId = 0;
try
{
excelApp = new Microsoft.Office.Interop.Excel.Application();
GetWindowThreadProcessId(new IntPtr(excelApp.Hwnd), out processId);
RegistPID(processId);
// Do Excel Edit
workbook.Save();
}
catch (Exception ex)
{
}
finally
{
if (worksheet != null)
{
Marshal.ReleaseComObject(worksheet);
worksheet = null;
}
if (workbook != null)
{
workbook.Close(false);
Marshal.ReleaseComObject(workbook);
workbook = null;
}
if (excelApp != null)
{
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
excelApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
KillExcelAndRemove(processId);
}
}
}
Убить дочерний процесс, когда родительский процесс уничтожен
https://learn.microsoft.com/en-us/windo ... jobobjectw
Подробнее здесь: https://stackoverflow.com/questions/798 ... el-process