Passa argomenti all’esecuzione dell’applicazione

Sto facendo un uploader di immagini (carica l’immagine sul sito di hosting di immagini) e sto riscontrando alcuni problemi nel passare un argomento (posizione dell’immagine a un’applicazione già in esecuzione)

  • Prima di tutto, supponiamo che MyApp.exe sia sempre in esecuzione
  • Ogni volta che faccio clic destro su un’immagine ho aggiunto un elemento nel menu di scelta rapida di Windows predefinito che dice “Carica immagine”.
  • Quando viene cliccato, deve passare la posizione all’applicazione già in esecuzione.

Il mio 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()); } } } 

Si noti che la class ControlPanel non ha un modulo visibile, solo un’icona nel vassoio è presente poiché non è necessario un modulo.

Posso avere qualche aiuto su come farlo?

L’ho capito, grazie fantastico per la persona che ha pubblicato il http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a5bcfc8a-bf69-4bbc-923d-f30f9ecf5f64 link, questo è esattamente quello che stavo cercando!

Ecco una soluzione completa:

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

Grazie mille, e soprattutto la persona che ha pubblicato quel link che ho citato sopra, ma suppongo che abbia cancellato la sua risposta?

Saluti, Kenny

Bene, dovrai stabilire un canale di comunicazione per altre applicazioni in cui pubblicare le immagini. Questo canale di comunicazione può essere uno dei seguenti: non un elenco completo solo dei campioni:

  • Una directory che viene guardata dalla tua app e il file viene aggiunto una volta aggiunto alla directory.
  • Una porta su cui altre applicazioni possono inviare informazioni.
  • Un servizio web self-hosted che accetta le immagini.
  • Una porta TCP che riceve le immagini.
  • Una pipa con nome.
  • ….

Come vedi ci sono diverse possibilità. Quello giusto per te dipende dal tuo scenario. Il file system è un’opzione che può essere implementata facilmente utilizzando un FileSystemWatcher per un esempio, vedere qui .

Un servizio Web ospitato in proprio espone un servizio Web in grado di ricevere immagini. Vedi qui per un campione.

IMHO, queste sono le due opzioni più facili. Ma … ce ne sono molti altri.

Per la porta TCP vedi il post di Tim.

Supponendo di avere il controllo sull’ambiente di esecuzione, l’applicazione di ascolto potrebbe semplicemente esporre un endpoint utilizzando WCF o persino un socket TCP non elaborato. In questo modo, qualsiasi altra applicazione può connettersi ad essa in modo dinamico ma strutturato.

Anche se sia il mittente che il destinatario si trovano sulla stessa macchina, l’utilizzo di una soluzione di trasporto di rete (come WCF o TCP) è un ottimo modo per inviare dati in tutta sicurezza tra i processi.

Ecco un esempio di come farlo in TCP con c #: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server

WCF può essere un po ‘più complicato (dovuto in parte alla sua flessibilità, e anche a causa delle restrizioni di serializzazione) ma vi è abbondanza di documentazione online su come usarlo. WCF è una soluzione più orientata agli oggetti poiché è ansible generare classi proxy che consentono di effettuare chiamate fortemente tipizzate su oggetti reali, rispetto all’invio di messaggi.

Ho aggiunto alcune piccole aggiunte alla soluzione precedente per fare riferimento a un setter nel modulo per passare gli argomenti ad esso.

Quindi, prima di tutto, crea un riferimento statico all’istanza iniziale del modulo (MainForm).

Quindi, al successivo invio di argomenti, NewInstanceHandler può utilizzare il riferimento salvato nel modulo per accedere ai suoi metodi / proprietà pubblici (nel mio caso, un setter chiamato AddItem).

Un modo semplice per testare questo è aggiungere una proprietà pubblica al modulo con un setter per modificare la proprietà del testo del modulo (il testo del titolo).

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

Per evitare l’esecuzione della seconda istanza dopo aver passato gli argomenti della riga di comando all’istanza esistente, ho aggiunto sotto lo snippet di codice.

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