Como passar argumentos para um aplicativo de console se ele já estiver sendo executado?
-
16-09-2020 - |
Pergunta
Eu uso um Aplicativo de Console no Windows Mobile para processar a receber a mensagem de interceptação.No mesmo aplicativo de console eu aceitar parâmetros (string args[]) que, com base nos parâmetros, registrar a mensagem de interceptor.
InterceptorType é um 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
}
Eu fiz isso uma aplicação de consola porque eu quero manter em execução no plano de fundo e interceptar mensagens de entrada.
Isso funciona bem para a primeira vez.Mas o problema é que eu tenho que manter a chamar a addInterception método para adicionar posterior interceptação regras.Isso faz com que o aplicativo de console começar de novo e de novo cada vez que eu adicionar uma regra.Como eu faço esse executada apenas uma vez e adicionar mais mensagem interceptor regras?
Solução
Pois você já tem um método para chamar o prompt de comando uma vez, atualizar a sua lógica com algumas simples loop, então você pode passar N comandos.
EDITAR:Eu escrevi uma totalmente compileable exemplo para mostrar a você exatamente o que eu estou falando.Note-se como o processo filho pode ser chamado de qualquer número de vezes sem re-lançamento.Esta não é apenas uma simples linha de comando lançamento com argumentos de que está sendo passado, pois essa idéia de que vai levar a X processos, que é exatamente o que você não quer.
PROCESSO PRINCIPAL:(Com o Sistema.O diagnóstico.Processo)
/// <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();
}
}
FILHO PROCESSO:
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 que codeplex tem um serviço gerenciado de biblioteca.
Outras dicas
EDITAR
Parece que as pessoas estão misunterstanding a sua pergunta (ou eu sou) então, eis aqui alguns esclarecimentos sobre como eu estou vendo o problema.
Você tem um aplicativo de console que leva em parâmetros de linha de comando.Estes parâmetros são usados para algo (o que é irrelevante, na verdade).Você quer ser capaz de adicionar parâmetros após a aplicação já está sendo executado chamando o aplicativo com o novo comando de linha de args.
O que está acontecendo é que quando você chamar o aplicativo a qualquer momento após a primeira, uma nova instância do processo é iniciado em vez de argumentos de linha de comando vai existente, já aplicativo em execução.
FINAIS EDITAR
A solução é bastante simples e requer apenas duas peças.
Você precisa de um chamado mutex.Para qualquer coisa (ruim) razão, a CF não expõe uma versão de um mutex que leva um nome, então você tem que P/Invoke CreateMutex ou use uma biblioteca (como o SDF) que já tem.Seu aplicativo precisa para criar o mutex durante a inicialização e verifique para ver se ele já existe.se não estiver a primeira instância em execução, e executar como normal.Se o mutex existe, você precisa passar sua linha de comando argumentos para o que já está sendo executado através de um P2P fila em seguida, simplesmente sai.
Depois de verificar o mutex, a primeira instância gera um thread de trabalho.Esta thread de escuta em P2P fila de mensagens.Quando eles chegam, você lidar com eles.