Как передать аргументы консольному приложению, если оно уже запущено? - PullRequest
2 голосов
/ 15 июля 2010

Я использую консольное приложение в Windows Mobile для обработки перехвата входящих сообщений. В том же консольном приложении я принимаю параметры (строковые аргументы []), которые на основе параметров регистрируют перехватчик сообщений.

InterceptorType - это перечисление

static void Main(string[] args)
        {                 

            if (args[0] == "Location")
            {               

                addInterception(InterceptorType.Location, args[1],args[2]);
            } 

        }


private static void addInterception(InterceptorType type, string Location, string Number )
    {

        if (type == InterceptorType.Location)
        {

           using (MessageInterceptor interceptor = new MessageInterceptor(InterceptionAction.NotifyAndDelete, false))
           {

               interceptor.MessageCondition = new MessageCondition(MessageProperty.Sender, MessagePropertyComparisonType.Contains, Number, false);

               string myAppPath = Assembly.GetExecutingAssembly().GetName().CodeBase;

               interceptor.EnableApplicationLauncher("Location", myAppPath);

               interceptor.MessageReceived += new MessageInterceptorEventHandler(interceptor_MessageReceived);


           }


        }


    }


static void interceptor_MessageReceived(object sender, MessageInterceptorEventArgs e)
    {

        //Do something



    }

Я сделал это консольное приложение, потому что я хочу, чтобы оно продолжало работать в фоновом режиме и перехватывало входящие сообщения.

Это отлично работает в первый раз. Но проблема в том, что мне нужно продолжать вызывать метод addInterception для добавления последующих правил перехвата. Это заставляет консольное приложение запускаться снова и снова при каждом добавлении правила. Как сделать так, чтобы это запускалось только один раз, и добавляю больше правил перехвата сообщений?

Ответы [ 2 ]

3 голосов
/ 15 июля 2010

Поскольку у вас уже есть метод для вызова командной строки один раз, обновите свою логику с помощью некоторого простого цикла, чтобы вы могли передавать N команд.

РЕДАКТИРОВАТЬ: я написал полностью компилируемый пример, чтобы показать вамименно то, о чем я говорю.Обратите внимание, как дочерний процесс может быть вызван любое количество раз без повторного запуска.Это не просто запуск командной строки с передачей аргументов, потому что эта идея приведет к X-процессам, а это именно то, что вам не нужно.

ПРОЦЕСС РОДИТЕЛЯ: (тот, что с System.Diagnostics.Process)

/// <summary>
    /// This is the calling application.  The one where u currently have System.Diagnostics.Process
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Process p = new Process();
            p.StartInfo.CreateNoWindow = false;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.FileName = @"C:\AppfolderThing\ConsoleApplication1.exe";
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;


            p.Start();            
            p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine("Output received from application: {0}", e.Data);
            };
            p.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine("Output received from application: {0}", e.Data);
            };
            p.BeginErrorReadLine();
            p.BeginOutputReadLine();
            StreamWriter inputStream = p.StandardInput;
            inputStream.WriteLine(1);
            inputStream.WriteLine(2);
            inputStream.WriteLine(-1);//tell it to exit
            p.WaitForExit();
        }

    }

ПРОЦЕСС РЕБЕНКА:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    enum InterceptorType
    {
        foo,
        bar,
        zee,
        brah
    } 
    /// <summary>
    /// This is the child process called by System.Diagnostics.Process
    /// </summary>
    class Program
    {
        public static void Main()
        {
            while (true)
            {
                int command = int.Parse(Console.ReadLine());
                if (command == -1)
                    Environment.Exit(0);
                else
                    addInterception((InterceptorType)command, "some location", "0");
            }
        }
        private static void addInterception(InterceptorType type, string Location, string Number)
        {
            switch (type)
            {
                case InterceptorType.foo: Console.WriteLine("bind foo"); break;
                case InterceptorType.bar: Console.WriteLine("bind bar"); break;
                default: Console.WriteLine("default bind zee"); break;
            }

        }


        static void interceptor_MessageReceived(object sender, EventArgs e)
        {
            //Do something  
        }  
    }
}

Обратите внимание, что в codeplex есть библиотека управляемых услуг .

2 голосов
/ 15 июля 2010

РЕДАКТИРОВАТЬ

Похоже, что люди неправильно понимают ваш вопрос (или я), поэтому вот несколько пояснений о том, как я вижу проблему.

У вас естьконсольное приложение, которое принимает параметры командной строки.Эти параметры используются для чего-то (что на самом деле не имеет значения).Вы хотите иметь возможность добавлять параметры после того, как приложение уже запущено, вызывая приложение с новыми аргументами командной строки.

То, что происходит, - то, что когда вы вызываете приложение в любое время после первого, новый экземплярпроцесс запускается вместо аргументов командной строки, идущих к существующему, уже запущенному приложению.

END EDIT

Решение довольно простое и требует двух частей.

  1. Вам необходим с именем мьютекс.По какой-либо (плохой) причине CF не предоставляет версию мьютекса, которая принимает имя, поэтому вам нужно P / Invoke CreateMutex или использовать библиотеку (например, SDF), которая уже имеет ее,Ваше приложение должно создать мьютекс при запуске и проверить, существует ли он уже.если это не так, вы первый запущенный экземпляр и работаете как обычно.Если мьютекс существует, вам нужно передать аргументы командной строки тому, который уже запущен через P2P очередь , а затем просто завершиться.

  2. После проверки мьютексапервый экземпляр порождает рабочий поток.Этот поток прослушивает в очереди P2P сообщения.Когда они входят, вы справляетесь с ними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...