2010-09-25 12 views
12

estoy haciendo un cargador de imágenes (carga de imágenes a la imagen de alojamiento de sitios web) y estoy teniendo algunos problemas que pasan un argumento (ubicación de la imagen a una aplicación ya se está ejecutando)argumentos Pass a la ejecución de la aplicación

  • En primer lugar digamos que MyApp.exe siempre se está ejecutando
  • Cada vez que hago clic derecho en una imagen, agregué un elemento en el menú contextual predeterminado de Windows que dice "Cargar imagen".
  • Cuando se hace clic en él, necesita pasar la ubicación a la aplicación en ejecución.

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

Tenga en cuenta que la clase ControlPanel no tiene una forma visible, solamente un icono de la bandeja está presente, ya que no se necesita una forma.

¿Podría obtener ayuda sobre cómo hacer esto?

Respuesta

13

Lo he descubierto, ¡muchísimo gracias por la persona que ha publicado el enlace http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a5bcfc8a-bf69-4bbc-923d-f30f9ecf5f64, esto es exactamente lo que estaba buscando!

Aquí hay una solución 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()); 
     } 
    } 
} 

Muchas gracias de todo, y sobre todo la persona que ha publicado que enlazan he mencionado anteriormente pero supongo que elimina su respuesta?

Regards, Kenny

+0

Kenny, gracias por la publicación. Me ayudó mucho. ¿Hay alguna forma de referenciar el Formulario (su ControlPanel) en el método NewInstanceHandler? Sé que está haciendo referencia al método "uploadImage" en ControlPanel, pero ese es un método estático. Pero necesito hacer referencia a los métodos no estáticos. Por favor, hágamelo saber – Dave

2

Suponiendo que tiene control sobre el entorno de ejecución, la aplicación de escucha podría simplemente exponer un punto final utilizando WCF o incluso un socket TCP sin formato. De esta forma, cualquier otra aplicación puede conectarse a ella de forma dinámica pero estructurada.

Aunque el emisor y el receptor están en la misma máquina, usar una solución de transporte de red (como WCF o TCP) es una forma excelente de enviar datos de forma segura entre procesos.

Aquí hay un ejemplo de cómo hacerlo en TCP con C#: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server

WCF puede ser un poco más complicado (en parte debido a su flexibilidad, y también debido a las restricciones de serialización), pero hay un montón de documentación en línea sobre cómo usarlo. WCF es una solución más orientada a objetos porque se pueden generar clases de proxy que le permiten realizar llamadas fuertemente tipadas a objetos reales, en lugar de simplemente enviar mensajes.

4

Bueno, tendrá que establecer un canal de comunicación para que otras aplicaciones publiquen las imágenes. Este canal de comunicación puede ser uno de los siguientes: no solo una lista completa muestras:

  • Un directorio que miran y su archivo se agrega una vez que se agrega al directorio.
  • Un puerto al que otras aplicaciones pueden enviar información.
  • Un servicio web alojado automáticamente que acepta las imágenes.
  • Un puerto TCP que recibe las imágenes.
  • Una tubería con nombre.
  • ....

Como se puede ver hay varias posibilidades. El más adecuado para usted depende de su escenario. El sistema de archivos es una opción que se puede implementar fácilmente usando FileSystemWatcher para una muestra see here.

Un servicio web alojado de forma autónoma expone un servicio web que puede recibir imágenes. See here para una muestra.

En mi humilde opinión, estas son las dos opciones que son más fáciles. Pero ... hay varios más.

Para el puerto TCP, ver la publicación de Tim.

+1

+1 para la sugerencia FileSystemWatcher. He usado un observador en muchas aplicaciones con excelentes resultados. No usaría uno si se requiere una comunicación sincrónica o una relación de solicitud/respuesta, pero no parece que esos sean requisitos. –

+0

Hola, gracias por darme algunas ideas adicionales, pero debes saber que no tengo control sobre el sitio web de alojamiento de imágenes. Acabo de subir la imagen haciendo un envío POST y recuperando la respuesta (que contiene el enlace de la imagen cargada, en Internet) Probé la idea de TCP, pero por alguna razón no creo que sea eso lo que necesito. Obtuve una aplicación totalmente funcional que carga imágenes, etc. Lo único que necesito ahora es: – Kenny

0

I añaden algunas pequeñas adiciones a la solución anterior para hacer referencia a un setter de la forma con el fin de pasar los argumentos a ella.

Primero que todo, cree una referencia estática a la instancia inicial del formulario (MainForm).

Luego, en el envío posterior de argumentos, NewInstanceHandler puede usar la referencia guardada al formulario para acceder a sus métodos/propiedades públicos (en mi caso, un sistema llamado AddItem).

Una manera fácil de probar esto es agregar una propiedad pública a su formulario con un colocador para cambiar la propiedad de texto del formulario (el texto del título).

[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

El nombre 'MainForm' no existe en el contexto actual ¿qué pasa ??? – ACE

0

Para evitar el funcionamiento del segundo ejemplo después de pasar los argumentos de línea de comandos para instancia existente, añadí debajo de fragmento de código.

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

El nombre 'MainForm' no existe en el contexto actual ¿Qué sucede? – ACE

Cuestiones relacionadas