Czytanie konfiguracji sprzętowej komputera + info o oprogramowaniu

0

Cześć,
napisałem jakiś czas temu aplikację webową do trzymania informacji o sprzęcie w firmie (konfiguracja sprzętowa, oprogramowanie). Komputerów jest jednak co raz więcej - na początku ręczne wpisywanie tych informacji miało prawo bytu, ale przy większej ilości - nie :)
Chciałbym więc ten proces trochę zautomatyzować - potrzebowałbym napisać aplikację, która będzie czytać konfigurację sprzętową komputera, oraz zainstalowane oprogramowanie, a następnie zapisywać to do txt.
Wiem, że takie rzeczy potrafi AIDA, czy Everest, jednak ja potrzebuje czegoś naprawdę lekkiego, coś w rodzaju skryptu, który będę mógł odpalać z dysku sieciowego, okresowo co jakiś czas. Później już czytanie danych z txt, csv lub czegoś innego przez aplikację i zapis do bazy to tylko formalność.
Potrzebuję wskazania kierunku, w jakim powinienem pójść i od czego zacząć :) może w czymś innym, nie w C++?

PS. wiem że są kombajny typu Spiceworks to zarządzania infrastrukturą IT w sieciach firmowych, ale na ten moment nie chcemy korzystać z tego typu rozwiązań.
Będę wdzięczny za rady.
pozdrawiam

3

zrob skrpyt w pythonie. Najpierw odczytuj dane pozniej wysylaj RESTem do swojej strony, niech ona odbiera i przetwarza. Nie ma sensu zadne txt / csv (mozesz to zrobic jezeli masz dostep do tej strony)

https://docs.python.org/3/library/platform.html
http://stackoverflow.com/questions/11322430/python-how-to-send-post-request

0

pozostaje ci WMI.
Masz tu trochę kodu (Delphi ale nie powinieneś mieć problemów z przeklikaniem tego na C) Właśnie piszę takie coś z tym, że oparte o centralny serwer i z webowym interfejsem, żeby mieć dane typu "czy jakiś program aktualnie działa" albo "od kiedy komp pracuje" + zdalne odpalanie programów czy wymuszanie restartu

 
unit Unit9;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,TlHelp32,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ActiveX, ComObj, Vcl.StdCtrls, IdBaseComponent, IdComponent, IdRawBase, IdRawClient, IdIcmpClient,
  AdvSysKeyboardHook;

type
  TForm9 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    IdIcmpClient1: TIdIcmpClient;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure GetWin32_NetworkConnectionInfo;
    procedure GetCIM_ProcessInfo;
    procedure GetWin32_ProcessInfo;
    procedure GetWin32_UserAccountInfo;
    procedure Button2Click(Sender: TObject);
    procedure IdIcmpClient1Reply(ASender: TComponent; const AReplyStatus: TReplyStatus);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form9: TForm9;

implementation

{$R *.dfm}



FUNCTION ProcessExists(nazwa :String):Boolean;
var
 uchwyt :THandle;
 proces :TProcessEntry32;
Begin
 Result:= False;
 uchwyt:= CreateToolHelp32SnapShot(TH32CS_SNAPALL,0);
 proces.dwSize:= SizeOf(Proces);
 if Integer(Process32First(uchwyt, proces)) <> 0 then
 repeat
   if nazwa = ExtractFileName(proces.szExeFile) then Result:= True;
 until Integer(Process32Next(uchwyt, proces)) = 0;
 CloseHandle(uchwyt);
End;

