如何发送一个指令给另外一个进程[进程通信2]
上一篇文章讲的是如何用Windows API去控制其他进程的显示,这次主要说的是一个应用程序如何如何获得指令并执行一系列的内部操作。如最大化,最小化等。
为什么要对消息进行转化处理?
因为Windows API只支持string类型的参数传递,所以在应用程序中对string进行转化,转化成进程可以识别的类型。
Scenario:
1. 用户发送指令给另外一个进程
2. 另外一个应用程序接收指令并做相应处理----------------------------------------------------- 消息转化 开始-----------------------------------------------------
using System;//[assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: CLSCompliant(false)] namespace SDK {public class CMDParameters{static UIArtifact Command { get; set; }/// <summary>/// Parse command line arguments./// </summary>/// <param name="args">command line arguments</param>/// <returns>True if parse ok, false means print help message only.</returns>public static UIArtifact ParseParameters(string[] args){Command = new UIArtifact(); #region parse command line parametersfor (int i = 0; i < args.Length; i++){string arg = args[i];string candidateArg = string.Empty;bool isSwitch = false;// normalize argumentif (arg.StartsWith("/") || arg.StartsWith("-")){isSwitch = true;int index = arg.IndexOf(":");if (index != -1){candidateArg = arg.Substring(index + 1);arg = arg.Substring(0, index);}}arg = arg.ToLower();// if it is a switch argumentif (isSwitch){ // parse argument by argument matchParseArguments(arg, candidateArg);}}return Command; #endregion}/// <summary>/// Parse command line arguments./// </summary>/// <param name="args">command line arguments</param>/// <returns>True if parse ok, false means print help message only.</returns>public static UIArtifact ParseParameters(string args){ #region parse command line parametersstring[] newargs = args.Split(new Char[] { ' ' });return ParseParameters(newargs); #endregion}private static bool ArgumentMatch(string arg, string formal){return ArgumentMatch(arg, formal, true);}/// <summary>/// Provides two match kinds:/// extra match: argu == formal./// short-form match: argu is a char and equals to formal's first char./// argu is striped from command line arg, without '/' or '-'/// </summary>/// <param name="arg">the command line argument which starts with '/' or '-'</param>/// <param name="formal">the expected argument string</param>/// <param name="exactMatch">true means exact match mode, false means short-form match</param>/// <returns>true if argument matches, else false.</returns>private static bool ArgumentMatch(string arg, string formal, bool exactMatch){if ((arg[0] == '/') || (arg[0] == '-')){arg = arg.Substring(1);if (arg == formal){return true;}else if (!exactMatch && arg.Length == 1){return (arg[0] == formal[0]);}}return false;}private static void WriteHelpMessage(){Console.WriteLine(String.Format("Help PTMC",System.Reflection.Assembly.GetExecutingAssembly().GetName().Name));}private static void ParseArguments(string arg, string candidateArg){if (ArgumentMatch(arg, "?") || ArgumentMatch(arg, "help")){WriteHeader();WriteHelpMessage();}else if (ArgumentMatch(arg, "v") || ArgumentMatch(arg, "visible")){if (!string.IsNullOrEmpty(candidateArg.Trim())){bool isSucess = false;if (bool.TryParse(candidateArg, out isSucess)){Command.IsShowInWindow = isSucess;}}}else if (ArgumentMatch(arg, "t") || ArgumentMatch(arg, "tablepage")){if (!string.IsNullOrEmpty(candidateArg.Trim())){UIView.Tab tab;bool isSucess = Enum.TryParse(candidateArg.Trim(), true, out tab);if (isSucess){switch (tab){case UIView.Tab.Review:Command.TabPage = UIView.Tab.Review;break;case UIView.Tab.Scheduling:Command.TabPage = UIView.Tab.Scheduling;break;case UIView.Tab.Reporting:Command.TabPage = UIView.Tab.Reporting;break;case UIView.Tab.Quality:Command.TabPage = UIView.Tab.Quality;break;case UIView.Tab.Administration:Command.TabPage = UIView.Tab.Administration;break;case UIView.Tab.None:Command.TabPage = UIView.Tab.None;break;}}}}else if (ArgumentMatch(arg, "c") || ArgumentMatch(arg, "cluster")){if (!string.IsNullOrEmpty(candidateArg.Trim())){int cluster = 0;if (int.TryParse(candidateArg.Trim(), out cluster)){Command.Cluster = cluster;}}}else if (ArgumentMatch(arg, "p") || ArgumentMatch(arg, "protocolname")){if (!string.IsNullOrEmpty(candidateArg.Trim())){Command.ProtocolName = candidateArg.Trim();}}else if (ArgumentMatch(arg, "f") || ArgumentMatch(arg, "folder")){if (!string.IsNullOrEmpty(candidateArg.Trim())){if (!string.IsNullOrEmpty(candidateArg.Trim())){Command.FolderPath = candidateArg.Trim();}}}else if (ArgumentMatch(arg, "fresh")){bool isSucess = false;if (bool.TryParse(candidateArg, out isSucess)){Command.Isfresh = isSucess;}}else if (ArgumentMatch(arg, "close")){bool isSucess = false;if (bool.TryParse(candidateArg, out isSucess)){Command.IsClose = isSucess;}}else if (ArgumentMatch(arg, "cmd") || ArgumentMatch(arg, "command")){if (!string.IsNullOrEmpty(candidateArg.Trim())){UIView.Command command;bool isSucess = Enum.TryParse(candidateArg.Trim(), true, out command);if (isSucess){switch (command){case UIView.Command.FileCommons:Command.Command = UIView.Command.FileCommons;break;case UIView.Command.ReviewRequest:Command.Command = UIView.Command.ReviewRequest;break;case UIView.Command.None:Command.Command = UIView.Command.None;break;}}}}else{throw new Exception("[ERROR] Invalid switch: " + arg);}}}public class UIArtifact{private PTMCHostBase windowInfo;public PTMCHostBase WindowInfo{get{if (windowInfo == null){windowInfo = new PTMCHostBase();}return windowInfo;}set{windowInfo = value;}}public bool? IsShowInWindow { get; set; }public bool Isfresh { get; set; }public bool? IsClose { get; set; }public UIView.Tab TabPage { get; set; }public UIView.Command Command { get; set; }public int Cluster { get; set; }public string ProtocolName { get; set; }public string FolderPath { get; set; }}public class UIView{public enum Tab{None = 0x00,Quality,Review,Scheduling,Reports,Reporting,Administration,}public enum Command{None = 0x00,ReviewRequest,FileCommons,}public enum AppWindowName{}}public class PTMCHostBase{public bool isShowInWindow { get; set; }public bool isShowInTaskBar { get; set; }public IntPtr IntPtr { get; set; }public string WindowName { get; set; }public string WindowClassName { get; set; }} }
----------------------------------------------------- 消息转化 结束-----------------------------------------------------
----------------------------------------------------- 初始化 必要接口-----------------------------------------------------
/// 在程序初始化的时候进行第一遍的消息处理
private void XXX(){string[] cmd = System.Environment.GetCommandLineArgs();UIArtifact command = CMDParameters.ParseParameters(cmd);// MessageBox.Show(command.isShowInWindow.ToString());
ShowWindow(command);}
private void RibbonWindow_Loaded(object sender, RoutedEventArgs e){this.InitialHook();}
private void InitialHook(){(PresentationSource.FromVisual(this) as HwndSource).AddHook(new HwndSourceHook(this.WndProc));}private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){
// 在其他进程需要的时候进行消息处理
if (msg == NativeMethodsExtensibility.WM_COPYDATA) { NativeMethodsExtensibility.COPYDATASTRUCT cds = (NativeMethodsExtensibility.COPYDATASTRUCT)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(NativeMethodsExtensibility.COPYDATASTRUCT)); if (!string.IsNullOrEmpty(cds.lpData)) { UIArtifact command = CMDParameters.ParseParameters(cds.lpData); // MessageBox.Show(cds.lpData); //测试返回消息 // ShowWindow(command);//对返回消息进行处理 } } return hwnd; }
----------------------------------------------------结束初始化 必要接口-----------------------------------------------------