Estoy tratando de mediar en un pequeño servicio de Windows, haciendo que espere una señal de otro proceso durante el inicio. Por supuesto, sé que ese enfoque puede (o incluso lo hará) a veces llevar al tiempo de espera de inicio del servicio. Ese no es el caso.El servicio de Windows no puede ver el semáforo con nombre
El problema es con el nombre System.Thread.Sempaphore que uso con fines de mediación. Semaphore se crea y se adquiere en otro lugar utilizando la siguiente construcción. No hay cambio GC lo tiene ya que rompo explícitamente la ejecución justo debajo de la línea dada para fines de prueba.
Boolean newOne;
System.Threading.Semaphore rootSemaphore =
new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out newOne);
El código anterior funciona bien, obviamente. Siguiente código funciona bien cuando se está ejecutando en modo de depuración o bajo aplicación de consola:
Boolean createdNew;
System.Threading.Semaphore semaphore =
new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew);
if (createdNew)
throw new Exception("That's not what we wanted");
exactamente el mismo código falla cuando se está ejecutando como parte del servicio de Windows:
static class Program
{
static void Main(string[] args)
{
Boolean createdNew;
System.Threading.Semaphore semaphore =
new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew);
if (createdNew)
throw new Exception("That's not what we wanted");
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new Dummy() };
ServiceBase.Run(ServicesToRun);
}
}
Así, lookig ayuda en esta.
PD: He estado tratando de usar Mutex en su lugar, sin embargo, había otro problema con él: la aplicación en espera no se pone al día cuando el propietario llama a Mutex.ReleaseMutex();
ACTUALIZACIÓN:
De acuerdo con la respuesta Anurag Ranjhan He editado semáforo de la creación de la rutina de la siguiente manera y esa cosa ahora funciona bien:
Boolean newOne = false;
System.Security.Principal.SecurityIdentifier sid =
new System.Security.Principal.SecurityIdentifier(
System.Security.Principal.WellKnownSidType.WorldSid,
null);
System.Security.AccessControl.SemaphoreSecurity sec =
new System.Security.AccessControl.SemaphoreSecurity();
sec.AddAccessRule(new System.Security.AccessControl.SemaphoreAccessRule(
sid,
System.Security.AccessControl.SemaphoreRights.FullControl,
System.Security.AccessControl.AccessControlType.Allow));
System.Threading.Semaphore rootSemaphore =
new Semaphore(1, 1, "Global\\DummyServiceSemaphore", out newOne, sec);
¡Gracias! Eso resolvió el problema. – Vitaly
Recientemente tuve el mismo problema, e incluso con el prefijo "Global \", tuve que especificar explícitamente el objeto SemaphoreSecurity como se indica en la actualización de pregunta anterior para que funcione dentro de un servicio de Windows. Eso, sin embargo, hizo el trabajo! – mthierba