我希望我的两个应用程序能够相互发送字符串,并根据字符串"做某事"执行不同的操作。
这是一个预概念模型,所以不需要安全措施,效率也可以尽可能低。
那么我该如何在尽可能少地付出努力的情况下实现这一目标呢?
(你可以尽自己所能解决这个问题)
这是一个预概念模型,所以不需要安全措施,效率也可以尽可能低。
那么我该如何在尽可能少地付出努力的情况下实现这一目标呢?
(你可以尽自己所能解决这个问题)
有几种机制可以实现这一点——可能最容易使用的是命名管道。我没有使用过,但我了解Windows通信基础(WCF)也很容易使用。
CodeProject上有许多关于WCF的文章 : http://www.codeproject.com/KB/WCF/?cat=3
使用WCF的好处是可以轻松地将您的进程移动到不同的系统中(如果对您的场景有意义的话)。
它们真的需要成为不同的应用程序吗?
你能否从第三个项目中启动两个不同线程的独立项目?
static void Main()
{
new Thread(Project1.Program.Main).Start();
new Thread(Project2.Program.Main).Start();
}
ProducerConsumer<string>
例如。如果您可以使用.NET 4.0 beta,则可以使用BlockingCollection<string>
。)AppDomain
的隔离,您也可能会看到从“应用程序”访问的静态变量的一些有趣影响,但这实际上是您要实现的目标。如果项目层次结构不太清晰,这里有一个图形表示
Launcher
/ \
/ \
App 1 App 2
\ /
\ /
\ /
Shared stuff
最好、最有趣的方法是使用我所做的命名管道,我完全满意。
class Client
{
static void Main(string[] args)
{
using (var pipe = new NamedPipeClientStream("localhost", "FtechPipe", PipeDirection.InOut))
{
if (ServerCheck())
pipe.Connect(5000);
pipe.ReadMode = PipeTransmissionMode.Message;
do
{
try
{
Console.Write("Type Something> ");
var input = Console.ReadLine();
if (String.IsNullOrEmpty(input)) continue;
byte[] bytes = Encoding.Default.GetBytes(input);
pipe.Write(bytes, 0, bytes.Length);
var result = ReadMessage(pipe);
string me = Encoding.UTF8.GetString(result);
Console.WriteLine(me);
Console.WriteLine();
}
catch (IOException pipedEx)
{
try
{
//inja bayad motmaeen beshi agent up hastesh
//age ip nabood upesh kon
//dobanre connect sho
pipe.Connect(5000);
}
catch (TimeoutException pipeTimeoutEx)
{
}
}
} while (true);
}
}
private static bool ServerCheck()
{
var allProcesses = Process.GetProcesses();
if (string.IsNullOrEmpty(allProcesses.Where(a => a.ProcessName == "Client.exe").FirstOrDefault()?.ToString()))
{
System.Diagnostics.Process.Start(@"C:\Client.exe");
return true;
}
else
return false;
}
private static byte[] ReadMessage(PipeStream pipe)
{
byte[] buffer = new byte[1024];
using (var ms = new MemoryStream())
{
do
{
var readBytes = pipe.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, readBytes);
}
while (!pipe.IsMessageComplete);
return ms.ToArray();
}
}
}
class Server
{
static void Main(string[] args)
{
using (var pipe = new NamedPipeServerStream(
"FtechPipe",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message))
{
Console.WriteLine("[*] Waiting for client connection...");
pipe.WaitForConnection();
Console.WriteLine("[*] Client connected.");
while (true)
{
var messageBytes = ReadMessage(pipe);
var line = Encoding.UTF8.GetString(messageBytes);
Console.WriteLine("[*] Received: {0}", line);
try
{
var response = Encoding.UTF8.GetBytes("Hello ");
pipe.Write(response, 0, response.Length);
}
catch (Exception ex)
{
//Console.WriteLine(ex);
pipe.Disconnect();
Console.WriteLine("Disaconnected");
Console.WriteLine("[*] Waiting for client connection...");
//vaghti ke pipe Broke mishe yani ertebat ghat shode va bayad agent motmaeen beshe terminal up hast ya kheir
pipe.WaitForConnection();
Console.WriteLine("[*] Client connected.");
}
}
}
}
private static byte[] ReadMessage(PipeStream pipe)
{
byte[] buffer = new byte[1024];
using (var ms = new MemoryStream())
{
do
{
var readBytes = pipe.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, readBytes);
}
while (!pipe.IsMessageComplete);
return ms.ToArray();
}
}
}
WCF是一种很好的方式,即使你开始深入研究它,它也可能变得复杂。
你可以定义一个简单的合同来接受字符串,然后在每个应用程序中实现该合同,在字符串到达时执行所需操作。在应用程序内部,您可以自托管服务,这意味着应用程序本身托管服务 - 因此您不需要IIS。将它们托管在已知端口上,在每个解决方案中添加Web服务引用,然后就可以开始了。
一种方法是使用.NET Remoting IpcChannel 类在同一台机器上的不同进程之间进行通信。
我能想到最简单的方法是创建一个其他进程会检查的文件。
一种更“高级”和“明智”的方法是使用套接字和本地主机。
如果我真的想要实现它,我会尝试学习有关正确的IPC的知识。
有很多非常简单的方法让应用程序以非常简单的方式进行通信。我认为其中一些最容易的方式如下:
我会选择使用套接字。