Я пишу приложение на C #, которое открывает файл шаблона Excel для операций чтения / записи. Я хочу, чтобы, когда пользователь закрывает приложение, процесс приложения Excel был закрыт без сохранения файла Excel. См. Мой диспетчер задач после нескольких запусков приложения.
Я использую этот код, чтобы открыть файл Excel:
public Excel.Application excelApp = new Excel.Application();
public Excel.Workbook excelBook;
excelBook = excelApp.Workbooks.Add(@"C:/pape.xltx");
а для доступа к данным я использую этот код:
Excel.Worksheet excelSheet = (Worksheet)(excelBook.Worksheets[1]);
excelSheet.DisplayRightToLeft = true;
Range rng;
rng = excelSheet.get_Range("C2");
rng.Value2 = txtName.Text;
Я вижу похожие вопросы в stackoverflow, такие как этот вопрос и этот , и тестовые ответы, но это не работает.
c#
excel
visual-studio-2012
excel-interop
kill-process
Джавад Юсефи
источник
источник
Ответы:
Попробуй это:
excelBook.Close(0); excelApp.Quit();
При закрытии рабочей книги у вас есть три необязательных параметра:
Workbook.Close(false)
или если вы выполняете позднее связывание, иногда проще использовать ноль.Workbook.Close(0)
Вот как я это сделал при автоматическом закрытии книг.Также я просмотрел документацию по нему и нашел ее здесь: Excel Workbook Close
Благодарность,
источник
xlBook.Save(); xlBook.Close(true); xlApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
попробуйте это ... это сработало для меня ... вы должны выпустить этот объект приложения xl, чтобы остановить процесс.
источник
Ссылка: https://stackoverflow.com/a/17367570/132599
Это решило проблему для меня. Ваш код становится:
public Excel.Application excelApp = new Excel.Application(); public Excel.Workbooks workbooks; public Excel.Workbook excelBook; workbooks = excelApp.Workbooks; excelBook = workbooks.Add(@"C:/pape.xltx"); ... Excel.Sheets sheets = excelBook.Worksheets; Excel.Worksheet excelSheet = (Worksheet)(sheets[1]); excelSheet.DisplayRightToLeft = true; Range rng; rng = excelSheet.get_Range("C2"); rng.Value2 = txtName.Text;
А затем отпустите все эти объекты:
System.Runtime.InteropServices.Marshal.ReleaseComObject(rng); System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets); excelBook .Save(); excelBook .Close(true); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook); System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); excelApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
Я заключаю это в a,
try {} finally {}
чтобы все было выпущено, даже если что-то пойдет не так (что может пойти не так?), Напримерpublic Excel.Application excelApp = null; public Excel.Workbooks workbooks = null; ... try { excelApp = new Excel.Application(); workbooks = excelApp.Workbooks; ... } finally { ... if (workbooks != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); excelApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); }
источник
Подумайте об этом, это убивает процесс:
System.Diagnostics.Process[] process=System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (!string.IsNullOrEmpty(p.ProcessName)) { try { p.Kill(); } catch { } } }
Тоже пробовали просто нормально закрыть?
myWorkbook.SaveAs(@"C:/pape.xltx", missing, missing, missing, missing, missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing); excelBook.Close(null, null, null); // close your workbook excelApp.Quit(); // exit excel application excel = null; // set to NULL
источник
Убить Excel не всегда легко; см. эту статью: 50 способов убить Excel
В этой статье используется лучший совет от Microsoft ( Базовая статья знаний MS ) о том, как заставить Excel нормально завершать работу, но при этом также обеспечивается это, убивая процесс, если это необходимо. Мне нравится второй парашют.
Обязательно закройте все открытые книги, закройте приложение и отпустите объект xlApp. Наконец, проверьте, жив ли процесс, и если да, то убейте его.
Эта статья также гарантирует, что мы не уничтожаем все процессы Excel, а убиваем только тот процесс, который был запущен.
См. Также Получить процесс из дескриптора окна
Вот код, который я использую: (работает каждый раз)
Sub UsingExcel() 'declare process; will be used later to attach the Excel process Dim XLProc As Process 'call the sub that will do some work with Excel 'calling Excel in a separate routine will ensure that it is 'out of scope when calling GC.Collect 'this works better especially in debug mode DoOfficeWork(XLProc) 'Do garbage collection to release the COM pointers 'http://support.microsoft.com/kb/317109 GC.Collect() GC.WaitForPendingFinalizers() 'I prefer to have two parachutes when dealing with the Excel process 'this is the last answer if garbage collection were to fail If Not XLProc Is Nothing AndAlso Not XLProc.HasExited Then XLProc.Kill() End If End Sub 'http://msdn.microsoft.com/en-us/library/ms633522%28v=vs.85%29.aspx <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _ Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _ ByRef lpdwProcessId As Integer) As Integer End Function Private Sub ExcelWork(ByRef XLProc As Process) 'start the application using late binding Dim xlApp As Object = CreateObject("Excel.Application") 'or use early binding 'Dim xlApp As Microsoft.Office.Interop.Excel 'get the window handle Dim xlHWND As Integer = xlApp.hwnd 'this will have the process ID after call to GetWindowThreadProcessId Dim ProcIdXL As Integer = 0 'get the process ID GetWindowThreadProcessId(xlHWND, ProcIdXL) 'get the process XLProc = Process.GetProcessById(ProcIdXL) 'do some work with Excel here using xlApp 'be sure to save and close all workbooks when done 'release all objects used (except xlApp) using NAR(x) 'Quit Excel xlApp.quit() 'Release NAR(xlApp) End Sub Private Sub NAR(ByVal o As Object) 'http://support.microsoft.com/kb/317109 Try While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) End While Catch Finally o = Nothing End Try End Sub
источник
Я встречал те же проблемы и пробовал много способов их решить, но не работает. Наконец-то я нашел свой путь. Некоторая ссылка введите описание ссылки здесь
Надеюсь, мой код поможет кому-то в будущем. На ее решение у меня ушло больше двух дней. Ниже мой код:
//get current in useing excel Process[] excelProcsOld = Process.GetProcessesByName("EXCEL"); Excel.Application myExcelApp = null; Excel.Workbooks excelWorkbookTemplate = null; Excel.Workbook excelWorkbook = null; try{ //DO sth using myExcelApp , excelWorkbookTemplate, excelWorkbook } catch (Exception ex ){ } finally { //Compare the EXCEL ID and Kill it Process[] excelProcsNew = Process.GetProcessesByName("EXCEL"); foreach (Process procNew in excelProcsNew) { int exist = 0; foreach (Process procOld in excelProcsOld) { if (procNew.Id == procOld.Id) { exist++; } } if (exist == 0) { procNew.Kill(); } } }
источник
excelBook.Close (); excelApp.Quit (); добавить конец кода, этого может хватить. он работает над моим кодом
источник
Вы можете убить процесс своим собственным
COM
объектом excel pidдобавить где-нибудь под кодом импорта dll
[DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);
и использовать
if (excelApp != null) { int excelProcessId = -1; GetWindowThreadProcessId(new IntPtr(excelApp.Hwnd), ref excelProcessId); Process ExcelProc = Process.GetProcessById(excelProcessId); if (ExcelProc != null) { ExcelProc.Kill(); } }
источник
Я обнаружил , что это очень важно иметь
Marshal.ReleaseComObject
вWhile
петлю и закончить Garbage Collection .static void Main(string[] args) { Excel.Application xApp = new Excel.Application(); Excel.Workbooks xWbs = xApp.Workbooks; Excel.Workbook xWb = xWbs.Open("file.xlsx"); Console.WriteLine(xWb.Sheets.Count); xWb.Close(); xApp.Quit(); while (Marshal.ReleaseComObject(xWb) != 0); while (Marshal.ReleaseComObject(xWbs) != 0); while (Marshal.ReleaseComObject(xApp) != 0); GC.Collect(); GC.WaitForPendingFinalizers(); }
источник
wb.Close(); app.Quit(); System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (!string.IsNullOrEmpty(p.ProcessName) && p.StartTime.AddSeconds(+10) > DateTime.Now) { try { p.Kill(); } catch { } } }
Он закрывает последние 10 секунд процесса с именем "Excel"
источник
Правильный способ закрыть все процессы Excel
var _excel = new Application(); foreach (Workbook _workbook in _excel.Workbooks) { _workbook.Close(0); } _excel.Quit(); _excel = null; var process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (var p in process) { if (!string.IsNullOrEmpty(p.ProcessName)) { try { p.Kill(); } catch { } } }
источник
На основе других решений. Я использую это:
IntPtr xAsIntPtr = new IntPtr(excelObj.Application.Hwnd); excelObj.ActiveWorkbook.Close(); System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (p.MainWindowHandle == xAsIntPtr) { try { p.Kill(); } catch { } } }
С помощью «MainWindowHandle» идентифицировать процесс и закрыть его.
excelObj: это мой объект excel Application Interop
источник
Используйте переменную для каждого объекта Excel и должны зацикливаться
Marshal.ReleaseComObject >0
. Без цикла процесс Excel остается активным.public class test{ private dynamic ExcelObject; protected dynamic ExcelBook; protected dynamic ExcelBooks; protected dynamic ExcelSheet; public void LoadExcel(string FileName) { Type t = Type.GetTypeFromProgID("Excel.Application"); if (t == null) throw new Exception("Excel non installato"); ExcelObject = System.Activator.CreateInstance(t); ExcelObject.Visible = false; ExcelObject.DisplayAlerts = false; ExcelObject.AskToUpdateLinks = false; ExcelBooks = ExcelObject.Workbooks; ExcelBook = ExcelBooks.Open(FileName,0,true); System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application"); ExcelSheet = ExcelBook.Sheets[1]; } private void ReleaseObj(object obj) { try { int i = 0; while( System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0) { i++; if (i > 1000) break; } obj = null; } catch { obj = null; } finally { GC.Collect(); } } public void ChiudiExcel() { System.Threading.Thread.CurrentThread.CurrentCulture = ci; ReleaseObj(ExcelSheet); try { ExcelBook.Close(); } catch { } try { ExcelBooks.Close(); } catch { } ReleaseObj(ExcelBooks); try { ExcelObject.Quit(); } catch { } ReleaseObj(ExcelObject); } }
источник
Мы можем закрыть приложение Excel при преобразовании xls в xlsx, используя следующий код. Когда мы выполняем такую задачу, тогда приложение Excel запускается в диспетчере задач, мы должны закрыть этот Excel, который работает в фоновом режиме. Interop - это компонент Com, для выпуска которого мы использовали Marshal.FinalReleaseComObject.
private void button1_Click(object sender, EventArgs e) { Excel03to07("D:\\TestExls\\TestExcelApp.XLS"); } private void Excel03to07(string fileName) { string svfileName = Path.ChangeExtension(fileName, ".xlsx"); object oMissing = Type.Missing; var app = new Microsoft.Office.Interop.Excel.Application(); var wb = app.Workbooks.Open(fileName, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); wb.SaveAs(svfileName, XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); wb.Close(false, Type.Missing, Type.Missing); app.Quit(); GC.Collect(); Marshal.FinalReleaseComObject(wb); Marshal.FinalReleaseComObject(app); }
источник
Большинство методов работают, но процесс Excel всегда остается до закрытия приложения.
При уничтожении процесса excel один раз он не может быть выполнен еще раз в том же потоке - не знаю почему.
источник
GetWindowThreadProcessId((IntPtr)app.Hwnd, out iProcessId); wb.Close(true,Missing.Value,Missing.Value); app.Quit(); System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (p.Id == iProcessId) { try { p.Kill(); } catch { } } } } [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); uint iProcessId = 0;
этот GetWindowThreadProcessId находит правильный идентификатор процесса или отлично .... После его уничтожения .... Наслаждайтесь !!!
источник
private void releaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; MessageBox.Show("Unable to release the Object " + ex.ToString()); } finally { GC.Collect(); } }
источник