예제 #1
0
        /// <summary>
        ///     Called when the form is loading.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormMain_Load(object sender, EventArgs e)
        {
            string[] arguments = Environment.GetCommandLineArgs();

            if (arguments.Length >= 2)
            {
                string arg = arguments[1].ToUpper();

                if (arg == "/?" || arg == "?")
                {
                    var usage = @"MutexSingleInstanceAndNamedPipe [/Close] | [Test option1] [Test option nn]";
                    MessageBox.Show(usage, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Close();
                    return;
                }

                if (arg == "/CLOSE" || arg == "CLOSE")
                {
                    // If we are not the first instance, send a quit message along the pipe
                    if (!IsApplicationFirstInstance())
                    {
                        var namedPipeXmlPayload = new NamedPipeXmlPayload
                        {
                            SignalQuit = true
                        };

                        // Send the message
                        NamedPipeClientSendOptions(namedPipeXmlPayload);
                    }

                    // Stop loading form and quit
                    Close();
                    return;
                }
            }

            // If are the first instance then we start the named pipe server listening and allow the form to load
            if (IsApplicationFirstInstance())
            {
                // Create a new pipe - it will return immediately and async wait for connections
                NamedPipeServerCreateServer();
            }
            else
            {
                // We are not the first instance, send the named pipe message with our payload and stop loading
                var namedPipeXmlPayload = new NamedPipeXmlPayload
                {
                    SignalQuit           = false,
                    CommandLineArguments = Environment.GetCommandLineArgs().ToList()
                };

                // Send the message
                NamedPipeClientSendOptions(namedPipeXmlPayload);

                // Stop loading form and quit
                Close();
            }
        }
예제 #2
0
        /// <summary>
        ///     The function called when a client connects to the named pipe. Note: This method is called on a non-UI thread.
        /// </summary>
        /// <param name="iAsyncResult"></param>
        private void NamedPipeServerConnectionCallback(IAsyncResult iAsyncResult)
        {
            try
            {
                // End waiting for the connection
                _namedPipeServerStream.EndWaitForConnection(iAsyncResult);

                // Read data and prevent access to _namedPipeXmlPayload during threaded operations
                lock (_namedPiperServerThreadLock)
                {
                    // Read data from client
                    var xmlSerializer = new XmlSerializer(typeof(NamedPipeXmlPayload));
                    _namedPipeXmlPayload = (NamedPipeXmlPayload)xmlSerializer.Deserialize(_namedPipeServerStream);

                    // Need to signal quit?
                    if (_namedPipeXmlPayload.SignalQuit)
                    {
                        NamedPipeThreadEvent_Close();
                        return;
                    }

                    // _namedPipeXmlPayload contains the data sent from the other instance
                    // As an example output it to the textbox
                    // In more complicated cases would need to do some processing here and possibly pass to UI thread
                    TextBoxAppend(_namedPipeXmlPayload);
                }
            }
            catch (ObjectDisposedException)
            {
                // EndWaitForConnection will exception when someone calls closes the pipe before connection made
                // In that case we dont create any more pipes and just return
                // This will happen when app is closing and our pipe is closed/disposed
                return;
            }
            catch (Exception)
            {
                // ignored
            }
            finally
            {
                // Close the original pipe (we will create a new one each time)
                _namedPipeServerStream.Dispose();
            }

            // Create a new pipe for next connection
            NamedPipeServerCreateServer();
        }
예제 #3
0
        /// <summary>
        ///     Appends string version of the payload to the end of the text box. Handles being called from a non UI thread.
        /// </summary>
        private void TextBoxAppend(NamedPipeXmlPayload namedPipeXmlPayload)
        {
            if (textBoxOutput.InvokeRequired)
            {
                textBoxOutput.Invoke((MethodInvoker) delegate { TextBoxAppend(namedPipeXmlPayload); });
                return;
            }

            string message = "SignalQuit: " + namedPipeXmlPayload.SignalQuit;

            foreach (string commandLine in namedPipeXmlPayload.CommandLineArguments)
            {
                message += "\r\nCommandLine: " + commandLine;
            }

            textBoxOutput.Text += message + "\r\n\r\n";
        }
예제 #4
0
        /// <summary>
        ///     Uses a named pipe to send the currently parsed options to an already running instance.
        /// </summary>
        /// <param name="namedPipePayload"></param>
        private void NamedPipeClientSendOptions(NamedPipeXmlPayload namedPipePayload)
        {
            try
            {
                using (var namedPipeClientStream = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
                {
                    namedPipeClientStream.Connect(3000); // Maximum wait 3 seconds

                    var xmlSerializer = new XmlSerializer(typeof(NamedPipeXmlPayload));
                    xmlSerializer.Serialize(namedPipeClientStream, namedPipePayload);
                }
            }
            catch (Exception)
            {
                // Error connecting or sending
            }
        }