it-swarm.dev

إغلاق عملية تطبيق Excel في C # بعد الوصول إلى البيانات

أكتب تطبيقًا في C # يفتح ملف قالب Excel لعمليات القراءة/الكتابة. أريد أن عندما يغلق المستخدم التطبيق ، تم إغلاق عملية تطبيق Excel ، دون حفظ ملف Excel. شاهد مدير المهام الخاص بي بعد عدة عمليات للتطبيق.

enter image description here

أستخدم هذا الكود لفتح ملف 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;

أرى أسئلة مشابهة في التدفق المكدس مثل هذا السؤال و هذا ، واختبار الإجابات ، لكنها لا تعمل.

69
Javad Yousefi

جرب هذا:

excelBook.Close(0); 
excelApp.Quit();

عند إغلاق كتاب العمل ، لديك ثلاثة معلمات اختيارية:

Workbook.close SaveChanges, filename, routeworkbook 

Workbook.Close(false) أو إذا كنت تقوم بربط متأخر ، فمن السهل في بعض الأحيان استخدام صفر Workbook.Close(0) هذه هي الطريقة التي قمت بها عند أتمتة إغلاق المصنفات.

كما ذهبت ونظرت إلى الوثائق الخاصة بها ، ووجدتها هنا: Excel Workbook Close

شكر،

77
Michael
xlBook.Save();
xlBook.Close(true);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

جرب هذا .. إنه يعمل من أجلي ... يجب عليك تحرير كائن تطبيق xl لإيقاف العملية.

20
Sameera R.

فكر في هذا ، إنه يقتل العملية:

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
10
Morris Miao

المرجع: https://stackoverflow.com/a/17367570/132599

تجنب استخدام تعبيرات النداء المزدوج ، مثل هذا:

var workbook = Excel.Workbooks.Open(/*params*/)

... لأنك بهذه الطريقة تقوم بإنشاء كائنات RCW ليس فقط للمصنف ، ولكن أيضًا للمصنفات ، ويجب عليك تحريرها أيضًا (وهذا غير ممكن إذا لم يتم الاحتفاظ بمرجع إلى الكائن).

هذا حل المشكلة بالنسبة لي. يصبح الرمز الخاص بك:

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);

أقوم بلف هذا في 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);
}
10
David Clarke

قتل Excel ليس بالأمر السهل ؛ انظر هذه المادة: 50 طرق لقتل اكسل

تأخذ هذه المقالة أفضل نصيحة من Microsoft ( MS Knowlege Base Article ) حول كيفية جعل 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
4
D_Bester

يمكنك قتل العملية باستخدام كائن COM الخاص بك pid Excel

إضافة مكان أدناه رمز الاستيراد دلل

[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();
                }
            }
1
Alican Kuklaci

لقد واجهت نفس المشكلات وحاولت العديد من الطرق لحلها ولكن لا يعمل. وأخيرا ، لقد وجدت طريقي. بعض المرجع أدخل وصف الرابط هنا

آمل أن يساعد الكود في المستقبل. لقد أمضيت أكثر من يومين لحلها. أدناه هو رمز بلدي:

//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();
                    }        
                }
            }
1
Kenneth Wong

excelBook.Close ()؛ excelApp.Quit ()؛ إضافة نهاية الرمز ، يمكن أن يكون كافيا. إنها تعمل على الكود الخاص بي

1
user2605046

تعمل معظم الطرق ، ولكن تظل عملية Excel دائمًا حتى يتم إغلاق التطبيق.

عندما تقتل عملية Excel مرة واحدة ، لا يمكن تنفيذها مرة أخرى في نفس الموضوع - لا أعرف لماذا.

0
Atanas Atanasov
         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"

0
xrhstos

بناء على حلول أخرى. لقد استخدم هذا:

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: هذا هو بلدي تطبيق Interop Excel كائن

0
merryrppin

الطريقة الصحيحة لإغلاق كل عملية 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 { }
    }
}
0
Md. Alim Ul Karim

استخدم متغيرًا لكل كائن 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);
        }
}
0
user10170010

يمكننا إغلاق تطبيق Excel أثناء تحويل xls إلى xlsx باستخدام الكود التالي. عندما نقوم بتنفيذ هذا النوع من المهام ، يتم تشغيل تطبيق Excel في مدير المهام ، يجب أن نغلق هذا Excel الذي يعمل في الخلفية. Interop هو أحد مكونات Com ، لتحرير مكون 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);
   }
0
Sumant Singh