Entwickler-Ecke
Windows API - Verwendete Grafikkarte ermitteln.
MephistoFFF - So 01.03.09 22:38
Titel: Verwendete Grafikkarte ermitteln.
Schönen guten Abend miteinander!
Ich habe vor einigen Tagen sehr lange in Google und Co zugebracht, allerdings nichts wirklich brauchbares gefunden.
Meine Frage: Wie kann ich am besten die AKTUELL VERWENDETE Grafikkarte eines PCs ermitteln?
Ich habe es zwar schon geschafft, mit diesen Codes hier:
http://www.delphipraxis.net/topic17365_name+der+grafikkarte+auslesen+wie.html&highlight=grafikkarte
auf manchen PCs die aktuelle Grafikkarte zu ermitteln, allerdings wird auf vielen PCs etwas komplett falsches angezeigt, weil beispielsweise noch die Treiber der vorigen Grafikkarte in der Registry vermerkt sind.
Ich bin für jede Hilfe dankbar.
mfG
Moderiert von
Narses: Topic aus Dateizugriff verschoben am So 01.03.2009 um 23:41
MephistoFFF - Mo 02.03.09 18:12
Klingt erstmal sehr gut, nur leider habe ich noch nie mit WMI gearbeitet... Wie binde ich das ganze in Delphi ein und arbeite dann damit in Delphi?
Vielen Dank.
mfG
MephistoFFF - Mo 02.03.09 18:33
Der erste Link ist unlustig ;) . trotzdem danke... und trotzdem schonwieder eine neue frage: wie importiere ich das ganze überhaupt erstmal? ich hab im google nichts brauchabres gefunden... und vor allem... wo lad ich die libary erstmal runter?
mfG
jaenicke - Mo 02.03.09 18:46
Da du Turbo Delphi vermutlich in der Explorer Edition (?) hast, kannst du sie nicht selbst importieren. Ich habe die Datei einmal in den Anhang gelegt. Das kannst du mit irgendeiner anderen Delphiversion machen, benutzen kannst du sie auch in Turbo Delphi. [meta]WbemScripting[/meta][meta]WbemScripting_TLB[/meta]
Narses - Mo 02.03.09 19:01
Moin!
Da ich bei Delphi+WMI jedesmal Hautausschlag kriege, hier noch ein Tipp: Die meisten Codes, die so im Netz in Bezug auf WMI+Delphi kursieren, haben Memory-Leaks. :shock:
Das hier ist AFAIK "sauber":
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| uses ..., Variants, WbemScripting_TLB, ActiveX;
function QueryWMI(const QueryClass, QueryProperty: String; AStrings: TStrings): Boolean; var Locator: ISWbemLocator; Services: ISWbemServices; ObjectSet: ISWbemObjectSet; WMIObject: ISWbemObject; WMIProperty: ISWbemProperty; Enum: IEnumVariant; ObjValue: Cardinal; TempObj: OleVariant; begin Result := FALSE; try Locator := CoSWbemLocator.Create; try Services := Locator.ConnectServer('', 'root\cimv2', '', '', '','', 0, NIL); if Assigned(Services) then begin Services.Security_.ImpersonationLevel := 3; ObjectSet := Services.ExecQuery('SELECT * FROM '+QueryClass, 'WQL', wbemFlagForwardOnly or wbemFlagReturnWhenComplete, NIL); Enum := (ObjectSet._NewEnum) as IEnumVariant; while (Enum.Next(1, TempObj, ObjValue) = S_OK) do begin try WMIObject := IUnknown(TempObj) as ISWBemObject; except WMIObject := NIL; end; TempObj := Unassigned; if Assigned(WMIObject) then begin WMIProperty := WMIObject.Properties_.Item(QueryProperty, 0); if (NOT VarIsNull(WMIProperty.Get_Value)) then AStrings.Add(Trim(WMIProperty.Get_Value)); end; end; Result := TRUE; end; finally Services := NIL; Locator := NIL; end; except Result := FALSE; end; end;
procedure TForm1.Button1Click(Sender: TObject); begin QueryWMI('Win32_VideoController','Caption',Memo1.Lines); end; |
cu
Narses
//EDIT: Es gibt mittlerweile auch
eine Komponenten-Version [
http://www.delphi-forum.de/topic_Komponenten+zur+WMIAbfrage+TWMIConnection+TWMIQuery_94142.html] zur IDE-Integration, die mehrere Abfragen hintereinander schnell ausführen kann.
MephistoFFF - Mo 02.03.09 19:34
Vielen Vielen Dank! Das funzt bis jetzt erstmal wunderbar!
Danke euch beiden ;) :) .
mfG
Stread - Mo 04.07.11 00:18
Ich hoffe mal, dass ich das hier ausgraben darf.
Ich habe die Typenbibliothek WMI Scripting als Unit eingebunden und mit dem Code von Narses funktioniert alles super. Grafikkarten und Grafikkarten Ram werden angezeigt.
Allerdings habe ich das Gefühl dass ich die Ergebnisse nur in Memos anzeigen lassen kann? Kann ich das direkt in einem Label anzeigen lassen oder muss ich den Umweg über das Memo gehen?
Edit: Verwendet wird Delphi XE
BenBE - Mo 04.07.11 04:25
Narses hat folgendes geschrieben : |
Moin!
Da ich bei Delphi+WMI jedesmal Hautausschlag kriege, hier noch ein Tipp: Die meisten Codes, die so im Netz in Bezug auf WMI+Delphi kursieren, haben Memory-Leaks. :shock:
Das hier ist AFAIK "sauber": Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| function QueryWMI(const QueryClass, QueryProperty: String; AStrings: TStrings): Boolean; var begin Result := FALSE; try Locator := CoSWbemLocator.Create; try Services := Locator.ConnectServer('', 'root\cimv2', '', '', '','', 0, NIL); if Assigned(Services) then begin Services.Security_.ImpersonationLevel := 3; ObjectSet := Services.ExecQuery('SELECT * FROM '+QueryClass, 'WQL', wbemFlagForwardOnly or wbemFlagReturnWhenComplete, NIL); Enum := (ObjectSet._NewEnum) as IEnumVariant; while (Enum.Next(1, TempObj, ObjValue) = S_OK) do begin try WMIObject := IUnknown(TempObj) as ISWBemObject; except WMIObject := NIL; end; TempObj := Unassigned; if Assigned(WMIObject) then begin WMIProperty := WMIObject.Properties_.Item(QueryProperty, 0); if (NOT VarIsNull(WMIProperty.Get_Value)) then AStrings.Add(Trim(WMIProperty.Get_Value)); end; end; Result := TRUE; end; finally Services := NIL; Locator := NIL; end; except Result := FALSE; end; end; | cu
Narses |
Ich hab da mal paar Variablen markiert, die nicht finalisiert werden via Resourcen-Schutzblock... Also zumindest nicht explizit.
Ganz von dem
Services abgesehen, was bei
Locator nix im gleichen
Finally-Abschnitt zu suchen hat.
Nice
Try. :mrgreen:
P.S.: Aber guter Hinweis bzgl. der Komponente.
jaenicke - Mo 04.07.11 05:56
Stread hat folgendes geschrieben : |
Allerdings habe ich das Gefühl dass ich die Ergebnisse nur in Memos anzeigen lassen kann? |
Wie kommst du auf die Idee?
Der Parameter ist vom Typ TStrings, da kannst du auch einfach eine TStringList übergeben.
Narses - Mo 04.07.11 09:33
Moin!
BenBE hat folgendes geschrieben : |
Ich hab da mal paar Variablen markiert, die nicht finalisiert werden via Resourcen-Schutzblock... Also zumindest nicht explizit.
Ganz von dem Services abgesehen, was bei Locator nix im gleichen Finally-Abschnitt zu suchen hat.
Nice Try. |
Ach Benny, du weißt doch mittlerweile, dass du mich nur dann beeindrucken kannst, wenn du auch deinen Code-Vorschlag dazu abgegeben hättest... :roll: Aber so? Nice Try! :mrgreen: Meckern kann ich auch, besser machen ist gefragt. :P
cu
Narses
Delete - Mo 04.07.11 10:50
Und das hier:
Delphi-Quelltext
1: 2: 3:
| except Result := FALSE; end; |
ist auch nicht sehr schön. Ich kann dann zwar prüfen, ob der Aufruf funktioniert hat oder nicht, aber was nützt mir das, wenn ich nicht weiß, warum er fehlgeschlagen ist? Lass doch die Exception durch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| try QueryWMI(...); except on E: Exception do ShowMessage(E.Message); end; |
Weil so wie du das machst, kann dir der Kunde wirklich nur sagen: "Geht nicht." Dann wünsche ich viel Spaß bei der Fehlerdiagnose. :?
uall@ogc - Mo 04.07.11 23:16
@BenBE:
1) Warum sollten Interfaces explizit freigegeben werden? Delphi sorgt doch im Grunde dafür, dass am Ende IntfClear/FinalizeArray aufgerufen wird:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| type ITest = interface['{5733B32B-BB90-42AC-9DD3-A27E32DF13AA}'] procedure Execute; end; TTest = class(TInterfacedObject, ITest) constructor Create; procedure Execute; destructor Destroy; override; end;
constructor TTest.Create; begin inherited; writeln('Create'); end;
destructor TTest.Destroy; begin writeln('Destroy'); inherited; end;
procedure TTest.Execute; begin raise Exception.Create('adsad'); end;
procedure aha; var a, b: ITest; begin a := nil; b := nil; try a := TTest.Create; b := TTest.Create; a.Execute; except writeln('exception'); end; end;
begin ReportMemoryLeaksOnShutdown := True; try aha; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; ReadLn; end. |
2. Interfaces sind mit NIL initialisiert (sollte auch bei lokalen Variablen so sein) ansonsten würde die IntfClear Funktion nicht sauber funktionieren:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure aha; var a, b: ITest; begin asm lea eax, dword ptr [ebp-$4] inc dword ptr [eax] end;
a := nil; b := nil;
00405EB4 8B10 mov edx,[eax] 00405EB6 85D2 test edx,edx <<< explizit auf nil getestet 00405EB8 740E jz $00405ec8 00405EBA C70000000000 mov [eax],$00000000 00405EC0 50 push eax 00405EC1 52 push edx 00405EC2 8B02 mov eax,[edx] |
Demnach wäre der Code nichts anderes als:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| Servies := nil; Locator := CoSWbemLocator.Create; try Services := Locator.ConnectServer('', 'root\cimv2', '', '', '','', 0, NIL); finally Locator := nil; Services := nil; end;
Obj2 := nil; Obj1 := TObject.Create; try Obj2 := Locator.ConnectServer('', 'root\cimv2', '', '', '','', 0, NIL); finally FreeAndNil(Obj1); FreeAndNil(Obj2); end; |
Dies ist eine (meiner Meinung nach) uebeliche Methode um viele verschachtelte try/finallys zu vermeiden und somit "sauber"
@Luckie:
Das ist einfach eine Designansicht. Es ist durchaus sinnvoll eine Funktion zu schreiben die die Exceptions abfaengt und dann ggf. loggt. Dafuer hat die Funktion ja auch einen Boolean als Rueckgabewert. Entweder sie funktioniert oder eben nicht. Ausserhalb kann ja immer noch "if not QueryWMI(..) then ShowMessage('Fehler, blablub bitte log "C:\fehler.log an Administrator xyz schicken')" angezeigt werden, denn bei Fehlern mit irgendwelchen Write/Read Exception klicken die Benutzer gerne die Fehlermeldung weg und rufen dann an ohne diese kopiert zu haben und sagen nur xyz funktioniert nicht.
Ansonsten könnte man auch einfach eine Prozedure raus machen und immer Exceptions werfen wie in Java, hier wird eher der WinAPI-Ansatz gewaehlt (keine Exception mit Rueckgabewert und ggf. Abfrage ubeer etwas wie GetLastError, Log-Datei bzw. Erkennung eines Fehlers am Rueckgabewert)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!