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

时间:2010-04-29 14:18:35

标签: c# console message hidden

我有一个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窗体中关闭我使用的控制台应用程序进程        proc.CloseMainWindow(); 将消息发送到控制台窗口。

P.S。 AppDomain.CurrentDomain.ProcessExit + = CurrentDomain_ProcessExit; - 也没帮助

你现在以其他方式处理这种情况吗? 感谢。

1 个答案:

答案 0 :(得分:1)

这可能有用。我在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();
    }