Как найти доступные параллельные порты и их адреса ввода / вывода, используя Delphi и WMI - PullRequest
5 голосов
/ 05 марта 2010

Я вижу, что WMI очень мощный и, похоже, способен вернуть большинство свойств аппаратного обеспечения ПК. Я хотел бы отобразить доступные параллельные порты на любом ПК и найти их адреса ввода / вывода - я знаю, что обычно это делается с помощью драйвера ядра, но это устаревшая необходимость - не спрашивайте! В настоящее время мы смотрим в диспетчере устройств, а затем должны ввести адрес, отображаемый там. Я хотел бы использовать WMI, чтобы узнать эту информацию. Существует отличный набор классов WMI на 1 , но я не вижу, как выполнить итерацию.

Спасибо.

Ответы [ 4 ]

2 голосов
/ 05 марта 2010

Нужно экспериментировать, чтобы извлечь сложную информацию из WMI.Я попытался найти адреса параллельных портов на моем ПК, и вот отчет:

Прежде всего я запросил класс Win32_ParallelPort, чтобы найти все параллельные порты.(используя тот же код, что и PRUZ в своем посте ранее): «Выбрать * из Win32_ParallelPort».В результате (у меня только один параллельный порт в моей системе):

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";
};

Во-вторых, я запросил Win32_PNPAllocatedResource («Выбрать * из Win32_PnPAllocatedResource»).У меня много информации здесь, но я выбрал только 3 записи по 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\"";
};

Третья запись не представляет интереса.Первые две записи дают нам два (десятичных) начальных адреса (888 и 1912)

Наконец я запросил Win32_PortResource ('Select * From Win32_PortResource'), чтобы найти конечные адреса, соответствующие начальным адресам 888 и 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";
};

Обновлено

Я использовал тот же код, что и RRUZ, в приложении с графическим интерфейсом (см. Ниже).Единственное, что вам нужно для его компиляции - это модуль WbemScripting_TLB.pas.Модуль генерируется мастером импорта библиотеки типов, вы можете прочитать о процессе в Delphi 2009 в мой блог

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.
1 голос
/ 05 марта 2010

Я не понимаю, какие значения вам нужны.
Если вам нужно знать это:

альтернативный текст http://img682.imageshack.us/img682/2382/imagen333.png

Я думаю, вы можете найти его в Win32_PortResource классах и Win32_portConnector

Можете ли вы подтвердить, что это так?
Сделать тест; Откройте окна CMD и введите:
> Список портов WMIC ПОЛНЫЙ

альтернативный текст http://img215.imageshack.us/img215/1696/imagen332.png

Если это значение, которое вы ищете, вы можете разработать новый компонент в GLibWMI (или попросите меня помочь вам), чтобы получить эти значения.

С уважением.

PD: Извините за ошибки с английским.

1 голос
/ 05 марта 2010

@ Брайан, вы просто используете класс Win32_parallelPort для получения информации.

проверьте этот код.

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

1 голос
/ 05 марта 2010

Может быть, это вам поможет:

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;
...