2016-07-20 4 views
1

Situation:WPF Single Instance Fenster + Clickonce + geben Argumente

Meine Anwendung ist so konzipiert, SingleInstance zu sein ->Arbeits
Meine Anwendung wird über Clickonce bereitgestellt ->Arbeits

New Anfrage ist, dass Sie Argumente an diese Anwendung übergeben können. Dies wird derzeit mit ApplicationDeployment.CurrentDeployment.ActivationUri.Query;

jetzt der schwierige Teil realisiert. Das Argument, das übergeben werden soll, ist ein Dateiname oder ein Pfad.

Parsing ist kein Problem.

Aber da meine SingleInstance mit PostMessage realisiert wird, habe ich Probleme beim Abrufen des Arguments an die laufende Instanz.

Mein Mutter ‚s-Klasse:

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); 

    } 

Die Message

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

Der Receiver (In 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; 
    } 

Frage/Problem:

Alles kompiliert und läuft gut in der ersten Instanz. Aber nach dem Start der zweiten Instanz erhalte ich eine System.AccessViolationException.

Sonderbare Sache: Manchmal im, keine Ausnahme bekommen, aber die empfangene Zeichenfolge zeigt, wie zum Beispiel:

䀊 虐 \ u0090

Da im kein Experte mit WindowMessages und Pointers, ich bin ein bisschen ahnungslos jetzt.

Lösungen 3rd-Party-Tools IPC oder WCF einschließlich nicht für dieses Projekt wollte

+0

Vielleicht sollten Sie dies versuchen: http: // Stackoverflow.com/questions/14506406/wpf-single-instance-best-practices – KANAX

+0

Danke für Ihre leisten, aber dieser Artikel ist nur handlig verschiedene Möglichkeiten, eine SingleInstance-Anwendung einzurichten, nicht, wie Parameter übergeben – lokusking

Antwort

1

ich einen schnellen Test tat realisieren (mit WinForms, obwohl). Wenn Sie PostMessage ausführen, machen Sie das Ende des Zugriffs auf den Speicher eines anderen Prozesses, was ein No-Go ist, daher AccessViolationException. Da Sie IPC nicht mögen, ist hier ein anderer Ansatz, Speicher-Mapped-Dateien zu verwenden. Sorry für unordentlichen Code, nur um den Ansatz zu veranschaulichen.

Absender Teil:

  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); 

Empfängerteil:

 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); 
     } 
+0

Wieder ein Tag habe ich etwas gelernt Neu. Danke, Mann. :) – lokusking