Windows Funktionen benutzen

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Antworten
vazili_Zaitzef
Beiträge: 43
Registriert: Do 6. Dez 2012, 21:55
OS, Lazarus, FPC: Win7 64 (L 1.6 FPC 3.0.0)
CPU-Target: 64Bit

Windows Funktionen benutzen

Beitrag von vazili_Zaitzef »

Hallo,

ich möchte mir ein kleines Programm schreiben, mit dem ich mir alle meine LAN Adapter auslesen kann und bearbeiten kann.
Hierzu habe ich mal gesucht und auch die Windows Funktionen gefunden (GetPerAdapterInfo,...etc.). 8)
Allerdings benötige ich hierzu die Iphlpapi Funktionen. Diese dachte ich würde mit der Uses Windows dabei sein. Dies ist allerdings nicht der Fall. :cry: (Die gleichnamige DLL ist im Windows Verzeichnis enthalten)

Was kann ich hier machen :?:

:) Ich würde mich über eure Hilfe sehr freuen. :)

Beste Grüße
Vazili

Socke
Lazarusforum e. V.
Beiträge: 2814
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Windows Funktionen benutzen

Beitrag von Socke »

Borland hatte seinerzeit alles Mögliche in die Windows-Unit hineingepackt. Hier findest du vor allem die "Standard"-Fuktionen, die jede Anwendung braucht. Für spezielle Funtionen solltest du die Jedi-Units (werden vom FPC mitgeliefert) durchsuchen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 8515
Registriert: Mo 11. Sep 2006, 19:01

Re: Windows Funktionen benutzen

Beitrag von theo »

Wenn du so etwas suchst, geht folgendes Vorgehen relativ schnell:

- Schreibe die gesuchte Fkt. einfach mal in den Code "GetPerAdapterInfo"
- Versuche zu kompilieren (grüner Pfeil o.ä.)
- Es erscheint im Meldungsfenster z.B.
unit1.pas(34,3) Error: Identifier not found "GetPerAdapterInfo"
- Klicke mit rechts auf diesen Eintrag, dann im Kontextmenu "Suche Bezeichner".

Falls die Fkt. in LCL, FCL, RTL etc. vorhanden ist, wird sie dir nun im Code Browser Fenster angezeigt (unit JwaIpHlpApi).
Ggf. "Bereich" ändern.

vazili_Zaitzef
Beiträge: 43
Registriert: Do 6. Dez 2012, 21:55
OS, Lazarus, FPC: Win7 64 (L 1.6 FPC 3.0.0)
CPU-Target: 64Bit

Re: Windows Funktionen benutzen

Beitrag von vazili_Zaitzef »

Hallo und vielen Dank Ihr beide für den guten Rat! :)
Das werd ich mir fürs nächste Mal merken :!:

Jetzt hab ich allerdings ein kleines anderes Problem. Wie komme ich jetzt an die Daten heran?
Wenn ich es so ausprobiere bekomme ich immer einen Fehler in der Zeile Memo1.text := pAdapterList^.AdapterName[0];
Es sieht für mich so aus, als ob die beiden Typen nicht kompatibel sind...

Dies hab ich in der MSDN gefunden doch irgendwie bin ich zu dumm dazu... :cry: :cry: :cry:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx





Code: Alles auswählen

procedure TForm2.Button2Click(Sender: TObject);
VAR
 dwLen       : DWORD;
 dwResult       : DWORD;
 pAdapterList : PIP_ADAPTER_INFO;
 begin
 DwLen := 1;
 dwResult   := GetAdaptersInfo(pAdapterList,dwLen);
 memo1.Text := pAdapterList^.AdapterName[0];
end;
Zuletzt geändert von Lori am Di 12. Aug 2014, 12:16, insgesamt 1-mal geändert.
Grund: Highlighter

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: Windows Funktionen benutzen

Beitrag von gocher »

so bekommst du die Liste der Lan Adapter, Form mit Button und Memo und fertig:

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, Windows, SysUtils, Forms, Controls, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
   btnShowInfo: TButton;
   memInfo: TMemo;
   procedure btnShowInfoClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
