C# 多个程序实例只允许一个及进程间通信sendMessage

时间:2022-06-30 05:22:27

发送方:
static class Program
{
#region 只运行一个实例
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);

        //遍历与当前进程名称相同的进程列表
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
{
//Return the other process instance.
//MessageBox.Show("已经有了!");
return process;
}
}
}
return null;
}
#endregion
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(System.IntPtr hWnd);

private static void HandleRunningInstance(Process instance)
{
//MessageBox.Show("该应用系统已经在运行!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
ShowWindowAsync(instance.MainWindowHandle, 1); //调用api函数,正常显示窗口
SetForegroundWindow(instance.MainWindowHandle); //将窗口放置最前端。
}

#region sendMessage
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}

//Win32 API函数:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int msg, int wP, ref COPYDATASTRUCT lParam);
private const int WM_COPYDATA = 0x004A;
#endregion

public static bool SendString(IntPtr hWnd, string str)
{
try
{
byte[] sarr = System.Text.Encoding.Default.GetBytes(str);
var ptr = Marshal.StringToHGlobalUni(str);
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = ptr;
cds.cbData = sarr.Length;
cds.lpData = Marshal.AllocHGlobal(sarr.Length);
Marshal.Copy(sarr, 0, cds.lpData, sarr.Length);
SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
//MessageBox.Show("我在sendMesasage后");
return true;
}
catch (Exception e) { return false; }
}

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] path)
{
//MessageBox.Show("我在这儿"+path.Length);
Process instance = RunningInstance();
if (instance == null)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//MessageBox.Show("我在这儿null");
Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CurrentCulture;
ChineseStringLocalizer.Register();
Localizer.SetStringLocalizer(new ChineseStringLocalizer());

var catalog = new TypeCatalog(
typeof(SettingsService),
typeof(CommandService),
typeof(StatusService),
typeof(ControlHostService),
typeof(StandardFileExitCommand),
typeof(DocumentRegistry),
typeof(ContextRegistry),
typeof(DefaultTabCommands),
typeof(MyOutputs), // passes messages to all log writers
typeof(ResFileInfo),
typeof(FileTreeView),
typeof(FolderViewer),
typeof(ResListView),
//typeof(ShortcutKey),
typeof(FileViewer),
typeof(MyOutputService),
typeof(Editor)
//,typeof(StandardEditCommands)
);

var container = new CompositionContainer(catalog);
var toolStripContainer = new ToolStripContainer();
var mainForm = new ResCopyTool.MainForm(toolStripContainer)
{
Text = "美术资源移动工具".Localize(),
Icon = GdiUtil.CreateIcon(ResourceUtil.GetImage(Sce.Atf.Resources.AtfIconImage))
};

var batch = new CompositionBatch();
//MessageBox.Show("我是窗口"+path);
mainForm.Args = path;

batch.AddPart(mainForm);
//batch.AddPart(new WebHelpCommands("http://192.168.2.121:8090/pages/viewpage.action?pageId=14745613".Localize()));
container.Compose(batch);
container.InitializeAll();
Application.Run(mainForm);

container.Dispose();
}
else
{
//MessageBox.Show("我在这儿not null");
HandleRunningInstance(instance);
IntPtr hWnd = instance.MainWindowHandle; //获取ProcessCommunication.exe主窗口句柄
SendString(hWnd, path[0]);
instance.Start();

}
}

接收方:
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}

    //Win32 API函数:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int msg, int wP, ref COPYDATASTRUCT lParam);
private const int WM_COPYDATA = 0x004A;

protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
//接收自定义消息MYMESSAGE,并显示其参数
case WM_COPYDATA:
{
//MessageBox.Show("我在收到 sendMesasage前");

//My_lParam a = new My_lParam();
////Type t = a.GetType();
//a = (My_lParam)m.GetLParam(typeof(My_lParam));
//Marshal.PtrToStringAnsi(m.LParam)
//this.textBox1.Text = a.s[0];
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
//this.textBox1.Text = Marshal.PtrToStringUni(mystr.lpData);Marshal.
byte[] bt = new byte[mystr.cbData];
Marshal.Copy(mystr.lpData, bt, 0, bt.Length);
string tmp = System.Text.Encoding.Default.GetString(bt);
m_args[0] = tmp;
//MessageBox.Show("我在收到 sendMesasage后");

OnReceiveMsgChanged.Raise(this, new OnReceiveMsgArgs(tmp));

}
break;
default:
base.DefWndProc(ref m);
break;
}
}