C #: закрытие окна формы на событие закрытия Excel - PullRequest
0 голосов
/ 18 января 2012

Моя ситуация такова, что я разрабатываю приложение на C #, которое запускает экземпляр приложения Microsoft Office Excel.
Я изменяю некоторые функции формы так, чтобы созданное приложение Excel уничтожалось и очищалось из памяти.когда моя форма закрывается.

То, что я хочу сделать, это выполнить противоположное.Я хотел бы, чтобы мой экземпляр Excel закрывал форму окна при выходе из нее.

Ответы [ 3 ]

2 голосов
/ 18 января 2012

Это то, что я сделал для того же сценария.

Я создал процесс в классе

System.Diagnostics.Process myProcess = new System.Diagnostics.Process();

Затем делегат метода, который закрывает приложение

delegate void KillProcess();
KillProcess aKillProcess;

Установка делегата для метода закрытия приложения

aKillProcess = CloseApp;

Этот код ниже написан внутри события нажатия кнопки. Это открывает Excel.Здесь подпишитесь на событие Exited процесса

myProcess.StartInfo = new System.Diagnostics.ProcessStartInfo (@"D:\SomeExcel.xlsx");
myProcess.Start();
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(ProcessKilled);

При нажатии кнопки закрытия Excel этот метод будет называться

private void ProcessKilled(object sender, EventArgs e)
{
    if (this.InvokeRequired)
        this.Invoke(aKillProcess);
    else
        this.Close();
}

void CloseApp()
{
   this.Close();
}

Это закроет приложение.

Надеюсь, это поможет

1 голос
/ 18 января 2012

Хорошо, я даже не пробовал это, поэтому я не уверен, что это будет работать, но вы можете попробовать что-то вроде этого:

Microsoft.Office.Interop.Excel.Application excel = ...;

System.Diagnostics.Process excelProcess = null;
var processes = System.Diagnostics.Process.GetProcesses();

foreach (var process in processes)
{
        if (process.Handle.ToInt32() == excel.Hwnd)
            excelProcess = process;
}

excelProcess.Exited += new EventHandler(excelProcess_Exited);

ОБНОВЛЕНИЕ

Попробуйте следующий код (это не красиво):

Microsoft.Office.Interop.Excel.Application xlsApp;
Process xlsProcess;
Timer timer;

public Form1()
{
    xlsApp = new Microsoft.Office.Interop.Excel.Application();
    xlsApp.Visible = true;

    foreach (var p in Process.GetProcesses()) //Get the relevant Excel process.
    {
        if (p.MainWindowHandle == new IntPtr(xlsApp.Hwnd))
        {
            xlsProcess = p;
            break;
        }
    }

    if (xlsProcess != null)
    {
        timer = new Timer();
        timer.Interval = 500;
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
    }
}

void timer_Tick(object sender, EventArgs e)
{
    if (xlsApp != null && !xlsApp.Visible)
    {
        //Clean up to make sure the background Excel process is terminated.
        xlsApp.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp);
        xlsApp = null;
    }

    if (xlsProcess.HasExited)
    {
        //The event is not fired but the property is eventually set once the process is terminated
        this.timer.Dispose();
        this.Close();
    }
}

Проблема при работе с приложением Excel заключается в том, что даже если пользователь закрывает свое главное окно, процесс будет продолжаться вфон.Чтобы полностью освободить его, вы должны позвонить Application.Quit, но вы должны делать это только тогда, когда обнаруживаете, что пользователь закрывает окно, что является именно той проблемой, которую вы пытаетесь решить ... у вас есть круговая ссылка здесь: D

Скорее всего, фиксация на соответствующем System.Diagnostics.Process тоже не работает, так как событие Exited никогда не запускается (даже если вы завершаете фоновый процесс из диспетчера задач).Я предполагаю, что это событие запускается только с процессами, запущенными через process = Process.Start(...).

Так что единственное решение, которое я вижу, это опрос, если главное окно Excel видно.Если это не так, это, вероятно, означает, что пользователь закрыл главное окно, и приложение Excel должно быть закрыто (если есть сценарий, когда видимость главного окна Excel может быть ложной, кроме случаев, когда пользователь хочет прекратить процесс, тогда это решение не являетсядействует).Оттуда это довольно просто.

0 голосов
/ 15 октября 2014

Ваша первая попытка сработала бы, просто нужно было вызвать события для процесса, это то, что я сделал, чтобы поймать запущенный выход или сбой visio.

                    foreach (var process in processes)
                    {
                        try
                        {
                            if (process.MainWindowHandle == new IntPtr(app.WindowHandle32))
                                visioProcess = process;
                        }
                        catch
                        {

                        }
                    }

                    visioProcess.EnableRaisingEvents = true;

                    visioProcess.Exited += new EventHandler(visioProcess_Exited);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...