const
  MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
  MAX_ADAPTER_NAME_LENGTH = 256;
  MAX_ADAPTER_ADDRESS_LENGTH = 8;
 
type
  PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
  IP_ADDRESS_STRING = packed record
    acString: array [1..16] of Char;
  end;
 
  IP_MASK_STRING = IP_ADDRESS_STRING;
 
  PIP_ADDR_STRING = ^IP_ADDR_STRING;
  IP_ADDR_STRING = packed record
    Next: PIP_ADDR_STRING;
    IpAddress: IP_ADDRESS_STRING;
    IpMask: IP_MASK_STRING;
    Context: DWORD;
  end;
 
  time_t = comp;
 
  PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
  IP_ADAPTER_INFO = packed record
    Next: PIP_ADAPTER_INFO;
    ComboIndex: DWORD;
    AdapterName: array [1..MAX_ADAPTER_NAME_LENGTH+4] of Char ;
    Description: array [1..MAX_ADAPTER_DESCRIPTION_LENGTH+4] of Char;
    AddressLength: UINT;
    Address: array [1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
    Index: DWORD;
    dwType: UINT;
    DhcpEnabled: UINT;
    CurrentIpAddress: PIP_ADDR_STRING;
    IpAddressList: IP_ADDR_STRING;
    GatewayList: IP_ADDR_STRING;
    DhcpServer: IP_ADDR_STRING;
    HaveWins: Boolean;
    PrimaryWinsServer: IP_ADDR_STRING;
    SecondaryWinsServer: IP_ADDR_STRING;
    LeaseObtained: time_t;
    LeaseExpires: time_t;
  end;
 
  PIP_PER_ADAPTER_INFO = ^IP_PER_ADAPTER_INFO;
  IP_PER_ADAPTER_INFO = packed record
    AutoConfigEnabled: UINT;
    AutoConfigActive: UINT;
    CurrentDnsServer: PIP_ADDR_STRING;
    DnsServerList: IP_ADDR_STRING;
  end;
 
function GetAdaptersInfo(const pAdapterInfo: PIP_ADAPTER_INFO; const pOutBufLen: PULONG): DWORD; stdcall; external 'iphlpapi.dll';
function GetPerAdapterInfo(const pIfIndex: ULONG; const pAdapterInfo: PIP_PER_ADAPTER_INFO; const pOutBufLen: PULONG): DWORD; stdcall; external 'iphlpapi.dll';
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.btnShowInfoClick(Sender: TObject);
var
  pAdapterList: PIP_ADAPTER_INFO;
  dwLenAdapter: DWORD;
  aaiAdapters: array of PIP_ADAPTER_INFO;
  dwResult: DWORD;
  iIndexAdapter: integer;
  iasWork: IP_ADDR_STRING;
  paiWork: PIP_PER_ADAPTER_INFO;
  dwLenAdapterInfo: DWORD;
begin
  pAdapterList := nil;
  dwLenAdapter := 0;
  if GetAdaptersInfo(pAdapterList, @dwLenAdapter) <> ERROR_BUFFER_OVERFLOW then exit;
  pAdapterList := AllocMem(dwLenAdapter);
  try
    if GetAdaptersInfo(pAdapterList,@dwLenAdapter) <> ERROR_SUCCESS then exit;
    SetLength(aaiAdapters,1);
    aaiAdapters[0] := pAdapterList;
    while aaiAdapters[High(aaiAdapters)]^.Next <> nil do
    begin
      SetLength(aaiAdapters,Length(aaiAdapters)+1);
      aaiAdapters[High(aaiAdapters)] := aaiAdapters[High(aaiAdapters)-1]^.Next;
    end;
    for iIndexAdapter := 0 to high(aaiAdapters) do
    begin
      memInfo.Lines.Add(trim(aaiAdapters[iIndexAdapter]^.Description)+'/'+trim(aaiAdapters[iIndexAdapter]^.AdapterName));
{<--- hier kannst Du natürlich weitere Eigenschaften von IP_ADAPTER_INFO ausgeben }
      paiWork := nil;
      dwLenAdapterInfo := 0;
      dwResult := GetPerAdapterInfo(aaiAdapters[iIndexAdapter]^.Index,paiWork,@dwLenAdapterInfo);
      if dwResult <> ERROR_BUFFER_OVERFLOW then
      begin
        memInfo.Lines.Add('***** (1) Fehler beim Auslesen der Adapterdaten: '+IntToStr(dwResult));
      end
      else
      begin
        paiWork := AllocMem(dwLenAdapterInfo);
        try
          dwResult := GetPerAdapterInfo(aaiAdapters[iIndexAdapter]^.Index,paiWork,@dwLenAdapterInfo);
          if dwResult <> ERROR_SUCCESS then
          begin
            memInfo.Lines.Add('***** (2) Fehler beim Auslesen der Adapterdaten: '+IntToStr(dwResult));
          end
          else
          begin
            iasWork := paiWork^.DnsServerList;
            while iasWork.Next <> nil do
            begin
              memInfo.Lines.Add('DNS: '+trim(iasWork.IpAddress.acString));
              iasWork := iasWork.Next^;
            end;
            memInfo.Lines.Add('DNS:'+trim(iasWork.IpAddress.acString));
          end;
        finally
          FreeMem(paiWork,dwLenAdapterInfo);
        end;
      end;
    end;
  finally
    FreeMem(pAdapterList,dwLenAdapter);
  end;
end;
 
end.
 

Ausgabe:
Microsoft Virtual WiFi Miniport Adapter/{556FF41D-562A-4D14-AECC-468D20721780}
DNS:
Atheros AR8151 PCI-E Gigabit Ethernet Controller (NDIS 6.20)/{55BC1B37-AC4A-4D57-ADB7-A6B328705704}
DNS:
Realtek RTL8188CE 802.11b/g/n WiFi Adapter/{331EC24C-9A60-49F1-B827-DAA343E3991F}
DNS:192.168.178.1
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

vazili_Zaitzef
Beiträge: 43
Registriert: Do 6. Dez 2012, 21:55
OS, Lazarus, FPC: Win7 64 (L 1.6 FPC 3.0.0)
CPU-Target: 64Bit

Re: Windows Funktionen benutzen

Beitrag von vazili_Zaitzef »

Hallo,

danke für den Quelltext.
Das ist genau das, was ich gesucht habe :)
Vielen lieben Dank dafür:)

