Jump to content
Mike Torrettinni

Library to get user, computer info

Recommended Posts

In my projects, I don't gather user identifiable info, even for licensing. Worked good so far, but now I have the need for different licensing style.

I have methods to get user name, computer name, some hardware info, local IP... for Windows. But I'm looking also for Linux version. Also identifying if VM is used or not.

 

So, looking for a library (linux would be a plus) that handles also cases like VM, RDP, Citrix, roaming user profile management... and other network particulars that can give odd results with basic methods.

 

Any suggestions?

Share this post


Link to post

You can get any info with WMI support.

WMI covers a very very incredible set of infos.

This is a sample that I use to recover some system info.

unit osSystemInfo;

interface

type
  TSystemInfoMode = ( simdCompact, simdFull );

  TMotherBoardInfo = ( mbiSerialNumber, mbiManufacturer, mbiProduct, mbiModel );
  TMotherBoardInfos = set of TMotherBoardInfo;

  TOSInfo = ( osiBuildNumber, osiBuildType, osiManufacturer, osiName, osiSerialNumber, osiVersion );
  TOSInfos = set of TOSInfo;

  TProcessorInfo = ( priDescription, priManufacturer, priName, priProcessorId, priUniqueId, priSystemName );
  TProcessorInfos = set of TProcessorInfo;

type
  TSystemInfo = class
  private
    FBuffer: AnsiString;
    FMotherBoardInfos: TMotherBoardInfos;
    FNeedUninitialize: Boolean;
    FOSInfos: TOSInfos;
    FProcessorInfos: TProcessorInfos;
  private
    procedure Clear;
  public
    function GenerateInfo(Mode: TSystemInfoMode = simdCompact): Boolean;
  public
    property Buffer: AnsiString read FBuffer;
    property MotherBoardInfos: TMotherBoardInfos read FMotherBoardInfos write FMotherBoardInfos;
    property OSInfos: TOSInfos read FOSInfos write FOSInfos;
    property ProcessorInfos: TProcessorInfos read FProcessorInfos write FProcessorInfos;
  public
    constructor Create;
    destructor Destroy; override;
  end;

implementation

uses
  ComObj,
  ActiveX,
  SysUtils,
  Variants,

  osExceptionUtils;

var
  MotherBoardInfoText: array[TMotherBoardInfo] of AnsiString = ( 'SerialNumber', 'Manufacturer', 'Product', 'Model' );
  OSInfoText: array [TOSInfo] of AnsiString = ( 'BuildNumber', 'BuildType', 'Manufacturer', 'Name', 'SerialNumber', 'Version' );
  ProcessorInfoText: array [TProcessorInfo] of AnsiString = ( 'Description', 'Manufacturer', 'Name', 'ProcessorId', 'UniqueId', 'SystemName' );

procedure TSystemInfo.Clear;
begin
  FBuffer := '';
end;

constructor TSystemInfo.Create;
begin
  inherited;

  FBuffer := '';
  FMotherBoardInfos := [];
  FNeedUninitialize := False;
  FOSInfos :=  [];
  FProcessorInfos := [];

  FNeedUninitialize := CoInitialize(nil) = S_OK;
end;

destructor TSystemInfo.Destroy;
begin
  if FNeedUninitialize then
    CoUninitialize;

  inherited;
end;

function TSystemInfo.GenerateInfo(Mode: TSystemInfoMode): Boolean;
var
  S: AnsiString;
  OSInfo: TOSInfo;
  IValue: LongWord;
  OSInfos: TOSInfos;
  OEnum: IEnumvariant;
  OWmiObject: OLEVariant;
  ObjWMIService: OLEVariant;
  ObjSWbemLocator: OLEVariant;
  objWbemObjectSet: OLEVariant;
  ProcessorInfo: TProcessorInfo;
  ProcessorInfos: TProcessorInfos;
  MotherBoardInfo: TMotherBoardInfo;
  MotherBoardInfos: TMotherBoardInfos;

  function VarArrayToStr(const vArray: Variant): AnsiString;

    function _VarToStr(const V: Variant): AnsiString;
    var
      Vt: Integer;
    begin
      Vt := VarType(V);
      case Vt of
        varSmallint,
        varInteger  : Result := AnsiString(IntToStr(Integer(V)));
        varSingle,
        varDouble,
        varCurrency : Result := AnsiString(FloatToStr(Double(V)));
        varDate     : Result := AnsiString(VarToStr(V));
        varOleStr   : Result := AnsiString(WideString(V));
        varBoolean  : Result := AnsiString(VarToStr(V));
        varVariant  : Result := AnsiString(VarToStr(Variant(V)));
        varByte     : Result := AnsiChar(Byte(V));
        varString   : Result := AnsiString(V);
        varArray    : Result := VarArrayToStr(Variant(V));
      end;
    end;

  var
    I: Integer;
  begin
    Result := '[';
    if (VarType(vArray) and VarArray) = 0 then
       Result := _VarToStr(vArray)
    else
    begin
      for I := VarArrayLowBound(vArray, 1) to VarArrayHighBound(vArray, 1) do
      begin
        if I = VarArrayLowBound(vArray, 1) then
          Result := Result + _VarToStr(vArray[I])
        else
          Result := Result + '|' + _VarToStr(vArray[I]);
      end;
    end;
    Result:=Result + ']';
  end;

  function VarStrNull(const V: OleVariant): AnsiString;
  begin
    Result := '';
    if not VarIsNull(V) then
    begin
      if VarIsArray(V) then
         Result := VarArrayToStr(V)
      else
      Result := AnsiString(VarToStr(V));
    end;
  end;

