Tengo una aplicación que en un inicio posterior detecta si hay un proceso con el mismo nombre en ejecución y, de ser así, activa la ventana de la aplicación en ejecución y luego sale.Enviar mensaje a un proceso de Windows (no su ventana principal)
El problema es que la ventana principal podría estar oculta (solo un ícono de área de notificación visible), dejándome así sin el identificador de ventana.
En el inicio, la propiedad MainWindowHandle
de la instancia anterior es 0, por lo que no puedo enviar ShowWindow
o PostMessage
.
¿Hay alguna manera en que pueda enviar un mensaje que pueda ser interceptado por la aplicación en ejecución, permitiéndole mostrar su ventana principal?
La aplicación está escrita en C#, el código que estoy usando para lograr esto a continuación.
[STAThread]
static void Main()
{
bool createdNew = true;
using (Mutex mutex = new Mutex(true, "MyMutexName", out createdNew))
{
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
Interop.WINDOWINFO pwi = new Interop.WINDOWINFO();
IntPtr handle = process.MainWindowHandle;
var isVisible = Interop.GetWindowInfo(handle, ref pwi);
if (!isVisible)
{
MessageBox.Show(Constants.APP_NAME + " is already running, check the notification area (near the clock).",
Constants.APP_NAME, MessageBoxButtons.OK, MessageBoxIcon.Information);//temporary message, until I find the solution
//Interop.ShowWindow(handle, Interop.WindowShowStyle.ShowNormal);
//Interop.PostMessage(handle, Interop.WM_CUSTOM_ACTIVATEAPP, IntPtr.Zero, IntPtr.Zero);
}
else
Interop.SetForegroundWindow(handle);//this works when the window is visible
break;
}
}
}
}
}
}
Tendrá una referencia a '' System.Runtime.InteropServices – BillW
@BillW: Gracias. La publicación se actualiza en consecuencia. –
@Matt ¡Buen trabajo, Matt! fyi: compila, funciona bien en VS 2010 beta 2 compilado contra FrameWork 4.0. Lo que realmente me gusta de esto es que puedes poner una llamada a 'MessageBox.Show (' ... '); en el caso de que esté reactivando la instancia única para que el usuario final sepa qué está sucediendo. Mi única pregunta sería sobre el tema de poner la activación en un bloque try-catch para que pueda lanzar el Mutex: ¿eso tiene alguna implicación para el comportamiento de la aplicación si la instancia del formulario principal continúa creando otros formularios o lo que sea? – BillW