2010-09-25 16 views
12

Ich mache ein Bild Uploader (Upload Bild zu Bild-Hosting-Website), und ich habe einige Fragen, die ein Argument (Bildstelle zu einer bereits laufenden Anwendung), denPass Argumente laufende Anwendung

  • Zu allererst Nehmen wir an, MyApp.exe läuft immer
  • Immer wenn ich mit der rechten Maustaste auf ein Bild klicke, habe ich ein Element im Standard-Windows-Kontextmenü mit dem Text "Bild hochladen" hinzugefügt.
  • Wenn Sie darauf klicken, muss der Speicherort an die bereits ausgeführte Anwendung übergeben werden.

Mein Program.cs:

static class Program 
{ 
    [DllImport("user32.dll")] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

    [DllImport("user32.dll")] 
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, UIntPtr 
    wParam, IntPtr lParam); 

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern uint RegisterWindowMessage(string lpString); 

    [STAThread] 
    static void Main(params string[] Arguments) 
    { 
     if (Arguments.Length > 0) 
     { 
    //This means that the the upload item in the context menu is clicked 
    //Here the method "uploadImage(string location)" 
    //of the running application must be ran 
     } 
     else 
     { 
    //just start the application 
      Application.Run(new ControlPanel()); 
     } 
    } 
} 

Beachten Sie, dass die Control Klasse keine sichtbare Form hat, nur ein Tray-Icon vorhanden ist, da ein Formular, das nicht benötigt wird.

Konnte ich Hilfe bekommen, wie man das macht?

Antwort

13

Ich habe es herausgefunden, also super danke für die Person, die den http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a5bcfc8a-bf69-4bbc-923d-f30f9ecf5f64 Link gepostet hat, das ist genau das, was ich gesucht habe!

Hier ist eine der vollständige Lösung:

static class Program 
{ 
    [STAThread] 
    static void Main(params string[] Arguments) 
    { 
     SingleInstanceApplication.Run(new ControlPanel(), NewInstanceHandler); 
    } 

    public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e) 
    { 
     string imageLocation = e.CommandLine[1]; 
     MessageBox.Show(imageLocation); 
     e.BringToForeground = false; 
     ControlPanel.uploadImage(imageLocation); 
    } 

    public class SingleInstanceApplication : WindowsFormsApplicationBase 
    { 
     private SingleInstanceApplication() 
     { 
      base.IsSingleInstance = true; 
     } 

     public static void Run(Form f, StartupNextInstanceEventHandler startupHandler) 
     { 
      SingleInstanceApplication app = new SingleInstanceApplication(); 
      app.MainForm = f; 
      app.StartupNextInstance += startupHandler; 
      app.Run(Environment.GetCommandLineArgs()); 
     } 
    } 
} 

Thanks a lot alle und vor allem die Person, die diesen Link gepostet ich oben erwähnt habe, aber ich denke, dass er seine Antwort gelöscht?

Regards, Kenny

+0

Kenny, danke für die Post. Es hat mir sehr geholfen. Gibt es in der NewInstanceHandler-Methode überhaupt ein Verweis auf das Formular (Ihr ControlPanel)? Ich weiß, dass Sie die "uploadImage" -Methode in ControlPanel referenzieren, aber das ist eine statische Methode. Aber ich muss auf die nicht-statischen Methoden verweisen. Bitte lassen Sie mich wissen – Dave

2

Angenommen, Sie haben die Kontrolle über die Ausführungsumgebung, kann die überwachte Anwendung einen Endpunkt mithilfe von WCF oder sogar einem Raw-TCP-Socket bereitstellen. Auf diese Weise kann sich jede andere Anwendung auf dynamische, aber strukturierte Weise mit ihr verbinden.

Obwohl Sender und Empfänger sich auf demselben Computer befinden, ist die Verwendung einer Netzwerktransportlösung (wie WCF oder TCP) eine hervorragende Methode, um Daten sicher zwischen Prozessen zu senden.

Hier ist ein Beispiel dafür, wie es in TCP mit C# zu tun: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server

WCF kann etwas komplizierter (was teilweise auf sie Flexibilität ist, und auch aufgrund der Serialisierung Einschränkungen), aber es gibt viel Dokumentation online, wie man es benutzt. WCF ist eine eher objektorientierte Lösung, da Proxyklassen generiert werden können, mit denen Sie stark typisierte Aufrufe an tatsächliche Objekte vornehmen können, anstatt nur Nachrichten zu senden.

4

Nun, Sie müssen einen Kommunikationskanal für andere Anwendungen einrichten, um die Bilder zu veröffentlichen. Dieser Kommunikationskanal kann einer der folgenden sein - keine vollständige Liste nur Beispiele:

  • Ein Verzeichnis, das von Ihrer App überwacht wird, und die Datei wird hinzugefügt, sobald sie dem Verzeichnis hinzugefügt wird.
  • Ein Port, an den andere Anwendungen Informationen senden können.
  • Ein selbst gehosteter Webservice, der die Bilder akzeptiert.
  • Ein TCP-Port, der die Bilder empfängt.
  • Ein Named Pipe.
  • ....

