赞
踩
最近尝试代码分离,减少主程序中的代码,将很多Form都独立成单独的exe,主程序跟这些小程序间的通信就使用命名管道在进行。
之前运用过命名管道,但是是直接使用win32 api实现的,并且一直有问题,比如说有时候接收信息的阻塞被释放,但是又收不到任何东西。之前使用vs2005进行开发的,后来发现vs2010直接将命名管道封装成了类,就尝试使用了,发现比之前使用api时要顺手的多。
引用using System.IO.Pipes;这个命名空间,在vs2005中是没有此命名空间的,所以我将开发环境全部升级到了vs2010,还好升级比较方便。
我使用的情景都是阻塞式的,就是主程序调出某个exe后,主程序是无法运行的,必要等那个exe中程序执行完,或者关掉exe后,主程序才能响应。当然,如果需要做成非阻塞式的也是可以的,用线程或回调就行了。
vs2010自带的命名管道的类是分成服务器端跟客户端两个,有点类似使用soket的感觉,并且跟win32 api的方式也感觉不一样。win32 api的方式更像两边是对称的。
我封装了一个类,让软件调用的时候尽量的统一,不去区分服务器、客户端什么的。
下面是代码,注释写的应该也比较清楚。
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO;
- using System.IO.Pipes;
- using System.Security.Principal;
- using System.Threading;
- using System.Diagnostics;
-
- namespace pipe
- {
-
- public class NamedPipe : IDisposable {
-
- string err = "";
-
- NamedPipeServerStream _pipeServer = null;
- NamedPipeClientStream _pipeClient = null;
-
- /// <summary>
- /// 初始化管道。每个进程发送与接收信息是两个管道进行通信。
- /// 两个进程使用的管道名是相对的
- /// 进程1使用的接收管道就是进程2使用的发送管道。进程2使用的发送管道就是进程1使用的接收管道。
- /// </summary>
- /// <param name="server">监听管道的名称</param>
- /// <param name="client">发送管道名称</param>
- public NamedPipe(string server, string client)
- {
- try {
- _pipeServer = new NamedPipeServerStream(server, PipeDirection.InOut, 10);
- _pipeClient = new NamedPipeClientStream(".", client, PipeDirection.InOut);
- }
- catch (Exception ex) {
- err = ex.Message;
- }
- }
-
- public bool openExe(string path) {
- Process p = new Process();
-
- try
- {
- p.StartInfo.FileName = path;
- p.StartInfo.UseShellExecute = false;
- p.StartInfo.RedirectStandardInput = true;
-
- p.StartInfo.CreateNoWindow = true;
- p.StartInfo.RedirectStandardOutput = true;
- p.StartInfo.RedirectStandardError = true;
- p.Start();
- return true;
- }
- catch (Exception ex)
- {
- err = ex.Message;
- return false;
- }
- finally {
- p.Close();
- p.Dispose();
- }
- }
-
- /// <summary>
- /// 读取错误信息
- /// </summary>
- /// <returns></returns>
- public string Err() {
- string s;
- s = err;
- err = "";
- return s;
- }
-
- /// <summary>
- /// 从管道中读取内容(阻塞式)
- /// </summary>
- /// <returns></returns>
- public string read()
- {
- try
- {
- if (!_pipeServer.IsConnected)
- {
- _pipeServer.WaitForConnection();
- }
-
- string str = "";
- StreamReader sr = new StreamReader(_pipeServer);
- while (_pipeServer.CanRead && (null != (str = sr.ReadLine())))
- {
- Thread.Sleep(50);
- return str;
- }
- return str;
- }
- catch (Exception ex)
- {
- err = ex.Message;
- return "";
- }
- }
-
- /// <summary>
- /// 往管道中写入内容
- /// </summary>
- /// <param name="s">写入的内容</param>
- public bool send(string s)
- {
- try
- {
- if (!_pipeClient.IsConnected)
- {
- _pipeClient.Connect();
- }
-
- StreamWriter sw = new StreamWriter(_pipeClient);
- sw.WriteLine(s);
- sw.Flush();
- return true;
- }
- catch (Exception ex)
- {
- err = ex.Message;
- return false;
- }
- }
-
- #region IDisposable 成员
-
- bool _disposed = false;
- public void Dispose()
- {
- try
- {
- if (!_disposed && _pipeServer != null)
- {
- _pipeServer.Close();
- _pipeServer.Dispose();
- }
-
- if (!_disposed && _pipeClient != null)
- {
- _pipeClient.Close();
- _pipeClient.Dispose();
- }
-
- _disposed = true;
- }
- catch (Exception ex)
- {
- err = ex.Message;
- }
- }
-
- #endregion
-
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。