繁体   English   中英

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

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

我有一个Windows窗体,它在后台启动一些控制台应用程序(CreateNoWindow = rue,WindowStyle = ProcessWindowStyle.Hidden)。

Windows窗体使我有机会随时停止控制台应用程序。 但是我想以某种方式处理控制台应用程序中的关闭消息。 我试图像这样使用钩子:

    [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
    }

但是只有在创建控制台窗口的情况下,我才能在ConsoleCtrlCheck中收到消息。 但是,如果窗口是隐藏的-我不会收到任何消息。

在我的Windows Form中以关闭控制台应用程序进程,我使用proc.CloseMainWindow();。 将消息发送到控制台窗口。

PS AppDomain.CurrentDomain.ProcessExit + = CurrentDomain_ProcessExit; -也无济于事

您现在是否以其他方式处理这种情况? 谢谢。

这可能有效。 我在NUnit睾丸中使用它来清理环境。 不幸的是,它不被保证被称为。 要使其正常工作,您需要为其创建一个实例并传递应在关机时调用的回调函数。

    /// <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