procedure TForm9.GetWin32_UserAccountInfo;
const
  WbemUser = '';
  WbemPassword = '';
  WbemComputer = 'localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator: OLEVariant;
  FWMIService: OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_UserAccount', 'WQL', wbemFlagForwardOnly);
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
      Memo1.Lines.add('===== Get user account info =====');
    Memo1.Lines.add(Format('AccountType           %d', [Integer(FWbemObject.AccountType)])); // Uint32
    Memo1.Lines.add(Format('Caption               %s', [String(FWbemObject.Caption)])); // String
    Memo1.Lines.add(Format('Description           %s', [String(FWbemObject.Description)])); // String
    Memo1.Lines.add(Format('Disabled              %s', [String(FWbemObject.Disabled)])); // Boolean
    Memo1.Lines.add(Format('Domain                %s', [String(FWbemObject.Domain)])); // String
    Memo1.Lines.add(Format('FullName              %s', [String(FWbemObject.FullName)])); // String
    Memo1.Lines.add(Format('LocalAccount          %s', [String(FWbemObject.LocalAccount)])); // Boolean
    Memo1.Lines.add(Format('Lockout               %s', [String(FWbemObject.Lockout)])); // Boolean
    Memo1.Lines.add(Format('Name                  %s', [String(FWbemObject.Name)])); // String
    Memo1.Lines.add(Format('PasswordChangeable    %s', [String(FWbemObject.PasswordChangeable)])); // Boolean
    Memo1.Lines.add(Format('PasswordExpires       %s', [String(FWbemObject.PasswordExpires)])); // Boolean
    Memo1.Lines.add(Format('PasswordRequired      %s', [String(FWbemObject.PasswordRequired)])); // Boolean
    Memo1.Lines.add(Format('SIDType               %d', [Integer(FWbemObject.SIDType)])); // Uint8
    Memo1.Lines.add(Format('Status                %s', [String(FWbemObject.Status)])); // String


    FWbemObject := Unassigned;
  end;
end;

procedure TForm9.IdIcmpClient1Reply(ASender: TComponent; const AReplyStatus: TReplyStatus);
var
  Time: string;
  k, w: Integer;
begin
  if (AReplyStatus.MsRoundTripTime = 0) then Time := '<1'
  else Time := '=';

  if AReplyStatus.BytesReceived = 0 then
  begin
    Memo1.Lines.add('host nie istnieje');
    k := w + 1;
  end;

  if (AReplyStatus.MsRoundTripTime > 1000) then

  begin
    Memo1.Lines.add(IdIcmpClient1.Host + ' - adres nie odpowiada ');
  end;

  if (AReplyStatus.MsRoundTripTime < 1000) and (AReplyStatus.BytesReceived <> 0) then
  begin

    Memo1.Lines.add(Format('Odpowiedź z hosta: ' + IdIcmpClient1.Host + ' ,IP: %s : bajtów=%d Czas%s%dms  TTL=%d ', [AReplyStatus.FromIpAddress, AReplyStatus.BytesReceived, Time,
      AReplyStatus.MsRoundTripTime, AReplyStatus.TimeToLive]));
    Memo1.Lines.add(AReplyStatus.FromIpAddress);

  end;
end;

