96 votes

Fermeture du processus d'application d'Excel en C# après l'accès aux données

J'écris une application en C# qui ouvre un fichier modèle Excel pour des opérations de lecture/écriture. Je veux que lorsque l'utilisateur ferme l'application, le processus de l'application Excel ait été fermé, sans sauvegarder le fichier Excel. Voir mon gestionnaire de tâches après plusieurs exécutions de l'application.

enter image description here

J'utilise ce code pour ouvrir le fichier excel :

public Excel.Application excelApp = new Excel.Application();
public Excel.Workbook excelBook;
excelBook = excelApp.Workbooks.Add(@"C:/pape.xltx");

et pour l'accès aux données j'utilise ce code :

Excel.Worksheet excelSheet = (Worksheet)(excelBook.Worksheets[1]);
excelSheet.DisplayRightToLeft = true;
Range rng;
rng = excelSheet.get_Range("C2");
rng.Value2 = txtName.Text;

Je vois des questions similaires dans stackoverflow telles que cette question y este et les réponses aux tests, mais ça ne marche pas.

0voto

quan_bui Points 39
workbook.Close(0);
excelApp.Quit();

Ça a marché pour moi.

0voto

Jamisco Points 334

Une autre solution à ce problème consiste à enregistrer le ProcessID du programme Excel dans lequel vous travaillez. Ensuite, lorsque vous avez terminé avec le programme, vous pouvez tuer spécifiquement ce processus Excel sans cibler d'autres processus Excel.

J'ai trouvé la solution dans este réponse. J'ai pensé la partager ici

Donc, tout d'abord, vous ajoutez ces lignes de code en dehors d'une méthode de classe

// The DllImport requires -- Using System.Runtime.InteropServices;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);

Après ça,

Maintenant, dans une méthode de votre choix, ajoutez ces lignes. Ces lignes suppriment le processus excel spécifique avec lequel vous travaillez.

Modifiez-les selon vos besoins, mais la logique est la même.

        if (ExcelApp != null)
        {
            int excelProcessId = 0;

            //your Excel Application variable has access to its Hwnd property
            GetWindowThreadProcessId(new IntPtr(ExcelApp.Hwnd), ref excelProcessId);

            // you need System.Diagnostics to use Process Class
            Process ExcelProc = Process.GetProcessById(excelProcessId);

            if (ExcelProc != null)
            {
                ExcelProc.Kill();
            }
        }

Au total, votre programme devrait donc ressembler à ceci

class Program
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);

    static void Main(string[] args)
    {
        Application ExcelApp = new Application();

        _Workbook ExcelWrkBook = ExcelApp.Workbooks.Open(filePath);

        _Worksheet ExcelWrkSht = ExcelWrkBook.ActiveSheet;

        ExcelWrkSht.Cells[1, 2] = "70";

        if (ExcelApp != null)
        {
            int excelProcessId = 0; // simple declare, zero is merely a place holder

            GetWindowThreadProcessId(new IntPtr(ExcelApp.Hwnd), ref excelProcessId);

            Process ExcelProc = Process.GetProcessById(excelProcessId);

            if (ExcelProc != null)
            {
                ExcelProc.Kill();
            }
        }

    }
}

J'ai testé cela et cela supprime mes processus Excel comme indiqué dans le Gestionnaire des tâches.

-1voto

xrhstos Points 31
        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;

ce GetWindowThreadProcessId trouve l'Id du processus correct et est excellent .... Après le tue.... Profitez-en ! !!

-1voto

Mehmet Yardım Points 1
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();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X