2010-03-05 8 views
5

Vedo che WMI è molto potente e sembra essere in grado di restituire la maggior parte delle proprietà dell'hardware di un PC. Mi piacerebbe visualizzare le porte parallele disponibili su qualsiasi PC e trovare i loro indirizzi I/O - So che normalmente questo viene fatto usando un driver Kernel ma questa è una necessità legacy - non chiedere! Attualmente guardiamo in Gestione periferiche e quindi dobbiamo digitare l'indirizzo visualizzato lì. Mi piacerebbe usare WMI per scoprire queste informazioni. C'è un eccellente set di classi WMI su 1 ma non riesco a vedere come iterare.Come trovare le porte parallele disponibili e i relativi indirizzi I/O usando Delphi e WMI

Grazie.

risposta

2

Bisogna sperimentare per estrarre un'informazione complessa da WMI. Ho cercato di trovare gli indirizzi delle porte parallele sul mio PC e questo è il rapporto:

Prima di tutto ho interrogato la classe Win32_ParallelPort per trovare tutte le porte parallele. (utilizzando lo stesso codice di PRUZ nel suo post precedente): 'Seleziona * Da Win32_ParallelPort'. Il risultato è (ho solo una porta parallela nel mio sistema):

instance of Win32_ParallelPort 
{ 
    Availability = 3; 
    Caption = "LPT1"; 
    ConfigManagerErrorCode = 0; 
    ConfigManagerUserConfig = FALSE; 
    CreationClassName = "Win32_ParallelPort"; 
    Description = "LPT1"; 
    DeviceID = "LPT1"; 
    Name = "LPT1"; 
    OSAutoDiscovered = TRUE; 
    PNPDeviceID = "ACPI\\PNP0401\\4&25C6B52A&0"; 
    PowerManagementSupported = FALSE; 
    ProtocolSupported = 17; 
    SystemCreationClassName = "Win32_ComputerSystem"; 
    SystemName = "JUPITER"; 
}; 

In secondo luogo, ho interrogato Win32_PNPAllocatedResource ('Select * From Win32_PnPAllocatedResource'). Ho un sacco di informazioni qui, ma ho selezionato solo le 3 voci di PNPDeviceID = "ACPI \ PNP0401 \ 4 & 25C6B52A & 0".

instance of Win32_PNPAllocatedResource 
{ 
    Antecedent = "\\\\JUPITER\\root\\cimv2:Win32_PortResource.StartingAddress=\"888\""; 
    Dependent = "\\\\JUPITER\\root\\cimv2:Win32_PnPEntity.DeviceID=\"ACPI\\\\PNP0401\\\\4&25C6B52A&0\""; 
}; 


instance of Win32_PNPAllocatedResource 
{ 
    Antecedent = "\\\\JUPITER\\root\\cimv2:Win32_PortResource.StartingAddress=\"1912\""; 
    Dependent = "\\\\JUPITER\\root\\cimv2:Win32_PnPEntity.DeviceID=\"ACPI\\\\PNP0401\\\\4&25C6B52A&0\""; 
}; 


instance of Win32_PNPAllocatedResource 
{ 
    Antecedent = "\\\\JUPITER\\root\\cimv2:Win32_DMAChannel.DMAChannel=3"; 
    Dependent = "\\\\JUPITER\\root\\cimv2:Win32_PnPEntity.DeviceID=\"ACPI\\\\PNP0401\\\\4&25C6B52A&0\""; 
}; 

La terza voce non è di interesse. Le prime due voci ci dà due (decimali) a partire indirizzi (888 e 1912)

Infine ho interrogato Win32_PortResource ('Select * From Win32_PortResource') per trovare gli indirizzi che terminano corrispondenti agli indirizzi di partenza 888 e il 1912:

instance of Win32_PortResource 
{ 
    Alias = FALSE; 
    Caption = "0x00000378-0x0000037F"; 
    CreationClassName = "Win32_PortResource"; 
    CSCreationClassName = "Win32_ComputerSystem"; 
    CSName = "JUPITER"; 
    Description = "0x00000378-0x0000037F"; 
    EndingAddress = "895"; 
    Name = "0x00000378-0x0000037F"; 
    StartingAddress = "888"; 
    Status = "OK"; 
}; 


instance of Win32_PortResource 
{ 
    Alias = FALSE; 
    Caption = "0x00000778-0x0000077B"; 
    CreationClassName = "Win32_PortResource"; 
    CSCreationClassName = "Win32_ComputerSystem"; 
    CSName = "JUPITER"; 
    Description = "0x00000778-0x0000077B"; 
    EndingAddress = "1915"; 
    Name = "0x00000778-0x0000077B"; 
    StartingAddress = "1912"; 
    Status = "OK"; 
}; 

