Seite 1 von 3

PureBasic und Windows Management Instrumentation (WMI) *PB4*

Verfasst: 11.04.2005 09:37
von DataMiner
Eins vorweg: ich bin nicht der Autor, sondern lediglich der Code-Collektor und Arrangeur aus vielen Codebeispielen in einen Code. Danke also an alle, die ihren Code wiederfinden.

Für Betriebssysteme, die "älter" als WinME sind (Win9x), muss der WMI-Core von Microsoft installiert werden:

http://msdn.microsoft.com/library/defau ... st/wmi.asp

Bei WinNT kann der WMI-Core über "Software" nachinstalliert werden.

Zum experimentieren sollte man sich gleich den Scriptomatic 2 von Microsoft heruterladen, damit ist es am einfachsten die Win32-Klassen und die richtige Objektbezeichnung herauszusuchen.

http://www.microsoft.com/technet/script ... ipto2.mspx

Der Code stellt eine Möglichkeit von vielen dar, WMI zu nutzen. Er basiert auf dem Basis-Beispiel von Microsoft und sollte damit recht universell sein.

http://msdn.microsoft.com/library/defau ... cation.asp

EDIT (15.04.2005): Code um das Beispiel erweitert, wie man mehrere Objekte einer Klasse auf einmal abfragen kann. Dazu werden die abzufragenden Daten (Sprungmarke CallData in DataSection) erst in ein Array eingelesen und per Schleife abgearbeitet.
EDIT (16.04.2005): Select um Case 11 erweitert, damit auch TRUE/FALSE dargestellt werden kann.

******************************************
EDIT (14.02.2006) Code überarbeitet damit er unter PB4 läuft und als "includefile" nutzbar ist. Bis ich das mit den "Pseudo types" hingebogen bekomme, ist der Code so erst einmal nutzbar.
******************************************

******************************************
EDIT (25.04.2007) ts-soft's überarbeiteten Code in den ersten Post eingefügt (Danke nochmal, ts-soft)
******************************************

Code: Alles auswählen

;- WMI Intialisierung, Datenabruf und Deinitialisierung 
; rewritten for PB4 and use as an "IncludeFile" 
; save this code as "wmi.pbi" 
; use it in your project with: 
; 
; includefile "wmi.pbi" 
; WMI_INIT() 
; WMI_Call("Select * FROM Win32_OperatingSystem", "Caption, CSDVersion, SerialNumber, RegisteredUser, Organization") 
; ResetList(wmidata()) 
; While NextElement(wmidata()) 
;   Debug wmidata()  ; Alle Listenelemente darstellen / show all elements 
; Wend 
; WMI_RELEASE("OK") 
; 
;---------------------------------------------------------------------------------------------------------------- 
; Update für PB4 Final by ts-soft 
; unnötige Konstanten und Structuren entfernt (sind in PB enthalten) 
; voller Unicode support 
; --------------------------------------------------------------------------------------------------------------- 
;- KONSTANTEN  PROZEDUREN  STRUKTUREN 

#COINIT_MULTITHREAD = 0 
#RPC_C_AUTHN_LEVEL_CONNECT = 2 
#RPC_C_IMP_LEVEL_IDENTIFY = 2 
#EOAC_NONE = 0 
#RPC_C_AUTHN_WINNT = 10 
#RPC_C_AUTHZ_NONE = 0 
#RPC_C_AUTHN_LEVEL_CALL = 3 
#RPC_C_IMP_LEVEL_IMPERSONATE = 3 
#CLSCTX_INPROC_SERVER = 1 
#wbemFlagReturnImmediately = 16 
#wbemFlagForwardOnly = 32 
#IFlags = #wbemFlagReturnImmediately + #wbemFlagForwardOnly 
#WBEM_INFINITE = $FFFFFFFF 
#WMISeparator = "," 

