简体   繁体   English

在隐藏的C#控制台应用程序中获取关闭窗口消息

[英]Get close window message in Hidden C# Console Application

I have a Windows Form that starts some console application in background(CreateNoWindow = rue,WindowStyle = ProcessWindowStyle.Hidden). 我有一个Windows窗体,它在后台启动一些控制台应用程序(CreateNoWindow = rue,WindowStyle = ProcessWindowStyle.Hidden)。

Windows form gives me opportunity to stop the console application at any time. Windows窗体使我有机会随时停止控制台应用程序。 But I'd like to handle somehow the close message inside the console application. 但是我想以某种方式处理控制台应用程序中的关闭消息。 I tried to use hooking like: 我试图像这样使用钩子:

    [DllImport("Kernel32")]
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine handler, bool add);

    // A delegate type to be used as the handler routine 
    // for SetConsoleCtrlHandler.
    public delegate bool HandlerRoutine(CtrlTypes ctrlType);

    // An enumerated type for the control messages
    // sent to the handler routine.
    public enum CtrlTypes
    {
        CTRL_C_EVENT = 0,
        CTRL_BREAK_EVENT,
        CTRL_CLOSE_EVENT,
        CTRL_LOGOFF_EVENT = 5,
        CTRL_SHUTDOWN_EVENT
    }

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
    {
        StaticLogger.Instance.DebugFormat("Main: ConsoleCtrlCheck: Got event {0}.", ctrlType);
        if (ctrlType == CtrlTypes.CTRL_CLOSE_EVENT)
        {
            // Handle close stuff
        }
        return true;
    }

    static int Main(string[] args)
    {
        // Subscribing
        HandlerRoutine hr = new HandlerRoutine(ConsoleCtrlCheck);
        SetConsoleCtrlHandler(hr, true);
        // Doing stuff
    }

but I get the message inside ConsoleCtrlCheck only if the console window is created. 但是只有在创建控制台窗口的情况下,我才能在ConsoleCtrlCheck中收到消息。 But if window is hidden - I don't get any message. 但是,如果窗口是隐藏的-我不会收到任何消息。

In my windows Form to close console application process I use proc.CloseMainWindow(); 在我的Windows Form中以关闭控制台应用程序进程,我使用proc.CloseMainWindow();。 to send message to the console window. 将消息发送到控制台窗口。

PS AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; PS AppDomain.CurrentDomain.ProcessExit + = CurrentDomain_ProcessExit; - also does not help -也无济于事

Do you now other way to handle this situation? 您现在是否以其他方式处理这种情况? Thanks. 谢谢。

This might work. 这可能有效。 I used it in NUnit testes to clean up environment. 我在NUnit睾丸中使用它来清理环境。 Unfortunately it is not garantieed to be called. 不幸的是,它不被保证被称为。 To make it working you need to create an instance of it and pass callback function that should be called on shutdown. 要使其正常工作,您需要为其创建一个实例并传递应在关机时调用的回调函数。

    /// <summary>
    /// Detects the moment when environment is about to be shutdown.
    /// <remarks>
    ///     For usage just create single instance of it.
    ///     Each time when GC calles Finilize a '~ShutdownDetector' will be called.
    /// </remarks>
    /// </summary>
    public sealed class ShutdownDetector
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:ShutdownDetector"/> class.
        /// </summary>
        /// <param name="notifier">The notifier</param>
        public ShutdownDetector(Notifier notifier)
        {
            if (notifier == null) throw new ArgumentNullException("notifier");
            _notifier = notifier;
        }

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="T:CQG.PDTools.Common.ShutdownDetector"/> is reclaimed by garbage collection.
        /// </summary>
        ~ShutdownDetector()
        {
            if (Environment.HasShutdownStarted)
            {
                onShutdown();
            }
            else
            {
                new ShutdownDetector(_notifier);
            }
        }

        /// <summary>
        /// Called when component needs to signal about shutdown.
        /// </summary>
        private void onShutdown()
        {
            if (_notifier != null)
            {
                _notifier();
            }
        }

        Notifier _notifier;
        public delegate void Notifier();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM