How to find available parallel ports and their I/O addresses using Delphi and WMI
I see that WMI is v开发者_开发知识库ery powerful and seems to be able to return most properties of a PC hardware. I'd like to display the available parallel ports on any PC and find their I/O addresses - I know that normally this is done using a Kernel driver but this is a legacy need - dont ask! Presently we look in Device Manager and then have to type in the address displayed there. I'd like to use WMI to find out this information. There are an excellent set of WMI classes at 1 but I cannot see how to iterate.
Thanks.
One must experiment to extract a complex information from WMI. I have tried to find the parallel port addresses on my PC and that is the report:
First of all I have queried Win32_ParallelPort class to find all parallel ports. (using the same code as PRUZ in his post before): 'Select * From Win32_ParallelPort'. The result is (I have only one parallel port in my system):
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";
};
Second, I have queried Win32_PNPAllocatedResource ('Select * From Win32_PnPAllocatedResource'). I have got a lot of information here, but I have selected only the 3 entries by 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\"";
};
The third entry is of no interest. The first two entries gives us two (decimal) starting addresses (888 and 1912)
Finally I have queried Win32_PortResource ('Select * From Win32_PortResource') to find the ending addresses corresponding to the starting addresses 888 and 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";
};
Updated
I have used the same code as RRUZ, in GUI application (see below). The only thing you need to compile it is the WbemScripting_TLB.pas unit. The unit is generated by type library import wizard, you can read about the process 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.
May be this will help you :
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;
I do not understand what are the values you need.
If you need to know this:
alt text http://img682.imageshack.us/img682/2382/imagen333.png
I think you can find it in Win32_PortResource classes and Win32_portConnector
Can you confirm that this is so?
Make a test; Open a CMD windows and type:
> WMIC PORT List FULL
alt text http://img215.imageshack.us/img215/1696/imagen332.png
If this is the value that you are searching, you can develop a new component in GLibWMI (or say to me for help you) that retrieve this values.
Regards.
PD: Excuseme for the mistakes with english.
@Brian , you just use the Win32_parallelPort class to get the info .
check this code.
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.
精彩评论