Aggiornato

ho usato lo stesso codice RRUZ, in applicazione GUI (vedi sotto). L'unica cosa che devi compilare è l'unità WbemScripting_TLB.pas. L'unità è generata dalla procedura guidata di importazione libreria dei tipi, si può leggere sul processo in Delphi 2009 in my blog

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TForm1 = class(TForm) 
    Memo1: TMemo; 
    Button4: TButton; 
    Button5: TButton; 
    Button6: TButton; 
    procedure Button4Click(Sender: TObject); 
    procedure Button5Click(Sender: TObject); 
    procedure Button6Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

uses WbemScripting_TLB, ActiveX; 


{$R *.dfm} 


procedure TForm1.Button4Click(Sender: TObject); 
var 
    WMIServices : ISWbemServices; 
    WMILocator : ISWbemLocator; 
    Root   : ISWbemObjectSet; 
    SWbemObject : ISWbemObject; 
    Item   : IEnumVariant; 
    rgVar  : OleVariant; 
    pCelFetched : Cardinal; 

begin 
    Memo1.Lines.Clear; 
    WMILocator := CoSWbemLocator.Create(); 
    WMIServices := WMILocator.ConnectServer('.', 'root\cimv2','', '', '', '', 0, nil); // 
    Root := WMIServices.ExecQuery('Select * From Win32_PnPAllocatedResource','WQL', 0, nil); 
    Item := (Root._NewEnum) as IEnumVariant; 
    while (Item.Next(1, rgVar, pCelFetched) = S_OK) do 
    begin 
    SWbemObject := IUnknown(rgVar) as ISWBemObject; 
    if (SWbemObject <> nil) then 
    begin 
     SWbemObject.Properties_;//Load the Properties to read 
     Memo1.Lines.Add(SWbemObject.GetObjectText_(0)); 
    end; 
    end; 
end; 

procedure TForm1.Button5Click(Sender: TObject); 
var 
    WMIServices : ISWbemServices; 
    WMILocator : ISWbemLocator; 
    Root   : ISWbemObjectSet; 
    SWbemObject : ISWbemObject; 
    Item   : IEnumVariant; 
    rgVar  : OleVariant; 
    pCelFetched : Cardinal; 

begin 
    Memo1.Lines.Clear; 
    WMILocator := CoSWbemLocator.Create(); 
    WMIServices := WMILocator.ConnectServer('.', 'root\cimv2','', '', '', '', 0, nil); // 
    Root := WMIServices.ExecQuery('Select * From Win32_PortResource','WQL', 0, nil); 
    Item := (Root._NewEnum) as IEnumVariant; 
    while (Item.Next(1, rgVar, pCelFetched) = S_OK) do 
    begin 
    SWbemObject := IUnknown(rgVar) as ISWBemObject; 
    if (SWbemObject <> nil) then 
    begin 
     SWbemObject.Properties_;//Load the Properties to read 
     Memo1.Lines.Add(SWbemObject.GetObjectText_(0)); 
    end; 
    end; 
end; 

procedure TForm1.Button6Click(Sender: TObject); 
var 
    WMIServices : ISWbemServices; 
    WMILocator : ISWbemLocator; 
    Root   : ISWbemObjectSet; 
    SWbemObject : ISWbemObject; 
    Item   : IEnumVariant; 
    rgVar  : OleVariant; 
    pCelFetched : Cardinal; 

begin 
    Memo1.Lines.Clear; 
    WMILocator := CoSWbemLocator.Create(); 
    WMIServices := WMILocator.ConnectServer('.', 'root\cimv2','', '', '', '', 0, nil); // 
    Root := WMIServices.ExecQuery('Select * From Win32_ParallelPort','WQL', 0, nil); 
    Item := (Root._NewEnum) as IEnumVariant; 
    while (Item.Next(1, rgVar, pCelFetched) = S_OK) do 
    begin 
    SWbemObject := IUnknown(rgVar) as ISWBemObject; 
    if (SWbemObject <> nil) then 
    begin 
     SWbemObject.Properties_;//Load the Properties to read 
     Memo1.Lines.Add(SWbemObject.GetObjectText_(0)); 
    end; 
    end; 
end; 

end. 
+0

Questo sembra promettente Serg - gli indirizzi sono il mio obiettivo - qualche possibilità di un codice Delphi approssimativo? Grazie Brian. –

+0

@Serg: Great - I'll experient. Grazie. Brian. –

+0