Ich verstehe zwar nicht viel, wie das programmiert wurde aber langsam komm ich dahinter, wie ich das benutzen kann.
Was bedeuten die ^in Lazarus? :roll:

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Windows Funktionen benutzen

Beitrag von Komoluna »

Wenn du einen Pointer(Zeiger) hast, kannst du damit auf den Inhalt des Wertebereiches, anstatt auf den Pointer selbst zugreifen.
(gegenteil von @xy)

Bsp:

Code: Alles auswählen

var
  p: PInteger;  //Pointer auf einen Integer
  i: Integer;
begin
  i := 2;
  p := @i;  //Weist p eine Referenz auf i zu
  WriteLn(p^)//Gibt 2 aus
  i := 34;
  WriteLn(p^); //Gibt 34 aus
end;


Ich hoffe das war nicht zu kompliziert

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: Windows Funktionen benutzen

Beitrag von gocher »

Die Funktion GetAdaptersInfo liefert einen Zeiger auf ein Record, wir wollen aber das Record selbst ansprechen und so muss man unter Free Pascal anders als unter Delphi erst einmal dereferenzieren.
http://wiki.freepascal.org/Code_Conversion_Guide/de#Beim_Zugriff_auf_den_Wert_eines_Record_mittels_eines_Zeigers_muss_dieser_zuerst_dereferenziert_werden
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

vazili_Zaitzef
Beiträge: 43
Registriert: Do 6. Dez 2012, 21:55
OS, Lazarus, FPC: Win7 64 (L 1.6 FPC 3.0.0)
CPU-Target: 64Bit

Re: Windows Funktionen benutzen

Beitrag von vazili_Zaitzef »

Ah jetzt geht mir ein Licht auf. Jetzt versteh ich das ein wenig besser.
Da muss ich mich wohl ein wenig mehr belesen. Wie ich finde kann man sich damit das Leben richtig leicht machen.

:)

Antworten