Wie Sie mehrere Möglichkeiten sehen gibt. Der richtige für Sie hängt von Ihrem Szenario ab. Das Dateisystem ist eine Option, die einfach unter Verwendung einer FileSystemWatcher für eine Probe see here implementiert werden kann.

Ein selbst gehosteter Webservice stellt einen Webdienst zur Verfügung, der Bilder empfangen kann. See here für eine Probe.

IMHO, das sind die zwei Optionen, die am einfachsten sind. Aber ... es gibt mehrere mehr.

Für den TCP-Port siehe Tims Beitrag.

+1

+1 für den FileSystemWatcher Vorschlag. Ich habe einen Beobachter in vielen Anwendungen mit tollen Ergebnissen verwendet. Ich würde keinen verwenden, wenn eine synchrone Kommunikation oder eine Anfrage/Antwort-Beziehung erforderlich ist, aber es klingt nicht so, als ob dies Anforderungen wären. –

+0

Hallo, danke, dass gab mir einige zusätzliche Ideen, aber Sie sollten wissen, dass ich keine Kontrolle über die Bild-Hosting-Website habe. Ich lade einfach das Bild hoch, indem ich eine POST sende und die Antwort (die den Link des hochgeladenen Bildes enthält) im Internet abruft. Ich habe versucht, die TCP-Idee, aber aus irgendeinem Grund denke ich nicht, dass das ist, was ich brauche. Ich habe eine voll funktionsfähige Anwendung, die Bilder usw. hochlädt. Das einzige, was ich jetzt brauche, ist: – Kenny

0

fügte ich einige kleine Zusätze zu der bisherigen Lösung eine setter auf dem Formular, um zu verweisen, die Argumente zu übergeben.

Also zuerst, erstellen Sie eine statische Referenz auf die erste Instanz des Formulars (MainForm).

Beim anschließenden Senden von Argumenten kann der NewInstanceHandler den gespeicherten Verweis auf das Formular verwenden, um auf seine öffentlichen Methoden/Eigenschaften zuzugreifen (in meinem Fall ein Setter namens AddItem).

Eine einfache Möglichkeit, dies zu testen, ist das Hinzufügen einer öffentlichen Eigenschaft zu Ihrem Formular mit einem Setter, um die Texteigenschaft des Formulars (den Titeltext) zu ändern.

[STAThread] 
    static Form1 MainForm; 

    static void Main(params string[] Arguments) 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     MainForm = new Form1(); 
     SingleInstanceApplication.Run(MainForm, NewInstanceHandler); 
    } 

    public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e) 
    { 
     MainForm.AddItem = e.CommandLine[1]; 
     e.BringToForeground = false; 
    } 

    public class SingleInstanceApplication : WindowsFormsApplicationBase 
    { 
     private SingleInstanceApplication() 
     { 
      base.IsSingleInstance = true; 
     } 

     public static void Run(Form f, StartupNextInstanceEventHandler startupHandler) 
     { 
      SingleInstanceApplication app = new SingleInstanceApplication(); 
      app.MainForm = f; 
      app.StartupNextInstance += startupHandler; 
      app.Run(Environment.GetCommandLineArgs()); 
     } 
    } 
+0

Der Name 'MainForm' existiert nicht im aktuellen Kontext was ist los ??? – ACE

0

Um zu vermeiden, dass die zweite Instanz ausgeführt wird, nachdem die Befehlszeilenargumente an die vorhandene Instanz übergeben wurden, habe ich das folgende Code-Snippet hinzugefügt.

static class Program 
{ 
    [STAThread] 

    static void Main(params string[] Arguments) 
    { 
     Form1 MainForm; 
     bool bInstanceFlag; 

     Mutex MyApplicationMutex = new Mutex(true, "MyApp_Mutex", out bInstanceFlag); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     if (!bInstanceFlag) 
     { 
      MainForm = new Form1(); 
     SingleInstanceApplication.Run(MainForm, NewInstanceHandler); 
    } 
    else 
    { 
     MainForm = new Form1(); 
     SingleInstanceApplication.Run(MainForm, NewInstanceHandler); 
     MainForm.Close(); 
    } 
} 

public static void NewInstanceHandler(object sender, StartupNextInstanceEventArgs e) 
{ 
    MainForm.AddItem = e.CommandLine[1]; 
    e.BringToForeground = false; 
} 

public class SingleInstanceApplication : WindowsFormsApplicationBase 
{ 
    private SingleInstanceApplication() 
    { 
     base.IsSingleInstance = true; 
    } 

    public static void Run(Form f, StartupNextInstanceEventHandler startupHandler) 
    { 
     SingleInstanceApplication app = new SingleInstanceApplication(); 
     app.MainForm = f; 
     app.StartupNextInstance += startupHandler; 
     app.Run(Environment.GetCommandLineArgs()); 
    } 
} 
} 
+0

Der Name 'MainForm' existiert nicht im aktuellen Kontext was ist los ??? – ACE

Verwandte Themen