一:在运行的主程序需要位置去启动一个进程
Process proc = new Process();
proc.StartInfo.FileName = @"D:\MyCode\WindowsFormsApplication2\WindowsFormsApplication1\bin\Debug\Test1.exe";
proc.StartInfo.Arguments = "lb:bb bb:100,300,4400";//参数
proc.Start();
二:要启动的程序操作(模态显示窗体)
Test1.exe的 Main函数方法如下
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
OpenApplicationContext app = new OpenApplicationContext(args);
Application.Run(app);//public static void Run(ApplicationContext context);
}
OpenApplicationContext 是继承自ApplicationContext 的一个,这个里面可以实现对参数的处理、打开指定窗口,部分代码如下
public class OpenApplicationContext : ApplicationContext
{
public OpenApplicationContext(string[] args)
{
if (args.Length > 1)
{
if (args[0].Contains("bb"))//打开webbrowser报表
{
string[] paras = args[1].Substring(3).Split(',');
ReportParasModel model = new ReportParasModel();
model.Height = int.Parse(paras[2]);
model.Width = int.Parse(paras[3]);
model.LinkUrl = paras[4];
model.Name = paras[5];
ReportWeb rw = new ReportWeb(model);
rw.ShowInTaskbar = false;
rw.StartPosition = FormStartPosition.Manual;
rw.Left = int.Parse(paras[0]);
rw.Top = int.Parse(paras[1]);
Process[] proces = Process.GetProcessesByName("PT4MainFrame");//获取进程
if (proces.Length != 0)
{
IntPtr hwnd = proces[0].MainWindowHandle;
rw.BringToFront();
rw.Show(new WindowWrapper(hwnd)); //也可以用ShowDialog(new WindowWrapper(hwnd));
}
} else if (args[0].Contains("wf"))//打开Winform报表
{
//省略
}
}
}
}
new WindowWrapper(hwnd)); 是一个继承自IWin32Window的类,代码如下
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}
三:实现进程间通信(共享内存方法)
在主程序里添加API
const int WM_COPYDATA = 0x004A;
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
ref COPYDATASTRUCT lParam // second message parameter
);
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
主程序方调用方法给指定进程窗口穿参数,部分代码
private void contractMenu_OnItemClick{
int WINDOW_HANDLER = FindWindow(null, @"HwReportWeb");//HwReportWeb 为窗体上标题Text值
if (WINDOW_HANDLER != 0)//存在该窗体
{ //height,width,url,name
string paras = height + "," + width + "," + url +","+ name;
byte[] sarr = System.Text.Encoding.Default.GetBytes(paras);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = paras;
cds.cbData = len + 1;
SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
}
}
主程序调用端已经完成,下面就是新打开的进程窗体接收这些消息,部分代码如下
const int WM_COPYDATA = 0x004A;
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
string[] paras = mystr.lpData.Split(',');
//height,width,url,name
ReportParasModel paraModel = new ReportParasModel();
paraModel.Height = int.Parse(paras[0]);
paraModel.Width = int.Parse(paras[1]);
paraModel.LinkUrl = paras[2];
paraModel.Name = paras[3];
ReloadUrl(paraModel);
this.BringToFront();
break;
default:
base.WndProc(ref m);
break;
}
}
至此,进程通信完成。