Ich füge die WMI-Veröffentlichung zu einem auf .net framework 3.5 basierenden Windows-Dienst hinzu, der unter dem Konto "Netzwerkdienst" ausgeführt wird.
Laut einer Dokument, das ich auf MSDN gefunden habe sollte das Konto "Netzwerkdienst" standardmäßig über WMI-Veröffentlichungsberechtigungen verfügen. (" Standardmäßig sind die folgenden Benutzer und Gruppen berechtigt, Daten und Ereignisse zu veröffentlichen: ... Netzdienst , ... ")
Wenn der Dienst jedoch Instrumentation.Publish(myStatusClassInstance) aufruft, kommt es zu einer DirectoryNotFoundException;
System.IO.DirectoryNotFoundException was unhandled
Message: Could not find a part of the path 'C:\Windows\system32\WBEM\Framework\root\MyWMINamespace\MyService_SN__Version_1.0.3686.26280.cs'.
also sieht es so aus, als ob System.Management.Instrumentation versucht, Code on the fly zu generieren, und wenn es unter dem Netzwerkdienst läuft, zielt es auf ein Verzeichnis, für das der Netzwerkdienst keine Berechtigungen hat.
Was ist die beste Lösung für dieses Problem? Kann ich das code-gen Zielverzeichnis in app.config oder im Code überschreiben? Ich möchte nicht mit Dateisystemberechtigungen herumfummeln müssen, wenn ich den Dienst bereitstelle...
更新情報 : Ich glaube, es handelt sich um eine "Funktion", bei der älterer FX-Code mit neueren Sicherheitseinstellungen in Win7 kollidiert. Intern rufen die WMI-verwalteten Klassen das WMI-Installationsverzeichnis aus der Registry ab und verwenden es als Ausgabepfad für den generierten Code. Leider dürfen (oder sollen) viele Benutzer nicht unter %SystemRoot% schreiben... ...ich habe einen Connect-Bug eingereicht ( #530392 ), um zu sehen, ob MSFT Klarheit schaffen und/oder eine Lösung oder Umgehung anbieten kann.
Update 2: Ich gehe davon aus, dass dies für normale Benutzerkonten kein Problem darstellt, da die UAC-Virtualisierung einsetzt und die Dateien an anderer Stelle speichert. Das "Netzwerkdienst"-Konto wird jedoch offenbar nicht von der UAC-Virtualisierung abgedeckt(?).
Aktualisierung 3: 550pt Kopfgeld hinzugefügt. Einfache Einschränkungen: .net framework 3.5 basierter Windows-Dienst, der als Netzwerkdienst läuft, muss in der Lage sein, Daten über WMI unter Verwendung von System.Management.Instrumentation auf Win7 und Win2008[RTM & R2] mit Standardberechtigungen/Sicherheitseinstellungen zu veröffentlichen, ohne auf die Änderung von internen/privaten Mitgliedern des Frameworks unter Verwendung von Reflection zurückzugreifen. Out-of-the-Box", aber saubere Lösungen sind willkommen. Wird eine zweite verwandte bounty-Q als Platzhalter für eine andere 550pt öffnen, wenn SO erlaubt.
Kopfgeld-Update: Ich beabsichtige, das Kopfgeld für diese Frage durch eine zweite Hand-in-Hand-Frage zu verdoppeln, die als Platzhalter für das Kopfgeld dienen wird:
https://stackoverflow.com/questions/2208341/bounty-placeholder (<-- Offenbar war dies nicht erlaubt, so dass die Kopfgeld-Platzhalterfrage von der SO-Knigge-Polizei geschlossen wurde).
Update 4: Das wird immer besser. Mir ist aufgefallen, dass installutil die fehlenden Dateien nach c schreibt: \windows\syswow64...etc... So stellte ich fest, dass ich die 32-Bit-Version von installutil zur Installation des Dienstes verwendete, der Dienst aber als 64-Bit-Prozess lief. Der offensichtliche Nebeneffekt war, dass der Code, der bei der Ausführung von installutil erzeugt wurde, unter syswow64 (dem 32-Bit-Systemverzeichnis) landete, während der Dienst im 64-Bit-Systemverzeichnis (system32) danach suchte. (<-- Off-Topic, aber ich mag es wirklich, wie MSFT es geschafft hat, die Namen zu vertauschen... :) ).
Also habe ich versucht, den Dienst mit der 64-Bit-Version von installutil zu installieren. Das scheiterte kläglich mit Berechtigungsfehlern in der %sysroot% \wbem\framework...etc... Pfad. Als Nächstes habe ich den Dienst als x86 neu kompiliert und ihn erneut mit der 32-Bit-Version von installutil registriert. Dies führte zu einer völlig neuen Ausnahme:
System.Exception: The code generated for the instrumented assembly failed to compile.
at System.Management.Instrumentation.InstrumentedAssembly..ctor(Assembly assembly, SchemaNaming naming)
at System.Management.Instrumentation.Instrumentation.Initialize(Assembly assembly)
at System.Management.Instrumentation.Instrumentation.GetInstrumentedAssembly(Assembly assembly)
at System.Management.Instrumentation.Instrumentation.GetPublishFunction(Type type)
at System.Management.Instrumentation.Instrumentation.Publish(Object instanceData)
at SomeService.InstanceClass.PublishApp(String name) in e:\work\clientname\SomeService\SomeService\WMIProvider.cs:line 44
at SomeService.SomeServiceService..ctor() in e:\work\clientname\SomeService\SomeService\SomeServiceService.cs:line 26
at SomeService.Program.Main() in e:\work\clientname\SomeService\SomeService\Program.cs:line 17
...kommt näher...