A blogban leírtak a szerzők saját véleménye, és nem a munkáltatójuké.

Egyszerű .NET WMI Provider futtatása

Ha a saját alkalmazásunkat ki szeretnénk egészíteni, hogy konfigurációs és monitorozási információkat szolgáltasson Windows platformon, akkor erre az ajánlott módszer egy WMI Provider készítése. A 3.5-ös .NET Frameworkben már egész jó támogatás van arra, hogy mindezt menedzselt kódban írjuk meg:

WMI Provider Extensions: itt található némi technológia áttekintő, példakódok, és néhány tanács, hogy mihez kezdjünk hiba esetén.

Saját provider készítése esetén az első kérdés, amit el kell döntenünk, hogy milyen úgynevezett “hosting modelt” használunk:

  • In-process: A providert egy DLL-ben implementáljuk, amit a Global Assembly Cache-be (GAC) kell rakni. A provider a WMI folyamatában fut.
  • Decoupled: A provider kódja az alkalmazás kódjába kerül, így az csak akkor érhető el, ha az alkalmazásunk fut.

Egyszerű provider példa futtatása

Nézzük meg, hogy hogyan lehet egy egyszerű decoupled providert lefordítani és futtatni! Az MSDN-en lévő példakódot fogjuk használni: How To: Create a Basic Decoupled Provider A példa szövegében jól le vannak írva, hogy mik a fontosabb .NET attribútumok, amikkel meg kell jelölnünk a kódunkat. A példa egy Singleton WMI osztályt implementál, így annak csak egy darab WMI-beli példánya lesz majd. A példát a következő módon tudjuk kipróbálni (a parancssoros módszert írom, Visual Studioból hasonló módon lehetne futtatni):

1. Előkövetelmény: 3.5-ös .NET Frameworknek kell telepítve lenni a gépen. Mentsük el a példa kódját egy ConsoleDecoupled.cs fájlba.

2. Fordítás: fordítsuk le a C# fordítóval, a fordításhoz kell a System.Management.Instrumentation szerelvényre hivatkoznunk:

c:\WINDOWS\Microsoft.NET\Framework\v3.5\csc.exe ConsoleDecoupled.cs /reference:"c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Management.Instrumentation.dll"

3. Telepítés: a WMI alrendszernek meg kell mondanunk, hogy van egy új provider a rendszerben, ennek a MOF leíró fájlját meg kell adnunk. Ezt szerencsére az installutil elvégzi, ha a kódban volt egy DefaultManagementInstaller-ból számazó osztályunk. Futtassuk le rendszergazdaként az installutilt:

c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installutil.exe ConsoleDecoupled.exe

Ha minden jól megy, a végén a következőt kell látnunk: “The transacted install has completed.”

4. Futtatás: Indítsuk el az alkalmazásunkat, egyelőre rendszergazdaként:

ConsoleDecoupled.exe

5. Tesztelés: egy PowerShell ablakból le tudjuk ellenőrizni, hogy tényleg szolgáltat-e információt az alkalmazásunk magáról WMI-on keresztül:

PS C:\> Get-WmiObject -namespace root\consoledecoupled -class runtimeconfigsettings

(RunTimeconfigSettings volt annak az osztálynak a neve, amit elláttunk a ManagementEntity attribútummal.) Ha minden működik, a következőhöz hasonló kimenetet kell látnunk:

__GENUS          : 2
__CLASS          : RuntimeConfigSettings
__SUPERCLASS     :
__DYNASTY        : RuntimeConfigSettings
__RELPATH        : RuntimeConfigSettings=@
__PROPERTY_COUNT : 1
__DERIVATION     : {}
__SERVER         : MZ-DEV
__NAMESPACE      : root\consoledecoupled
__PATH           : \\MZ-DEV\root\consoledecoupled:RuntimeConfigSettings=@
ReadMe           : StartValue

Látszik, hogy a WMI példányunknak egy tulajdonsága van, a ReadMe, aminek az értéke a StartValue. Tehát működik rendesen a WMI provider.

Futtatás nem rendszergazdaként

Most már csak azt kéne megoldani, hogy ne kelljen rendszergazdaként futtatni az alkalmazást. Ugyanis, ha sima felhasználóval indítjuk a ConsoleDecoupled.exe-t, akkor a következőt kapjuk:

Unhandled Exception: System.Management.Instrumentation.WmiProviderInstallationException: Exception of type 'System.Management.Instrumentation.WMIInfraException' was thrown.
at System.Management.Instrumentation.InstrumentationManager.RegisterType(TypemanagementType) at ConsoleDecoupled.Program.Main(String[] args)

Egy lehetséges megoldás, ha megadjuk a provider SecurityDescriptorában, hogy ki az még, aki futtathatja. Indítsunk  rendszergazdaként egy wbemtest.exe-t!

  1. Connect: root\ConsoleDecoupled
  2. Enum Classes: a superclass nevéhez nem kell beírni semmit, és állítsuk át Recursive-ra, majd nyomjuk OK-ot. Erre kilistázza az összes WMI osztályt, ami ebben a névtérben van.
  3. Keressük ki a WMI_extension-t, és kattintsuk duplán rá!
  4. Az Instances gombbal kérjük le a példányait, és kattintsunk duplán a ConsoleDecoupled nevűre!
  5. Így most megkaptuk a providerünket reprezentáló példányt.
  6. Keressük meg a SecurityDescriptor tulajdonságát, és írjuk át az értékét a O:%G:%D:(A;;0x1;;;%) stringre (az összes % helyére helyettesítsük be annak a felhasználónak vagy csoportnak a SID-jét, akinek jogot akarunk adni).
  7. Ne felejtsük el megnyomni a Save Object gombot!

Teszteljük a ConsoleDecoupled futtatását sima felhasználóként.

Hibák

Sajnos a WMI Providerek által visszaadott hibakódokról kevés dokumentáció van.

  • Troubleshooting WMI Provider Extensions: itt találhatunk néhány jó tanácsot.
  • Állítólag az Application eseménynaplóba is loggol hiba esetén, én ilyesmivel még nem találkoztam.
  • Miután telepítettük az installutil segítségével a saját providerünket, wbemtest segítségével érdemes kikeresni az osztályt, és a Show MOF gombbal megnézni, hogy tényleg átkerült-e a MOF állományba az összes tulajdonság és metódus, amit a kódban definiáltunk.
  • Ha a WmiConfigurationAttribute-ot hiányolja a fordító, akkor a System.Core-ra kell referenciát hozzáadni (a WmiConfigurationAttribute MSDN-es leírásában az Assembly résznél szerepel az, hogy melyik szerelvény tartalmazza).
  • “Provider is not capable of the attempted operation” hiba (kód: 0x80041024): nincs megadva [ManagementBind] attribútum egyik metódusra sem, vagy az nem publikus, vagy nem konstruktor vagy statikus metódus, így a WMI nem tud mit meghívni, amikor el szeretné érni a providert.
  • A WMIInfraException jogosultság gond esetén szokott például előjönni, ellenőrizzük, hogy rendszergazdaként futtatva is ez a hiba-e.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>