begin
  Clear;
  try
    ObjSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    if VarIsNull(ObjSWbemLocator) then AbortFast;
    ObjWMIService := objSWbemLocator.ConnectServer('localhost','root\cimv2', '','');
    if VarIsNull(ObjWMIService) then AbortFast;

    if FMotherBoardInfos <> [] then
    begin
      MotherBoardInfos := FMotherBoardInfos;
      ObjWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_BaseBoard', 'WQL', 0);
      OEnum := IUnknown(ObjWbemObjectSet._NewEnum) as IEnumVariant;
      while OEnum.Next(1, OWmiObject, IValue) = 0 do
      begin
        if MotherBoardInfos = [] then Break;
        for MotherBoardInfo := Low(TMotherBoardInfo) to High(TMotherBoardInfo) do
        begin
          if MotherBoardInfo in FMotherBoardInfos then
          begin
            S := VarStrNull(OWmiObject.Properties_.Item(MotherBoardInfoText[MotherBoardInfo]).Value);
            Exclude(MotherBoardInfos, MotherBoardInfo);
            case Mode of
              simdCompact:
                FBuffer := FBuffer + S;
              simdFull:
                FBuffer := FBuffer + MotherBoardInfoText[MotherBoardInfo] + ' = ' + S + #13#10;
            end;
          end;
        end;
        OWmiObject := Unassigned;
      end;
    end;

    if FOSInfos <> [] then
    begin
      OSInfos := FOSInfos;
      ObjWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_OperatingSystem', 'WQL', 0);
      OEnum := IUnknown(ObjWbemObjectSet._NewEnum) as IEnumVariant;
      while OEnum.Next(1, OWmiObject, IValue) = 0 do
      begin
        if OSInfos = [] then Break;
        for OSInfo := Low(TOSInfo) to High(TOSInfo) do
        begin
          if OSInfo in OSInfos then
          begin
            S := VarStrNull(OWmiObject.Properties_.Item(OSInfoText[OSInfo]).Value);
            Exclude(OSInfos, OSInfo);
            case Mode of
              simdCompact:
                FBuffer := FBuffer + S;
              simdFull:
                FBuffer := FBuffer + OSInfoText[OSInfo] + ' = ' + S + #13#10;
            end;
          end;
        end;
        OWmiObject := Unassigned;
      end;
    end;

    if FProcessorInfos <> [] then
    begin
      ProcessorInfos := FProcessorInfos;
      ObjWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_Processor', 'WQL', 0);
      OEnum := IUnknown(ObjWbemObjectSet._NewEnum) as IEnumVariant;
      while OEnum.Next(1, OWmiObject, IValue) = 0 do
      begin
        if ProcessorInfos = [] then Break;
        for ProcessorInfo := Low(TProcessorInfo) to High(TProcessorInfo) do
        begin
          if ProcessorInfo in ProcessorInfos then
          begin
            S := VarStrNull(OWmiObject.Properties_.Item(ProcessorInfoText[ProcessorInfo]).Value);
            Exclude(ProcessorInfos, ProcessorInfo);
            case Mode of
              simdCompact:
                FBuffer := FBuffer + S;
              simdFull:
                FBuffer := FBuffer + ProcessorInfoText[ProcessorInfo] + ' = ' + S + #13#10;
            end;
          end;
        end;
        OWmiObject := Unassigned;
      end;
    end;

    Result := True;
  except
    Clear;
    Result := False;
  end;
end;

end.

 

There is also a WMI Delphi Code Generator in which you can brose the interesting data and it creates code for you:
image.thumb.png.60d909171c1e081fd355d3e468e0aa77.png

 

https://github.com/RRUZ/wmi-delphi-code-creator

 

 

  • Like 1
  • Thanks 1

Share this post


Link to post
2 hours ago, shineworld said:

You can get any info with WMI support.

WMI covers a very very incredible set of infos.

Not such much on Linux 

  • Like 1

Share this post


Link to post
On 11/26/2021 at 9:35 AM, timfrost said:

For Windows, MiTeC System Information Component Suite can get every hardware and software detail you can think of, and more; there is also a trial version available. https://www.mitec.cz/msics.html

Thanks, it looks like it does cover a lot. And having available all the demos is quite refreshing. No Linux support is not a deal breaker, but it would be nice to have all in one.

 

On 11/26/2021 at 12:21 PM, shineworld said:

You can get any info with WMI support.

WMI covers a very very incredible set of infos.

Thanks, at this moment I'm looking for ready-made library (commercial) up to date and a Linux support is a plus.

 

There's plenty example available online for all sorts of system info, but I'm trying to avoid my own trial and error.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×