Ich habe eine Anwendung erstellt, die auch als Service- -service
Switch (mit einem ) ausgeführt werden kann. Dies funktioniert einwandfrei, wenn ich den Dienst über eine Eingabeaufforderung ausführe (ich habe etwas eingerichtet, mit dem ich ihn von einer Konsole aus debuggen kann, wenn er nicht als echter Dienst ausgeführt wird). Wenn ich jedoch versuche, es als echten Dienst auszuführen und dann meine Anwendung zum Öffnen der vorhandenen Speicherzuordnung verwende, wird der Fehler angezeigt ...
Die angegebene Datei konnte nicht gefunden werden.
Wie ich es als Dienst oder in der Konsole ausführe:
[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());
}
}
In meiner Anwendung habe ich eine Service- und eine Anwendungsseite. Der Zweck der Anwendung besteht lediglich darin, den Dienst zu steuern. Ich mache die gesamte Steuerung mithilfe von Speicherzuordnungsdateien und es scheint großartig zu funktionieren und entspricht meinen Anforderungen. Wenn ich die Anwendung jedoch als echten Dienst ausführe, der aus meinen Debug-Protokollen hervorgeht, wird die Speicherzuordnungsdatei mit dem richtigen Namen und den richtigen Zugriffseinstellungen erstellt. Ich kann auch sehen, dass die Datei dort erstellt wird, wo sie sein sollte. Im Service scheint alles genauso zu funktionieren wie beim Debuggen über die Konsole. Meine Anwendung (wenn sie als Anwendung anstelle des Dienstes ausgeführt wird) teilt mir jedoch mit, dass die Speicherzuordnungsdatei nicht gefunden werden kann. Ich habe es auch den Dateinamenpfad in den Fehler werfen, damit ich weiß, dass es an der richtigen Stelle sucht.
Wie öffne ich die Speicherzuordnung (wo der Fehler ausgelöst wird):
m_mmf = MemoryMappedFile.OpenExisting(
m_sMapName,
MemoryMappedFileRights.ReadWrite
);
Hinweis: Der Dienst wird als dasselbe Konto ausgeführt, in dem ich Visual Studio ausgeführt habe. Das folgende Bild zeigt als Beispiel meinen Task-Manager, die GUI services.msc und mein aktuell identifiziertes Konto.
Wie kann ich meine Clientanwendung dazu bringen, die Speicherzuordnungsdatei anzuzeigen, nachdem der Dienst sie erstellt hat? Warum funktioniert es, wenn ich es als Konsolendienst ausführe und nicht, wenn ich es als echten Dienst ausführe?
quelle
Antworten:
Windows-Dienste werden isoliert in der Sitzung ausgeführt
0
, während Ihre Konsolenanwendung in einer Benutzersitzung ausgeführt wird. Damit sie miteinander kommunizieren können, muss die Speicherzuordnungsdatei imGlobal\
Namespace erstellt werden, damit sie für andere Sitzungen zugänglich ist. z.BSie sollten auch die entsprechenden Berechtigungen für die Datei festlegen, um sicherzustellen, dass alle Benutzer darauf zugreifen können.
Ich würde empfehlen, diesen Beitrag zu lesen. Implementieren von nicht persistenten Speicherzuordnungsdateien Offenlegen der IPC-Kommunikation mit Windows-Diensten. In diesem Beitrag werden die obigen Informationen ausführlicher erläutert und Beispiele zum Festlegen der Berechtigungen usw.
Quellcode aus dem oben verlinkten Beitrag kopiert:
quelle