Criei um aplicativo que também pode ser executado como um serviço (usando uma -service
opção). Isso funciona perfeitamente sem problemas quando estou executando o serviço em um prompt de comando (eu tenho algo configurado que permite depurá-lo em um console quando não estou sendo executado como um serviço verdadeiro). No entanto, quando tento executá-lo como um serviço verdadeiro, utilizo meu aplicativo para abrir o mapa de memória existente, recebo o erro ...
Não foi possível encontrar o arquivo especificado.
Como eu o executo como um serviço ou no console:
[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());
}
}
No meu aplicativo, tenho um lado de serviço e um lado de aplicativo. O objetivo do aplicativo é apenas controlar o serviço. Eu faço todo o controle usando arquivos de mapeamento de memória e parece funcionar muito bem e atende às minhas necessidades. No entanto, quando executo o aplicativo como um serviço verdadeiro, vejo nos meus logs de depuração, criando o arquivo de mapa de memória com o nome correto e as configurações de acesso. Também posso ver o arquivo sendo criado onde deveria estar. Tudo parece funcionar exatamente da mesma forma no serviço, quando depuro via console. No entanto, meu aplicativo (quando executado como um aplicativo em vez do serviço) informa que não é possível encontrar o arquivo de mapa de memória. Eu tenho que lançar o caminho do nome do arquivo no erro também, então eu sei que ele está procurando no lugar certo.
Como abro o mapa de memória (onde o erro é gerado):
m_mmf = MemoryMappedFile.OpenExisting(
m_sMapName,
MemoryMappedFileRights.ReadWrite
);
Nota: O serviço está sendo executado com a mesma conta em que executo o Visual Studio. Como exemplo, a imagem abaixo mostra meu gerenciador de tarefas, o services.msc gui e minha conta atualmente identificada.
Como faço para que meu aplicativo cliente veja o arquivo de mapa de memória depois que o serviço o cria? Por que funciona quando eu o executo como um serviço de console e não quando o executo como um serviço verdadeiro?
fonte
Respostas:
Os Serviços do Windows são executados isoladamente, na Sessão
0
, enquanto o aplicativo Console é executado em uma sessão do usuário. Para que eles se comuniquem, o arquivo mapeado de memória deve ser criado noGlobal\
espaço para nome, para torná-lo acessível a outras sessões. por exemploVocê também deve definir as permissões apropriadas para o arquivo, para garantir que todos os usuários possam acessá-lo.
Eu recomendo a leitura desta postagem Implementando arquivos mapeados de memória não persistente, expondo as comunicações no estilo IPC com o Windows Services , que explica o item acima com muito mais detalhes e tem exemplos de configuração de permissões etc.
Código-fonte copiado da postagem vinculada acima:
fonte