Procedure StringToBStr(string$) 
  Protected Unicode$ = Space(StringByteLength(string$, #PB_Unicode) + 1) 
  Protected bstr_string.l 
  PokeS(@Unicode$, String$, -1, #PB_Unicode) 
  bstr_string = SysAllocString_(@Unicode$) 
  ProcedureReturn bstr_string 
EndProcedure 

Procedure.s UniToPB(*Unicode) 
  ProcedureReturn PeekS(*Unicode, #PB_Any, #PB_Unicode) 
EndProcedure 


Global txt$, loc.IWbemLocator, svc.IWbemServices, pEnumerator.IEnumWbemClassObject, pclsObj.IWbemClassObject, x.Variant, error.l 
Global NewList wmidata.s() 

ProcedureDLL.s wmi_release(dumdum$) 
  ;- WMI Release 
  svc\release() 
  loc\release() 
  pEnumerator\release() 
  If error=0 
    pclsObj\release() 
  EndIf 
  CoUninitialize_() 
  If FindString(dumdum$, "ERROR", 1) 
    MessageRequester("", dumdum$) 
    End 
  EndIf 
EndProcedure 

ProcedureDLL.s wmi_init() 
  ;- WMI Initialize 
  txt$="" 
  CoInitializeEx_(0,#COINIT_MULTITHREAD) 
  hres=CoInitializeSecurity_(0, -1,0,0,#RPC_C_AUTHN_LEVEL_CONNECT,#RPC_C_IMP_LEVEL_IDENTIFY,0,#EOAC_NONE,0) 
  If hres <> 0: txt$="ERROR: unable To call CoInitializeSecurity": wmi_release(txt$): EndIf 
  hres=CoCreateInstance_(?CLSID_WbemLocator,0,#CLSCTX_INPROC_SERVER,?IID_IWbemLocator,@loc.IWbemLocator) 
  If hres <> 0: txt$="ERROR: unable To call CoCreateInstance": wmi_release(txt$): EndIf 
  hres=loc\ConnectServer(StringToBStr("root\cimv2"),0,0,0,0,0,0,@svc.IWbemServices) 
  If hres <> 0: txt$="ERROR: unable To call IWbemLocator::ConnectServer": wmi_release(txt$): EndIf 
  hres=svc\queryinterface(?IID_IUnknown,@pUnk.IUnknown) 
  hres=CoSetProxyBlanket_(svc,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE) 
  If hres <> 0: txt$="ERROR: unable To call CoSetProxyBlanket": wmi_release(txt$): EndIf 
  hres=CoSetProxyBlanket_(pUnk,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE) 
  If hres <> 0: txt$="ERROR: unable To call CoSetProxyBlanket": wmi_release(txt$): EndIf 
  pUnk\release() 
  ProcedureReturn txt$ 
EndProcedure 

ProcedureDLL.s WMI_Call(WMISelect.s, WMICommand.s) 
  ;- Call Data 
  OnErrorResume() 
  error=0 
  WMICommand=WMISelect+","+WMICommand 
  ClearList(wmidata()) 
  k=CountString(WMICommand,#WMISeparator) 
  Dim wmitxt$(k) 
  For i=0 To k 
    wmitxt$(i) = Trim(StringField(WMICommand,i+1,#WMISeparator)) 
  Next 

  hres=svc\ExecQuery(StringToBStr("WQL"),StringToBStr(wmitxt$(0)), #IFlags,0,@pEnumerator.IEnumWbemClassObject) 
  If hres <> 0: txt$="ERROR: unable To call IWbemServices::ExecQuery": wmi_release(txt$): EndIf 
  hres=pEnumerator\reset() 
  Repeat 
    hres=pEnumerator\Next(#WBEM_INFINITE, 1, @pclsObj.IWbemClassObject, @uReturn) 
    For i=1 To k 
      Sleep_(0) 
      If uReturn <> 0 

        hres=pclsObj\get(StringToBStr(wmitxt$(i)), 0, @x.Variant, 0, 0) 

        type=x\vt 

        Select type 

          Case 8200 
            val.s="" 
            nDim=SafeArrayGetDim_(x\lVal) 
            SafeArrayGetUBound_(x\lVal, nDim, @plUbound) 
            For z=0 To plUbound 
              SafeArrayGetElement_(x\lVal, @z, @rgVar) 
              val.s=val.s+", "+UniToPB(rgVar) 
            Next 
            val.s=Mid(val.s, 3, Len(val.s)) 

          Case 8195 
            val.s="" 
            nDim=SafeArrayGetDim_(x\scode) 
            SafeArrayGetUBound_(x\scode, nDim, @plUbound) 
            For z=0 To plUbound 
              SafeArrayGetElement_(x\scode, @z, @rgVar) 
              val.s=val.s + ", " +  Str(rgVar) 
            Next 
            val.s=Mid(val.s, 3, Len(val.s)) 

          Case 11 
            If x\boolVal=0 
              val.s="FALSE" 
            ElseIf x\boolVal=-1 
              val.s="TRUE" 
            EndIf 

          Case 8 
            val.s=UniToPB(x\bstrVal) 

          Case 3 
            val.s=Str(x\lVal) 

          Case 1 
            val.s="n/a" 

          Default 
            val.s="" 

        EndSelect 

        If FindString(wmitxt$(i), "Date", 1) Or FindString(wmitxt$(i), "Time", 1) 
          AddElement(wmidata()) 
          wmidata()=Mid(val, 7, 2)+"."+Mid(val, 5, 2)+"."+Mid(val, 1, 4)+" "+Mid(val, 9, 2)+":"+Mid(val, 11,2)+":"+Mid(val, 13,2) ;+Chr(10)+Chr(13) 
        Else 
          AddElement(wmidata()) 
          wmidata()=Trim(val) ;+Chr(10)+Chr(13) 
        EndIf 
      EndIf 
    Next 

  Until uReturn = 0 
  If CountList(wmidata())=0 
    For i=1 To k 
      AddElement(wmidata()) 
      wmidata()="n/a" 
    Next 
    error=1 
  EndIf 
  ProcedureReturn wmidata() 
EndProcedure 

;- Data Section 
DataSection 
  CLSID_IEnumWbemClassObject: 
  ;1B1CAD8C-2DAB-11D2-B604-00104B703EFD 
  Data.l $1B1CAD8C 
  Data.w $2DAB, $11D2 
  Data.b $B6, $04, $00, $10, $4B, $70, $3E, $FD 
  IID_IEnumWbemClassObject: 
  ;7C857801-7381-11CF-884D-00AA004B2E24 
  Data.l $7C857801 
  Data.w $7381, $11CF 
  Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24 
  CLSID_WbemLocator: 
  ;4590f811-1d3a-11d0-891f-00aa004b2e24 
  Data.l $4590F811 
  Data.w $1D3A, $11D0 
  Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24 
  IID_IWbemLocator: 
  ;dc12a687-737f-11cf-884d-00aa004b2e24 
  Data.l $DC12A687 
  Data.w $737F, $11CF 
  Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24 
  IID_IUnknown: 
  ;00000000-0000-0000-C000-000000000046 
  Data.l $00000000 
  Data.w $0000, $0000 
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46 

EndDataSection 
Alle Anregungen/Erweiterungen sind willkommen!

Verfasst: 11.04.2005 15:07
von bluejoke
Meine durch Unbildung verursachte Nerverei tut mir sogar selbst leid, aber was ist denn WMI nochmal, und für was ist das gut? Bei wikipedia ist leider auch noch nix drüber geschrieben...

Verfasst: 11.04.2005 15:11
von 125
Google+MSDN hilft:
Was ist WMI?

WMI (Windows Management Instrumentation = Windows-Verwaltungsinstrumentation) wurde ursprünglich 1998 als eine Add-On-Komponente mit Windows NT 4.0 Service Pack 4 veröffentlicht und ist die zentrale Verwaltungstechnologie, die in den Betriebssystemfamilien Windows 2000, Windows XP und Windows Server 2003 integriert ist. WMI basiert auf von der Distributed Management Task Force (DMTF) festgelegten Industriestandards. Die Technologie enthält das Instrumentarium, das den Zugriff auf, die Konfiguration, Verwaltung und Überwachung aller - nun, fast aller - Windows-Ressourcen ermöglicht.

Um die Leistungsfähigkeit und das Funktionsspektrum von WMI zu verstehen, bedenken Sie, wie Windows-Workstations früher einmal verwaltet und überwacht wurden und mitunter heute noch werden. Wahrscheinlich verwendeten oder verwenden Sie eine Vielzahl von grafischen, administrativen Programmen zur Verwaltung von Windows-Ressourcen, wie etwa Datenträger, Ereignisprotokolle, Dateien, Ordner, Dateisysteme, Netzwerkkomponenten, Betriebssystemeinstellungen, Leistungsdaten, Drucker, Prozesse, Registrierungseinstellungen, Sicherheit, Freigaben, Benutzer, Gruppen usw.

Obwohl die grafischen Programme eine funktionale Verwaltungslösung bieten, haben sie doch eines gemeinsam: Vor WMI benötigten alle grafischen Windows-Verwaltungsprogramme Win32-APIs (Application Programming Interface), um Windows-Ressourcen zu verwalten und darauf zuzugreifen. Warum? Weil der programmtechnische Zugriff auf Windows-Ressourcen vor WMI einzig und allein über Win32-APIs möglich war.

Aufgrund dieser Situation hatten Windows-Systemadministratoren keine einfache Möglichkeit, allgemeine Systemverwaltungsaufgaben mit populären Skriptingsprachen zu automatisieren, da die meisten Skriptingsprachen nicht in der Lage sind, Win32-APIs direkt aufzurufen.

Mit WMI ändert sich dies, indem ein durchgängiges Modell und Gerüst geboten wird, mit dem alle Windows-Ressourcen nach außen hin beschrieben und verfügbar gemacht werden. Das Nützlichste daran ist wohl die Tatsache, dass Systemadministratoren mit der WMI-Skriptingbibliothek Systemverwaltungsskripts erstellen können, um beliebige Windows-Ressourcen zu verwalten, die über WMI verfügbar gemacht werden.

Mit Windows Script Host und Microsoft Visual Basic Scripting Edition (VBScript) oder einer beliebigen Skriptsprache, die die COM-Automatisierung unterstützt (z.B. ActivePerl von ActiveState Corporation) können Sie Skripts zur Verwaltung und Automatisierung der folgenden Aspekte Ihrer Unternehmenssysteme, Anwendungen und Netzwerke erstellen:


Systemverwaltung unter Windows Server 2003, Windows XP Professional und Windows 2000. Sie können Skripts zum Abrufen von Leistungsdaten anlegen sowie zur Verwaltung von Ereignisprotokollen, Dateisystemen, Druckern, Prozessen, Registrierungseinstellungen, Planern, Sicherheit, Diensten, Freigaben und einer Vielzahl von anderen Betriebssystemkomponenten und Konfigurationseinstellungen.


Netzwerkverwaltung. Sie können WMI-basierte Skripts zur Verwaltung von Netzwerkdiensten, wie etwa DNS, DHCP und SNMP-fähigen Geräten, schreiben.


Echtzeit-Integritätsüberwachung. Mit WMI-Ereignisabonnements können Sie Skripts zur Überwachung und Beantwortung von Ereignisprotokolleinträgen unmittelbar nach deren Auftreten sowie von Dateisystem- und Registrierungsänderungen und anderen Echtzeit-Betriebssystemänderungen schreiben. Konzeptionell bedeuten WMI-Ereignisabonnements und -Benachrichtigungen für WMI in etwa das Gleiche, was SNMP-Traps im SNMP-Kontext bedeuten.


Windows Server 2003-Verwaltung, Enterprise Edition. Sie können Skripts zur Verwaltung von Microsoft Application Center, Operations Manager, Systems Management Server, Internet Information Server, Exchange Server und SQL Server erstellen.

Re: PureBasic und Windows Management Instrumentation (WMI)

Verfasst: 11.04.2005 19:27
von SoS
DataMiner hat geschrieben:........ und sollte damit recht universell sein.
Hab jetzt mal ein wenig damit rumgespielt.

So wie ich das sehe muss man nur in zeile 85 und 99 anpassen ?

zeile 85 sieht bei mir nun so aus

Code: Alles auswählen

hres=svc\ExecQuery(ansi2bstr("WQL"),ansi2bstr("SELECT * FROM Win32_Processor"), #IFlags,0,@pEnumerator.IEnumWbemClassObject)
und wird richtig angezeigt.

Danach habe ich mal Zeile 99 angepasst

Code: Alles auswählen

hres=pclsObj\get(ansi2bstr("Caption"), 0, mem, 0, 0) 
und wird auch richtig angezeigt.

Also universell ist es schon :allright:

Aber es ist doch recht umständlich,vor allem wie zeige ich mehrere Daten auf einmal an ? Da blicke ich im moment überhaupt nicht durch. :roll:

Verfasst: 12.04.2005 07:03
von DataMiner
Oh, hat sich ja was getan :D

@125: Danke für die Erläuterung

@SoS: richtig, die Zeilen sind es, ich hätte es schreiben sollen.
Aber es ist doch recht umständlich,vor allem wie zeige ich mehrere Daten auf einmal an ? Da blicke ich im moment überhaupt nicht durch.
Ganz ehrlich: ich war so froh, dass der Code überhaupt mal läuft, da habe ich an eine Mehrfachabfrage (so wie in einem VBScript) noch überhaupt nicht zu denken gewagt. Aber das wird der nächste logische Schritt sein. Hab da für die Umsetzung nur ein kleines Zeitproblem, da ich die nächsten Tage unterwegs bin...

Der Code soll exemplarisch erst mal nur eins zeigen: es geht!
Alles weitere folgt.

Verfasst: 15.04.2005 15:16
von DataMiner
Code um das Beispiel erweitert, wie man mehrere Objekte einer Klasse auf einmal abfragen kann. Dazu werden die abzufragenden Daten (Sprungmarke CallData in DataSection) erst in ein Array eingelesen und per Schleife abgearbeitet.

:mrgreen:

Verfasst: 15.04.2005 20:02
von DataMiner
... mehrere Klassen mit den jeweiligen Objekten abfragen:

Code: Alles auswählen

;- KONSTANTEN  PROZEDUREN
#COINIT_MULTITHREAD=0
#RPC_C_AUTHN_LEVEL_CONNECT=2
#RPC_C_IMP_LEVEL_IDENTIFY=2
#EOAC_NONE=0
#RPC_C_AUTHN_WINNT=10
#RPC_C_AUTHZ_NONE=0
#RPC_C_AUTHN_LEVEL_CALL=3
#RPC_C_IMP_LEVEL_IMPERSONATE=3
#CLSCTX_INPROC_SERVER=1
#wbemFlagReturnImmediately=16
#wbemFlagForwardOnly=32
#IFlags = #wbemFlagReturnImmediately + #wbemFlagForwardOnly
#WBEM_INFINITE=$FFFFFFFF

Procedure.l ansi2bstr(ansi.s)
  size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0)
  Dim unicode.w(size)
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), size)
  ProcedureReturn SysAllocString_(@unicode())
EndProcedure

Procedure bstr2string (bstr)
  Shared result.s
  result.s = ""
  pos=bstr
  While PeekW (pos)
    result=result+Chr(PeekW(pos))
    pos=pos+2
  Wend
  ProcedureReturn @result
EndProcedure

;- WMI Initialize
CoInitializeEx_(0,#COINIT_MULTITHREAD)
hres=CoInitializeSecurity_(0, -1,0,0,#RPC_C_AUTHN_LEVEL_CONNECT,#RPC_C_IMP_LEVEL_IDENTIFY,0,#EOAC_NONE,0)
If hres <> 0: MessageRequester("ERROR", "unable to call CoInitializeSecurity", #MB_OK): Goto cleanup: EndIf
hres=CoCreateInstance_(?CLSID_WbemLocator,0,#CLSCTX_INPROC_SERVER,?IID_IWbemLocator,@loc.IWbemLocator)
If hres <> 0: MessageRequester("ERROR", "unable to call CoCreateInstance", #MB_OK): Goto cleanup: EndIf
hres=loc\ConnectServer(ansi2bstr("root\cimv2"),0,0,0,0,0,0,@svc.IWbemServices)
If hres <> 0: MessageRequester("ERROR", "unable to call IWbemLocator::ConnectServer", #MB_OK): Goto cleanup: EndIf
hres=svc\queryinterface(?IID_IUnknown,@pUnk.IUnknown)
hres=CoSetProxyBlanket_(svc,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE)
If hres <> 0: MessageRequester("ERROR", "unable to call CoSetProxyBlanket", #MB_OK): Goto cleanup: EndIf
hres=CoSetProxyBlanket_(pUnk,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE)
If hres <> 0: MessageRequester("ERROR", "unable to call CoSetProxyBlanket", #MB_OK): Goto cleanup: EndIf
pUnk\release()

;- CallData
Restore CallData1
Read k
Dim wmitxt$(k)
For i=1 To k
  Read wmitxt$(i)
Next
Gosub WMI
MessageRequester(wmitxt$(1), wmi$, #MB_OK)
wmi$=""
Restore CallData2
Read k
Dim wmitxt$(k)
For i=1 To k
  Read wmitxt$(i)
Next
Gosub WMI
MessageRequester(wmitxt$(1), wmi$, #MB_OK)
wmi$=""
Restore CallData3
Read k
Dim wmitxt$(k)
For i=1 To k
  Read wmitxt$(i)
Next
Gosub WMI
MessageRequester(wmitxt$(1), wmi$, #MB_OK)
wmi$=""
Restore CallData4
Read k
Dim wmitxt$(k)
For i=1 To k
  Read wmitxt$(i)
Next
Gosub WMI
MessageRequester(wmitxt$(1), wmi$, #MB_OK)
Goto cleanup

WMI:
hres=svc\ExecQuery(ansi2bstr("WQL"),ansi2bstr(wmitxt$(1)), #IFlags,0,@pEnumerator.IEnumWbemClassObject)
If hres <> 0: MessageRequester("ERROR", "unable to call IWbemServices::ExecQuery", #MB_OK): Goto cleanup: EndIf
hres=pEnumerator\reset()
Repeat
hres=pEnumerator\Next(#WBEM_INFINITE, 1, @pclsObj.IWbemClassObject, @uReturn)
For i=2 To k
  mem=AllocateMemory(1000)
  hres=pclsObj\get(ansi2bstr(wmitxt$(i)), 0, mem, 0, 0)
  type=PeekW(mem)
  Select type
    Case 11
      v=PeekL(mem+8)
      If v=0 
        val.s="FALSE" 
      Else 
        val.s="TRUE"
      EndIf
    Case 8
      val.s=PeekS(bstr2string(PeekL(mem+8)))
    Case 3
      val.s=Str(PeekL(mem+8))
    Default
      val.s=""
  EndSelect
  If uReturn <> 0: wmi$=wmi$+wmitxt$(i)+" = "+val+Chr(10)+Chr(13): EndIf
  FreeMemory(mem)
Next
Until uReturn = 0
Return

;- Cleanup
cleanup:
svc\release()
loc\release()
pEnumerator\release()
pclsObj\release()
CoUninitialize_()
End

;- DATA
DataSection
CLSID_IEnumWbemClassObject:
  ;1B1CAD8C-2DAB-11D2-B604-00104B703EFD
Data.l $1B1CAD8C
Data.w $2DAB, $11D2
Data.b $B6, $04, $00, $10, $4B, $70, $3E, $FD
IID_IEnumWbemClassObject:
  ;7C857801-7381-11CF-884D-00AA004B2E24
Data.l $7C857801
Data.w $7381, $11CF
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24
CLSID_WbemLocator:
    ;4590f811-1d3a-11d0-891f-00aa004b2e24
Data.l $4590F811
Data.w $1D3A, $11D0
Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24
IID_IWbemLocator:
    ;dc12a687-737f-11cf-884d-00aa004b2e24
Data.l $DC12A687
Data.w $737F, $11CF
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24
IID_IUnknown:
    ;00000000-0000-0000-C000-000000000046
Data.l $00000000
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46

CallData1:
Data.l 6
Data.s "Select * FROM Win32_OperatingSystem", "Name", "CSDVersion", "SerialNumber", "RegisteredUser", "Organization"
CallData2:
Data.l 4
Data.s "SELECT * FROM Win32_BIOS", "Manufacturer", "Caption", "SerialNumber"
CallData3:
Data.l 10
Data.s "SELECT * FROM Win32_VideoController", "DeviceID", "Caption", "AdapterDACType", "DriverVersion", "InstalledDisplayDrivers", "CurrentBitsPerPixel", "CurrentRefreshRate", "CurrentHorizontalResolution", "CurrentVerticalResolution"
CallData4:
Data.l 9
Data.s "SELECT * FROM Win32_LogicalDisk", "DeviceID", "Description", "VolumeName", "FileSystem", "Size", "FreeSpace", "VolumeSerialNumber", "Compressed"

EndDataSection
(Habe diesen Code separat gepostet, da ich die Kommentierung entfernt und den Code umstrukturiert habe.)
:wink:

Verfasst: 16.04.2005 11:46
von SoS
Hmm,das über Data-Zeilen abzuwickeln darauf hätte ich auch selbst kommen können. Manchmal sieht man den Wald vor Bäumen nicht :allright:

Verfasst: 16.04.2005 17:14
von bingo
:allright: @DataMiner

hast dich doch von einer anderen seite durchgeboxt ... alle achtung !

mal etwas gestrafft ... für einmalige abfragen . du kannst sicher die speicherreservierung aus der schleife rausnehmen - muss nur 1x erfolgen .

[zugefügt ...]
die zeilen (inkl. data ...) , die sich auf pUnk.IUnknown beziehen sind hier nicht notwendig .


auflistung aller netzwerkadapter ...

Code: Alles auswählen

;- KONSTANTEN  PROZEDUREN 
#COINIT_MULTITHREAD=0 
#RPC_C_AUTHN_LEVEL_CONNECT=2 
#RPC_C_IMP_LEVEL_IDENTIFY=2 
#EOAC_NONE=0 
#RPC_C_AUTHN_WINNT=10 
#RPC_C_AUTHZ_NONE=0 
#RPC_C_AUTHN_LEVEL_CALL=3 
#RPC_C_IMP_LEVEL_IMPERSONATE=3 
#CLSCTX_INPROC_SERVER=1 
#wbemFlagReturnImmediately=16 
#wbemFlagForwardOnly=32 
#IFlags = #wbemFlagReturnImmediately + #wbemFlagForwardOnly 
#WBEM_INFINITE=$FFFFFFFF 

Procedure.l ansi2bstr(ansi.s) 
  size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0) 
  Dim unicode.w(size) 
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), size) 
  ProcedureReturn SysAllocString_(@unicode()) 
EndProcedure 

Procedure bstr2string (bstr) 
  Shared result.s 
  result.s = "" 
  pos=bstr 
  While PeekW (pos) 
    result=result+Chr(PeekW(pos)) 
    pos=pos+2 
  Wend 
  ProcedureReturn @result 
EndProcedure 

;- WMI Initialize 
CoInitializeEx_(0,#COINIT_MULTITHREAD) 
hres=CoInitializeSecurity_(0, -1,0,0,#RPC_C_AUTHN_LEVEL_CONNECT,#RPC_C_IMP_LEVEL_IDENTIFY,0,#EOAC_NONE,0) 
If hres <> 0: MessageRequester("ERROR", "unable to call CoInitializeSecurity", #MB_OK): Goto cleanup: EndIf 
hres=CoCreateInstance_(?CLSID_WbemLocator,0,#CLSCTX_INPROC_SERVER,?IID_IWbemLocator,@loc.IWbemLocator) 
If hres <> 0: MessageRequester("ERROR", "unable to call CoCreateInstance", #MB_OK): Goto cleanup: EndIf 
hres=loc\ConnectServer(ansi2bstr("root\cimv2"),0,0,0,0,0,0,@svc.IWbemServices) 
If hres <> 0: MessageRequester("ERROR", "unable to call IWbemLocator::ConnectServer", #MB_OK): Goto cleanup: EndIf 
hres=CoSetProxyBlanket_(svc,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE) 
If hres <> 0: MessageRequester("ERROR", "unable to call CoSetProxyBlanket", #MB_OK): Goto cleanup: EndIf 

hres=svc\ExecQuery(ansi2bstr("WQL"),ansi2bstr("SELECT * FROM Win32_NetworkAdapter"), #IFlags,0,@pEnumerator.IEnumWbemClassObject) 
If hres <> 0: MessageRequester("ERROR", "unable to call IWbemServices::ExecQuery", #MB_OK): Goto cleanup: EndIf 
hres=pEnumerator\reset() 
mem=AllocateMemory(1000) 

While pEnumerator\Next(#WBEM_INFINITE, 1, @pclsObj.IWbemClassObject, @uReturn) = 0

hres=pclsObj\get(ansi2bstr("ProductName"), 0, mem, 0, 0) 

  Select PeekW(mem) 
    Case 8 
      val.s=PeekS(bstr2string(PeekL(mem+8))) 
    Case 3 
      val.s=Str(PeekL(mem+8)) 
    Default 
      val.s="" 
  EndSelect 

Debug val

Wend 

FreeMemory(mem) 

;- Cleanup 
cleanup: 
svc\release() 
loc\release() 
pEnumerator\release() 
pclsObj\release() 
CoUninitialize_() 
End 

;- DATA 
DataSection 
CLSID_IEnumWbemClassObject: 
  ;1B1CAD8C-2DAB-11D2-B604-00104B703EFD 
Data.l $1B1CAD8C 
Data.w $2DAB, $11D2 
Data.b $B6, $04, $00, $10, $4B, $70, $3E, $FD 
IID_IEnumWbemClassObject: 
  ;7C857801-7381-11CF-884D-00AA004B2E24 
Data.l $7C857801 
Data.w $7381, $11CF 
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24 
CLSID_WbemLocator: 
    ;4590f811-1d3a-11d0-891f-00aa004b2e24 
Data.l $4590F811 
Data.w $1D3A, $11D0 
Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24 
IID_IWbemLocator: 
    ;dc12a687-737f-11cf-884d-00aa004b2e24 
Data.l $DC12A687 
Data.w $737F, $11CF 
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24 
EndDataSection
ok ... nächste aufgabe :)

restorepoint unter XP per wmi ein/aus ...
http://support.microsoft.com/default.as ... 99&sd=tech

Verfasst: 16.04.2005 17:47
von DataMiner
@bingo:
Danke für die Blumen.
Der Code ist ja in weiten Teilen dein Verdienst, daher Danke an dich!
Das mit AllocateMemory aus der Schleife nehmen funzt net. Zumindest im ersten Beispiel. Beim 2ten geht´s. Keine Ahnung warum.
ok ... nächste aufgabe

restorepoint unter XP per wmi ein/aus ...
http://support.microsoft.com/default.as ... 99&sd=tech
Wie heisst es so schön:
man soll immer nach dem Höheren streben
aber momentan gefällt´s mir ganz gut auf dieser Stufe :lol:

Ma schaun - wenn ich Zeit hab...

Du meinst doch das hier, oder?
http://msdn.microsoft.com/library/defau ... estore.asp
:?