Закрыть окно сообщения в консольном приложении C # - PullRequest
0 голосов
/ 29 апреля 2010

У меня есть форма 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 Ответ

1 голос
/ 02 марта 2011

Это может сработать. Я использовал его в тестах 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();
    }
...