WPF单实例窗口+ ClickOnce +传递参数

时间:2016-07-20 05:54:29

标签: c# wpf pointers

情况:

我的应用程序设计为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在内的解决方案

1 个答案:

答案 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);
        }