Creé una aplicación que también se puede ejecutar como un -service
conmutador de servicio (usando un ). Esto funciona perfectamente sin problemas cuando estoy ejecutando el servicio desde un símbolo del sistema (tengo algo configurado que me permite depurarlo desde una consola cuando no se ejecuta como un verdadero servicio). Sin embargo, cuando intento ejecutarlo como un verdadero servicio y luego uso mi aplicación para abrir el mapa de memoria existente, aparece el error ...
No se puede encontrar el archivo especificado.
Cómo lo ejecuto como un servicio o en la consola:
[STAThread]
static void Main(string[] args)
{
//Convert all arguments to lower
args = Array.ConvertAll(args, e => e.ToLower());
//Create the container object for the settings to be stored
Settings.Bag = new SettingsBag();
//Check if we want to run this as a service
bool runAsService = args.Contains("-service");
//Check if debugging
bool debug = Environment.UserInteractive;
//Catch all unhandled exceptions as well
if (!debug || debug)
{
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
if (runAsService)
{
//Create service array
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new CRSService()
};
//Run services in interactive mode if needed
if (debug)
RunInteractive(ServicesToRun);
else
ServiceBase.Run(ServicesToRun);
}
else
{
//Start the main gui
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainGUI());
}
}
En mi aplicación tengo un lado de servicio y un lado de aplicación. El propósito de la aplicación es solo controlar el servicio. Realizo todo el control usando archivos de mapeo de memoria y parece funcionar muy bien y se adapta a mis necesidades. Sin embargo, cuando ejecuto la aplicación como un verdadero servicio, veo en mis registros de depuración que está creando el archivo de mapa de memoria con el nombre correcto y la configuración de acceso. También puedo ver el archivo que se crea donde debería estar. Todo parece funcionar exactamente igual en el servicio que cuando depuro a través de la consola. Sin embargo, mi aplicación (cuando se ejecuta como una aplicación en lugar del servicio) me dice que no puede encontrar el archivo de mapa de memoria. También tengo que arrojar la ruta del nombre del archivo en el error, así que sé que está buscando en el lugar correcto.
Cómo abro el mapa de memoria (donde se produce el error):
m_mmf = MemoryMappedFile.OpenExisting(
m_sMapName,
MemoryMappedFileRights.ReadWrite
);
Nota: El servicio se ejecuta con la misma cuenta en la que ejecuto Visual Studio. Como ejemplo, la siguiente imagen muestra mi administrador de tareas, la interfaz gráfica de usuario services.msc y mi cuenta actualmente identificada.
¿Cómo puedo hacer que mi aplicación cliente vea el archivo de mapa de memoria después de que el servicio lo cree? ¿Por qué funciona cuando lo ejecuto como un servicio de consola y no cuando lo ejecuto como un verdadero servicio?
fuente
Respuestas:
Los servicios de Windows se ejecutan de forma aislada, en sesión
0
, mientras que su aplicación de consola se ejecuta en una sesión de usuario, por lo que para que se comuniquen entre sí, el archivo mapeado de memoria debe crearse en elGlobal\
espacio de nombres, para que sea accesible a otras sesiones. p.ejTambién debe establecer los permisos apropiados para el archivo, para asegurarse de que todos los usuarios puedan acceder a él.
Recomiendo leer esta publicación Implementando archivos mapeados de memoria no persistente que exponen las comunicaciones de estilo IPC con los servicios de Windows , que explica lo anterior con mucho más detalle y tiene ejemplos sobre cómo configurar los permisos, etc.
Código fuente copiado de la publicación vinculada anteriormente:
fuente