C#在应用程序退出后为背景应用程序执行代码

时间:2017-08-30 12:38:08

标签: c#

这不是此post的副本。我从这篇文章中得到了我的解决方案,但它不起作用,更不用说我的应用程序是一个winforms应用程序,而不是一个控制台应用程序。

所以我有一个在后台运行的项目。基本上,我创建了一个Windows窗体应用程序,但我没有在Program.cs中调用Form。我创建了一个监听应用程序退出时间的类:

class ShutDownManager
    {
        public ShutDownManager()
        {
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);
        }
        static bool exitSystem = false;


        [DllImport("Kernel32")]
        private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

        private delegate bool EventHandler(CtrlType sig);
        static EventHandler _handler;

        enum CtrlType
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT = 1,
            CTRL_CLOSE_EVENT = 2,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT = 6
        }

        private static bool Handler(CtrlType sig)
        {
            Console.Writeline("I'M OUT OF HERE");


            return true;
        }

    }

我在Program.cs的Main函数中创建了这个类的实例。 然而,这似乎并没有激发。它在控制台应用程序中的功能就像一个魅力,但当涉及到我的表单应用程序(没有表单)时,它不起作用。 可能是什么问题?

我在Main的代码:

static void Main()
{
     ShutDownManager sdm = new ShutDownManager();
     StartUpManager.AddApplicationToCurrentUserStartup();
     Timers timers = new Timers();
}

1 个答案:

答案 0 :(得分:0)

让我打破你的情况:摘自docs.microsoft.com SetConsoleCtrlHandler

  

每个控制台进程都有自己的应用程序定义的HandlerRoutine函数列表,用于处理CTRL + C和CTRL + BREAK信号。处理程序函数还处理用户关闭控制台,注销或关闭系统时系统生成的信号。控制台进程通过调用SetConsoleCtrlHandler函数来添加或删除其他处理函数,该函数不会影响其他进程的处理函数列表。

正如您所注意到的,这似乎仅指控制台进程。当其他应用程序退出时,它无法告诉您,但仅限于此应用程序。此外,它还可以通知您LOGOFFSHUTDOWN。此外,由于没有控制台(因为您需要后台进程),因此不涉及CTRL-C或CTRL-BREAK处理。
结论:最好的情况是,您只能收到有关LOGOFFSHUTDOWN

的通知

winforms app同一页面的相关信息:

  

此功能为控制台应用程序和服务提供了类似的通知, WM_QUERYENDSESSION为图形应用程序提供了消息泵。

您的代码有什么问题?

嗯,它旨在在系统运行应用程序时LOGOFFSHUTDOWN 时提供回调。不用说,您的申请已经退出接收此类活动。因此,您必须在注册回调后等待。

最好的方法是什么?

您应该为此编写服务。如果我没有弄错的话,服务已收到LOGOFFSHUTDOWN的通知 How to write a simple C# service有一个很好的例子。

编辑:

为了更全面地理解,您可能需要查看MSDN docs about ServiceBase class。此外,您应该查看OnSessionChange事件,该事件会通知all session events。它在SessionChangeDescription class doc有一些有用的代码摘录。同样适用于OnShutdown event

现在,如果您无法执行Windows服务,则必须从winform应用程序创建Form并使表单不可见。然后,您应该处理WM_QUERYENDSESSION event或使用SystemEvents.SessionEnding Event来处理这种情况

该示例代码

var frm = new Form();
frm.Activated += (s, e) => { frm.Visible = false; };
SystemEvents.SessionEnded += (s, e) => { /* your code to handle logoff and shutdown */ };
Application.Run(frm);
相关问题