Actualmente mantengo una aplicación interna en .Net. La aplicación utiliza IPC para mantener una sesión de ejecución a la vez; si intenta abrir otra sesión (Alguien vuelve a hacer clic en el icono, algunos abren un archivo de resultados guardado), la segunda sesión lo comunica a la primera sesión y luego finaliza, con la primera sesión y luego iniciando la acción solicitada.¿Cómo usar IPC sin ser un administrador local?
Actualmente hago esto utilizando el espacio de nombres System.ServiceModel, así:
espacio de nombres EventLogViewer.IPCServer {// proporciona el marco común para los procesos comunicarse a contactar a los demás.
[ServiceContract(Namespace = "http://ELV.domain")]
interface IELVLauncher
{
[OperationContract]
bool LaunchTabs(String[] fileNames);
}
public delegate void TabLauncher(String[] fileNames);
class ELVLauncherServer : IDisposable
{
ServiceHost ipcService;
public ELVLauncherServer()
{
Uri baseAddress = new Uri("Http://localhost:45600/elvlauncher/service");
String address = "net.pipe://localhost/elvlauncher/tablauncher";
ipcService = new ServiceHost(typeof(ELVLauncher), baseAddress);
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
ipcService.AddServiceEndpoint(typeof(IELVLauncher), binding, address);
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://localhost:45601/elvlauncher");
ipcService.Description.Behaviors.Add(behavior);
Utilities.WriteMemoryDebugStatement(new DebugStatement(DebugStatement.StatementType.INFO, "Registering IPC Service"));
ipcService.Open();
}
#region IDisposable Members
public void Dispose()
{
ipcService.Close();
}
#endregion
}
public class ELVLauncher : IELVLauncher
{
#region IELVLauncher Members
public bool LaunchTabs(string[] fileNames)
{
try
{
Utilities.WriteMemoryDebugStatement(new DebugStatement(DebugStatement.StatementType.INFO, String.Format("IPC request received, files: {0}", String.Join(", ", fileNames))));
Program.mainWindow.backgroundListener_OnLaunchRequestReceived(fileNames);
}
catch (Exception exception)
{
Utilities.WriteMemoryDebugStatement(new DebugStatement(exception));
}
return (true);
}
#endregion
}
Este código fue desarrollado originalmente bajo Windows XP, ya que al igual que la mayoría de las corporaciones, no pasamos a Vista. Como todos nos ejecutamos como administradores locales, este código se ejecutó sin problemas.
Sin embargo, estamos haciendo la transición a Win 7 ahora, y este código produce una excepción al inicio porque no puede registrar el punto final de IPC. Más información aquí: http://mark.michaelis.net/Blog/WindowsCommunicationFoundationWithWindowsVistaAndUAC.aspx
La solución dada es subir la aplicación para requerir privilegios de administrador. Esto no funciona por dos razones:
- Esta aplicación no necesita privledges de administración de otra forma
- Utilizamos ClickOnce para el despliegue de nuestras herramientas internas y ClickOnce no apoya que no sea correr como el lanzador proceso de nada.
Así que en este punto tengo que encontrar una solución IPC que no requiere privledges de administración y me permite lograr el objetivo original: la detección de una instancia en ejecución del código y le dice qué hacer, de lo contrario el lanzamiento en sí. Cualquier sugerencia sobre qué hacer (dentro del marco .Net, sin soluciones de terceros, por favor) sería muy apreciada.
No repita las etiquetas ".Net 3.5 C#:" en el título. –