如果控制台应用程序已经在运行,如何将参数传递给它?

发布于 2024-09-10 00:24:18 字数 1409 浏览 8 评论 0原文

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

I use a Console Application in Windows Mobile to handle incoming message interception. In the same console application i accept parameters (string args[]) which based on the parameters, register the message interceptor.

InterceptorType is a enum

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



    }

I made this a console application because i want it keep running in the background and intercept incoming messages.

This works fine for the first time. But the problem is that I have to keep calling the addInterception method to add subsequent interception rules. This makes the console application start again and again for each time i add a rule. How do i make this run only once and add more message interceptor rules?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海拔太高太耀眼 2024-09-17 00:24:18

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

Since you already have a method in place to call the command prompt once, update your logic with some simple looping so you can pass N commands.

EDIT: I wrote it a fully compileable example to show you exactly what I am talking about. Note how the child process can be called any number of times without re-launching. This is not just a simple command line launch with arguments being passed because that idea will lead to X processes which is exactly what you do not want.

PARENT PROCESS: (The one with 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();
        }

    }

CHILD PROCESS:

    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  
        }  
    }
}

Note that codeplex has a managed service library.

残花月 2024-09-17 00:24:18

编辑

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

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

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

END EDIT

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

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

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

EDIT

It seems that people are misunterstanding your question (or I am) so here's some clarification on how I'm seeing the problem.

You have an console app that takes in command-line parameters. These parameters are used for something (the what is irrelevant actually). You want to be able to add parameters after the app is already running by calling the app with new command line args.

What is happening is that when you call the app any time after teh first, a new instance of the process starts up instead of the command-line arguments going to the existing, already running application.

END EDIT

The solution is fairly straightforward and requires two pieces.

  1. You need a named mutex. For whatever (poor) reason, the CF doesn't expose a version of a mutex that takes a name, so you have to P/Invoke CreateMutex or use a library (like the SDF) that already has it. Your app needs to create the mutex at startup and check to see if it already exists. if it doesn't you're the first running instance and run as normal. If the mutex exists, you need to pass your command line args to the one that is already running via a P2P queue then simply exits.

  2. After checking the mutex, the first instance spawns a worker thread. This thread listens on a P2P queue for messages. When they come in, you handle them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文