代码之家  ›  专栏  ›  技术社区  ›  Ranhiru Jude Cooray

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

  •  2
  • Ranhiru Jude Cooray  · 技术社区  · 14 年前

    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 回复  |  直到 14 年前
        1
  •  3
  •   P.Brian.Mackey    14 年前

    因为您已经有了一个方法来调用命令提示符一次,所以用一些简单的循环来更新您的逻辑,这样您就可以传递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  
            }  
        }
    }
    

    managed service library .

        2
  •  2
  •   ctacke    14 年前

    编辑

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

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

    结束编辑

    1. 你需要一个 命名 P/Invoke CreateMutex 或者使用已有的库(比如SDF)。你的应用程序需要在启动时创建互斥,并检查它是否已经存在。如果没有,你是第一个运行的实例,正常运行。如果互斥存在,则需要通过 P2P queue

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