procedure TForm9.GetWin32_ProcessInfo;
const
  WbemUser = '';
  WbemPassword = '';
  WbemComputer = 'localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator: OLEVariant;
  FWMIService: OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_Process', 'WQL', wbemFlagForwardOnly);
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
      Memo1.Lines.add('===== Get Win32 process info =====');
    Memo1.Lines.add(Format('Caption                       %s', [String(FWbemObject.Caption)])); // String
    Memo1.Lines.add(Format('CSCreationClassName           %s', [String(FWbemObject.CSCreationClassName)])); // String
    Memo1.Lines.add(Format('CSName                        %s', [String(FWbemObject.CSName)])); // String
    Memo1.Lines.add(Format('Description                   %s', [String(FWbemObject.Description)])); // String
    Memo1.Lines.add(Format('Handle                        %s', [String(FWbemObject.Handle)])); // String
    Memo1.Lines.add(Format('HandleCount                   %d', [Integer(FWbemObject.HandleCount)])); // Uint32
    Memo1.Lines.add(Format('Name                          %s', [String(FWbemObject.Name)])); // String
    Memo1.Lines.add(Format('OSCreationClassName           %s', [String(FWbemObject.OSCreationClassName)])); // String
    Memo1.Lines.add(Format('OSName                        %s', [String(FWbemObject.OSName)])); // String
    Memo1.Lines.add(Format('OtherOperationCount           %d', [Integer(FWbemObject.OtherOperationCount)])); // Uint64
    Memo1.Lines.add(Format('OtherTransferCount            %d', [Integer(FWbemObject.OtherTransferCount)])); // Uint64
    Memo1.Lines.add(Format('PageFaults                    %d', [Integer(FWbemObject.PageFaults)])); // Uint32
    Memo1.Lines.add(Format('PageFileUsage                 %d', [Integer(FWbemObject.PageFileUsage)])); // Uint32
    Memo1.Lines.add(Format('ParentProcessId               %d', [Integer(FWbemObject.ParentProcessId)])); // Uint32
    Memo1.Lines.add(Format('PeakPageFileUsage             %d', [Integer(FWbemObject.PeakPageFileUsage)])); // Uint32
    Memo1.Lines.add(Format('PeakVirtualSize               %d', [Integer(FWbemObject.PeakVirtualSize)])); // Uint64
    Memo1.Lines.add(Format('PeakWorkingSetSize            %d', [Integer(FWbemObject.PeakWorkingSetSize)])); // Uint32
    Memo1.Lines.add(Format('Priority                      %d', [Integer(FWbemObject.Priority)])); // Uint32
    Memo1.Lines.add(Format('PrivatePageCount              %d', [Integer(FWbemObject.PrivatePageCount)])); // Uint64
    Memo1.Lines.add(Format('ProcessId                     %d', [Integer(FWbemObject.ProcessId)])); // Uint32
    Memo1.Lines.add(Format('QuotaNonPagedPoolUsage        %d', [Integer(FWbemObject.QuotaNonPagedPoolUsage)])); // Uint32
    Memo1.Lines.add(Format('QuotaPagedPoolUsage           %d', [Integer(FWbemObject.QuotaPagedPoolUsage)])); // Uint32
    Memo1.Lines.add(Format('QuotaPeakNonPagedPoolUsage    %d', [Integer(FWbemObject.QuotaPeakNonPagedPoolUsage)])); // Uint32
    Memo1.Lines.add(Format('QuotaPeakPagedPoolUsage       %d', [Integer(FWbemObject.QuotaPeakPagedPoolUsage)])); // Uint32
    Memo1.Lines.add(Format('ReadOperationCount            %d', [Integer(FWbemObject.ReadOperationCount)])); // Uint64
    Memo1.Lines.add(Format('SessionId                     %d', [Integer(FWbemObject.SessionId)])); // Uint32
    Memo1.Lines.add(Format('ThreadCount                   %d', [Integer(FWbemObject.ThreadCount)])); // Uint32
    Memo1.Lines.add(Format('VirtualSize                   %d', [Integer(FWbemObject.VirtualSize)])); // Uint64
    Memo1.Lines.add(Format('WindowsVersion                %s', [String(FWbemObject.WindowsVersion)])); // String
    Memo1.Lines.add(Format('WorkingSetSize                %d', [Integer(FWbemObject.WorkingSetSize)])); // Uint64
    Memo1.Lines.add(Format('WriteOperationCount           %d', [Integer(FWbemObject.WriteOperationCount)])); // Uint64


    FWbemObject := Unassigned;
  end;
end;

procedure TForm9.Button2Click(Sender: TObject);
begin
  try
    IdIcmpClient1.Host := '192.168.2.217';
  //  IdIcmpClient1.Send('1234567'); // 7
 //   IdIcmpClient1.Send('12345678911111'); // 14
    IdIcmpClient1.Ping('1234567890');
  //  IdIcmpClient1.Ping;
  except
    on e: exception do Memo1.Lines.add(e.Message);
  end;
end;

procedure TForm9.Button3Click(Sender: TObject);
begin
  if ProcessExists('notepad.exe') then
memo1.Lines.add('notepad.exe - Jest!')
else
memo1.Lines.add('notepad.exe - Nie ma!');
end;



procedure TForm9.Button4Click(Sender: TObject);
//posyła do notatnika (a właściwie dopisuje ciąg znaków "hello" +  wciska enter     + spację
var
  wnd: HWND;
  i: Integer;
  s: string;
begin
  wnd := FindWindow('notepad', nil);
  if wnd <> 0 then
  begin
    wnd := FindWindowEx(wnd, 0, 'Edit', nil);
    s := 'Hello';
    for i := 1 to Length(s) do
    SendMessage(wnd, WM_CHAR, Word(s[i]), 0);
    PostMessage(wnd, WM_KEYDOWN, VK_RETURN, 0);
    PostMessage(wnd, WM_KEYDOWN, VK_SPACE, 0);    //spacja
  end;

end;

