情况:
我的应用程序设计为SingleInstance - > 工作
我的应用程序通过ClickOnce部署 - >的工作
新请求是,您可以将参数传递给此Application。目前通过ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
现在是棘手的部分。应该传递的Argument是FileName或Path。
解析这个没问题。
但是由于我的SingleInstance是用PostMessage
实现的,因此我很难将Argument传递给正在运行的实例。
我的原生' s-Class:
internal static class NativeMethods {
public const int HwndBroadcast = 0xffff;
public static readonly int WmShowme = RegisterWindowMessage("WM_SHOWME");
public static readonly int SendArg = RegisterWindowMessage("WM_SENDARG");
[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32")]
private static extern int RegisterWindowMessage(string message);
}
MessageSender
protected override void OnStartup(StartupEventArgs e) {
// check that there is only one instance of the control panel running...
bool createdNew;
this._instanceMutex = new Mutex(true, @"{0D119AC4-0F2D-4986-B4AB-5CEC8E52D9F3}", out createdNew);
if (!createdNew) {
var ptr = Marshal.StringToHGlobalUni("Hello World");
NativeMethods.PostMessage((IntPtr)NativeMethods.HwndBroadcast, NativeMethods.WmShowme, IntPtr.Zero, IntPtr.Zero);
NativeMethods.PostMessage((IntPtr)NativeMethods.HwndBroadcast, NativeMethods.SendArg, ptr, IntPtr.Zero);
Environment.Exit(0);
}
}
接收器(在MainWindow中):
protected override void OnSourceInitialized(EventArgs e) {
base.OnSourceInitialized(e);
var source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(this.WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
if (msg == NativeMethods.SendArg) {
var s = Marshal.PtrToStringUni(wParam);
MessageBox.Show(s);
}
if (msg == NativeMethods.WmShowme) {
this.ShowMe();
}
return IntPtr.Zero;
}
问题/问题:
在第一个实例中,所有内容都可以编译并运行良好。但在开始第二个实例后,我收到了System.AccessViolationException
。
奇怪的事情:有时我没有异常,但收到的字符串显示为例如:
䀊虐\ u0090
由于我不是WindowMessages和Pointers的专家,我现在有点无能为力。
该项目不希望实现包括第三方工具,IPC或WCF在内的解决方案
答案 0 :(得分:1)
我做了一个快速测试(尽管使用WinForms)。当你执行PostMessage时,你会让接收端访问另一个进程的内存,这是一个不行,因此是AccessViolationException。由于您不喜欢IPC,这是另一种使用内存映射文件的方法。对不起凌乱的代码,只是为了说明方法。
发件人部分:
mmf = MemoryMappedFile.CreateOrOpen("testmap", 10000);
using (var stm = mmf.CreateViewStream())
{
new BinaryWriter(stm).Write("Hello World");
}
NativeMethods.PostMessage((IntPtr)NativeMethods.HwndBroadcast, NativeMethods.SendArg, IntPtr.Zero, IntPtr.Zero);
接收方部分:
if (m.Msg == NativeMethods.SendArg)
{
string s;
using (var mmf = MemoryMappedFile.OpenExisting("testmap"))
{
using (var stm = mmf.CreateViewStream())
{
s = new BinaryReader(stm).ReadString();
}
}
listBox1.Items.Add(s);
}