@Serg: Funziona alla grande, molte grazie - esattamente quello di cui avevo bisogno per iniziare. –

1

Può essere questo vi aiuterà a:

uses ComObj, ActiveX; 

function TForm1.GetObject(const objectName: String): IDispatch; 
var 
    bindCtx: IBindCtx; 
    moniker: IMoniker; 
    chEaten: Integer; 
begin 
    OleCheck(CreateBindCtx(0, bindCtx)); 
    OleCheck(MkParseDisplayName(bindCtx, StringToOleStr(objectName), chEaten, moniker)); 
    OleCheck(moniker.BindToObject(bindCtx, nil, IDispatch, Result)); 
end; 
procedure TForm1.Button1Click(Sender: TObject); 
var 
    objWMIService: OLEVariant; 
    colItems, colItem: OLEVariant; 
    oEnum : IEnumvariant; 
    iValue, test : longword; 
begin 
    objWMIService := GetObject('winmgmts:\\YourPCname\root\CIMV2'); 
    colItems := objWMIService.ExecQuery('SELECT * FROM Win32_ParallelPort',,48); 
    oEnum := IUnknown(colItems._NewEnum) as IEnumVariant; 
    while oEnum.Next(1, colItem, iValue) = 0 do begin 
    //You can get all the properties here 
    //for example colItem.Caption 
    // properties of Win32_ParalelPort class : http://msdn.microsoft.com/en-us/library/aa394247%28VS.85%29.aspx 
    end; 
end; 
1

@ Brian, è sufficiente utilizzare la classe Win32_parallelPort per avere le informazioni.

controllare questo codice.

program GetWMI_ParallelPortInfo; 

{$APPTYPE CONSOLE} 

uses 
    Windows, 
    Classes, 
    ActiveX, 
    Variants, 
    SysUtils, 
    WbemScripting_TLB in '..\..\Documents\RAD Studio\5.0\Imports\WbemScripting_TLB.pas'; 

procedure GetWMIParallelPortInfo; 
var 
    WMIServices : ISWbemServices; 
    WMILocator : ISWbemLocator; 
    Root   : ISWbemObjectSet; 
    SWbemObject : ISWbemObject; 
    Item   : IEnumVariant; 
    rgVar  : OleVariant; 
    pCelFetched : Cardinal; 

begin 
    WMILocator := CoSWbemLocator.Create(); 
    WMIServices := WMILocator.ConnectServer('.', 'root\cimv2','', '', '', '', 0, nil); // 
    Root := WMIServices.ExecQuery('Select * From Win32_ParallelPort','WQL', 0, nil); 
    Item := (Root._NewEnum) as IEnumVariant; 
    while (Item.Next(1, rgVar, pCelFetched) = S_OK) do 
    begin 
    SWbemObject := IUnknown(rgVar) as ISWBemObject; 
    if (SWbemObject <> nil) then 
    begin 
     SWbemObject.Properties_;//Load the Properties to read 
     Writeln(SWbemObject.GetObjectText_(0));//The GetObjectText_ method of the SWbemObject object returns a textual rendering of the object in MOF format 
    end; 
    end; 
end; 

begin 
try 
    CoInitialize(nil); 
    try 
     GetWMIParallelPortInfo; 
     Readln; 
    finally 
     CoUninitialize; 
    end; 
except 
    on E:Exception do 
    Begin 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    End; 
    end; 
end. 

alt text http://i48.tinypic.com/2e67wxz.png

+0

@RRUZ Grazie, il codice mi dà un inizio. Come faccio a trovare il parametro "StartAddress" per favore? Brian. –

+0

@RRUZ: Grazie per i suggerimenti - ora risolto. –

1

Non capisco quali sono i valori necessari.
Se avete bisogno di sapere questo:

alt text http://img682.imageshack.us/img682/2382/imagen333.png

Penso che si può trovare in Win32_PortResource classi e Win32_portConnector

Può confermare che è così?
Effettuare un test; Aprire una finestra CMD e digitate:
> WMIC PORT elenco completo

alt text http://img215.imageshack.us/img215/1696/imagen332.png

Se questo è il valore che si sta cercando, è possibile sviluppare un new component in GLibWMI (o dire per me per un aiuto voi) che recuperare questi valori.

Saluti.

PD: Excuseme per gli errori con l'inglese.

+0

Sì! Questo è esattamente quello che vorrei. Non capisco come mostrare le informazioni, e un problema comune è quando ci sono due porte parallele, ho bisogno di sapere le informazioni per entrambi, non solo per il primo. Spero di non essere confuso. Il tuo inglese va bene! Brian. –