【问题标题】:How to find available parallel ports and their I/O addresses using Delphi and WMI如何使用 Delphi 和 WMI 查找可用的并行端口及其 I/O 地址
【发布时间】:2010-03-05 10:58:45
【问题描述】:

我看到 WMI 非常强大,并且似乎能够返回 PC 硬件的大多数属性。我想在任何 PC 上显示可用的并行端口并找到它们的 I/O 地址——我知道通常这是使用内核驱动程序完成的,但这是一个遗留需求——不要问!目前我们在设备管理器中查看,然后必须输入那里显示的地址。我想使用 WMI 来查找此信息。 1 有一组出色的 WMI 类,但我看不到如何迭代。

谢谢。

【问题讨论】:

    标签: delphi wmi port parallel-processing


    【解决方案1】:

    必须尝试从 WMI 中提取复杂信息。我试图在我的 PC 上找到并行端口地址,这就是报告:

    首先,我查询了 Win32_ParallelPort 类以查找所有并行端口。 (在他之前的帖子中使用与 PRUZ 相同的代码):'Select * From 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('Select * From Win32_PnPAllocatedResource')。我这里有很多信息,但我只选择了 PNPDeviceID = "ACPI\PNP0401\4&25C6B52A&0" 的 3 个条目。

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

    更新

    我在 GUI 应用程序中使用了与 RRUZ 相同的代码(见下文)。唯一需要编译它的是 WbemScripting_TLB.pas 单元。该单元由类型库导入向导生成,您可以在my blog阅读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.
    

    【讨论】:

    • 这看起来很有希望 Serg - 地址是我的目标 - 是否有可能提供一些粗略的 Delphi 代码?谢谢布赖恩。
    • @Serg:太好了——我会体验的。谢谢。布赖恩。
    • @Serg:这很好用,非常感谢 - 正是我开始所需要的。
    【解决方案2】:

    也许这会对你有所帮助:

    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;
    

    【讨论】:

      【解决方案3】:

      我不明白您需要什么值。
      如果您需要知道这一点:

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

      我想你可以在 Win32_PortResource 类和 Win32_portConnector

      中找到它

      你能确认是这样吗?
      做一个测试;打开 CMD 窗口并输入:
      > WMIC PORT List FULL

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

      如果这是您正在搜索的值,您可以开发一个new component in GLibWMI(或向我寻求帮助)来检索此值。

      问候。

      PD:请原谅英语的错误。

      【讨论】:

      • 是的!这正是我想要的。我不明白如何显示信息,一个常见的问题是当有两个并行端口时,我需要知道两者的信息,而不仅仅是第一个。我希望我没有混淆。你的英语很好!布赖恩。
      【解决方案4】:

      @Brian,您只需使用 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.
      

      【讨论】:

      • @RRUZ 谢谢,代码给了我一个开始。请问如何找到“StartAddress”参数?布赖恩。
      猜你喜欢
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2019-11-01
      • 2012-04-23
      • 1970-01-01
      相关资源
      最近更新 更多