2

我在 Windows Mobile 中使用控制台应用程序来处理传入消息拦截。在同一个控制台应用程序中,我接受基于参数的参数(字符串 args []),注册消息拦截器。

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方法来添加后续的拦截规则。这使得控制台应用程序在我每次添加规则时一次又一次地启动。我如何使它只运行一次并添加更多消息拦截器规则?

4

2 回答 2

3

由于您已经有一种方法可以调用命令提示符一次,因此可以通过一些简单的循环来更新您的逻辑,以便您可以传递 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 有一个托管服务库

于 2010-07-15T16:13:18.793 回答
2

编辑

似乎人们误解了你的问题(或者我是)所以这里有一些关于我如何看待问题的澄清。

您有一个接受命令行参数的控制台应用程序。这些参数用于某些事情(实际上无关紧要的事情)。您希望能够在应用程序已经运行后通过使用新的命令行参数调用应用程序来添加参数。

发生的情况是,当您在第一次之后的任何时间调用应用程序时,会启动一个新的进程实例,而不是将命令行参数转到现有的、已经运行的应用程序。

结束编辑

该解决方案相当简单,需要两部分。

  1. 你需要一个命名的互斥锁。无论出于何种(糟糕的)原因,CF 都不会公开使用名称的互斥锁版本,因此您必须P/Invoke CreateMutex或使用已经拥有它的库(如 SDF)。您的应用程序需要在启动时创建互斥锁并检查它是否已经存在。如果不是,您是第一个运行的实例并正常运行。如果互斥体存在,您需要将命令行参数传递给已经通过P2P 队列运行的那个,然后简单地退出。

  2. 检查互斥体后,第一个实例产生一个工作线程。该线程在 P2P 队列上侦听消息。当他们进来时,你处理他们。

于 2010-07-15T16:00:03.190 回答