procedure TForm9.GetCIM_ProcessInfo;
const
  WbemUser = '';
  WbemPassword = '';
  WbemComputer = 'localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator: OLEVariant;
  FWMIService: OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM CIM_Process', 'WQL', wbemFlagForwardOnly);
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
     Memo1.Lines.add('===== Get CIM process info =====');
    Memo1.Lines.add(Format('Caption                %s', [String(FWbemObject.Caption)])); // String
    Memo1.Lines.add(Format('CSCreationClassName    %s', [String(FWbemObject.CSCreationClassName)])); // String
    Memo1.Lines.add(Format('CSName                 %s', [String(FWbemObject.CSName)])); // String
    Memo1.Lines.add(Format('Description            %s', [String(FWbemObject.Description)])); // String
    Memo1.Lines.add(Format('Handle                 %s', [String(FWbemObject.Handle)])); // String
    Memo1.Lines.add(Format('Name                   %s', [String(FWbemObject.Name)])); // String
    Memo1.Lines.add(Format('OSCreationClassName    %s', [String(FWbemObject.OSCreationClassName)])); // String
    Memo1.Lines.add(Format('OSName                 %s', [String(FWbemObject.OSName)])); // String
    Memo1.Lines.add(Format('Priority               %d', [Integer(FWbemObject.Priority)])); // Uint32
    Memo1.Lines.add(Format('WorkingSetSize         %d', [Integer(FWbemObject.WorkingSetSize)])); // Uint64


    FWbemObject := Unassigned;
  end;
end;

procedure TForm9.GetWin32_NetworkConnectionInfo;
const
  WbemUser = '';
  WbemPassword = '';
  WbemComputer = 'localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator: OLEVariant;
  FWMIService: OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_NetworkConnection', 'WQL', wbemFlagForwardOnly);
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant;

  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
        Memo1.Lines.add('===== Get Network drives =====');
    Memo1.Lines.add(Format('AccessMask         %d', [Integer(FWbemObject.AccessMask)])); // Uint32
    Memo1.Lines.add(Format('Caption            %s', [String(FWbemObject.Caption)])); // String
    Memo1.Lines.add(Format('Comment            %s', [String(FWbemObject.Comment)])); // String
    Memo1.Lines.add(Format('ConnectionState    %s', [String(FWbemObject.ConnectionState)])); // String
    Memo1.Lines.add(Format('ConnectionType     %s', [String(FWbemObject.ConnectionType)])); // String
    Memo1.Lines.add(Format('Description        %s', [String(FWbemObject.Description)])); // String
    Memo1.Lines.add(Format('DisplayType        %s', [String(FWbemObject.DisplayType)])); // String
    Memo1.Lines.add(Format('LocalName          %s', [String(FWbemObject.LocalName)])); // String
    Memo1.Lines.add(Format('Name               %s', [String(FWbemObject.Name)])); // String
    Memo1.Lines.add(Format('Persistent         %s', [String(FWbemObject.Persistent)])); // Boolean
    Memo1.Lines.add(Format('ProviderName       %s', [String(FWbemObject.ProviderName)])); // String
    Memo1.Lines.add(Format('RemoteName         %s', [String(FWbemObject.RemoteName)])); // String
    Memo1.Lines.add(Format('RemotePath         %s', [String(FWbemObject.RemotePath)])); // String
    Memo1.Lines.add(Format('ResourceType       %s', [String(FWbemObject.ResourceType)])); // String
    Memo1.Lines.add(Format('Status             %s', [String(FWbemObject.Status)])); // String
    Memo1.Lines.add(Format('UserName           %s', [String(FWbemObject.UserName)])); // String

    // Writeln('');
    FWbemObject := Unassigned;
  end;
end;

procedure TForm9.Button1Click(Sender: TObject);
begin
  // 888
  try
  GetWin32_NetworkConnectionInfo;
  GetCIM_ProcessInfo;
  GetWin32_ProcessInfo;
  GetWin32_UserAccountInfo;
  except
  on e:exception do
  memo1.Lines.Add('jakiś błąd');
  end;

end;

end.
0

Panowie, wielkie dzięki za odpowiedzi.
Poszedłem jeszcze inną drogą, skrypty VBS (korzystające z info z WMI) i dodawanie za ich pomocą informacji bezpośrednio do bazy danych MySql.
Aplikacja webowa będzie służyć głównie do wyświetlania informacji o sprzęcie + oczywiście edycja, wstawianie dodatkowych danych.

Skrypty będą odpalane okresowo, w celu sprawdzenia czy zaszły jakieś zmiany itd.

1 użytkowników online, w tym zalogowanych: 0, gości: 1