Freigeben über


Exemplarische Vorgehensweise: Aufrufen von Windows-APIs (Visual Basic)

Windows-APIs sind Dynamic Link Libraries (DLLs), die Teil des Windows-Betriebssystems sind. Sie verwenden sie, um Aufgaben auszuführen, wenn es schwierig ist, gleichwertige Prozeduren zu schreiben. Beispielsweise stellt Windows eine Funktion mit dem Namen FlashWindowEx bereit, mit der Sie die Titelleiste für eine Anwendung zwischen hellen und dunklen Schattierungen wechseln können.

Der Vorteil der Verwendung von Windows-APIs in Ihrem Code besteht darin, dass sie Zeit sparen können, da sie Dutzende nützlicher Funktionen enthalten, die bereits geschrieben wurden und darauf warten, verwendet zu werden. Der Nachteil besteht darin, dass Windows-APIs schwierig zu handhaben sind und unerbittlich reagieren, wenn die Dinge schief gehen.

Windows-APIs stellen eine spezielle Kategorie der Interoperabilität dar. Windows-APIs verwenden keinen verwalteten Code, verfügen nicht über integrierte Typbibliotheken und verwenden Datentypen, die sich von denen unterscheiden, die mit Visual Studio verwendet werden. Aufgrund dieser Unterschiede und da Windows-APIs keine COM-Objekte sind, wird die Interoperabilität mit Windows-APIs und .NET Framework mithilfe des Plattform-Aufrufs oder PInvoke ausgeführt. Der Plattformaufruf ist ein Dienst, mit dem verwalteter Code nicht verwaltete Funktionen aufrufen kann, die in DLLs implementiert sind. Weitere Informationen finden Sie unter Verwenden nicht verwalteter DLL-Funktionen. Sie können PInvoke in Visual Basic verwenden, indem Sie entweder die Declare Anweisung verwenden oder das DllImport Attribut auf eine leere Prozedur anwenden.

Windows-API-Aufrufe waren in der Vergangenheit ein wichtiger Bestandteil der Visual Basic-Programmierung, sind jedoch selten mit Visual Basic .NET erforderlich. Wann immer möglich, sollten Sie verwalteten Code aus .NET Framework verwenden, um Aufgaben auszuführen, anstelle von Windows-API-Aufrufen. Diese exemplarische Vorgehensweise enthält Informationen für situationen, in denen die Verwendung von Windows-APIs erforderlich ist.

Hinweis

Auf Ihrem Computer werden möglicherweise unterschiedliche Namen oder Speicherorte für einige der Visual Studio-Benutzeroberflächenelemente in den folgenden Anweisungen angezeigt. Die Visual Studio-Edition, über die Sie verfügen, und die Einstellungen, die Sie verwenden, bestimmen diese Elemente. Weitere Informationen finden Sie unter Personalisierung der IDE.

API-Aufrufe mithilfe von Declare

Die am häufigsten verwendete Methode zum Aufrufen von Windows-APIs ist die Verwendung der Declare Anweisung.

So deklarieren Sie eine DLL-Prozedur

  1. Ermitteln Sie den Namen der Funktion, die Sie aufrufen möchten, sowie deren Argumente, Argumenttypen und Rückgabewert sowie den Namen und Speicherort der DLL, die sie enthält.

    Hinweis

    Vollständige Informationen zu den Windows-APIs finden Sie in der Win32 SDK-Dokumentation in der Plattform-SDK-Windows-API. Weitere Informationen zu den von Windows-APIs verwendeten Konstanten finden Sie in den Headerdateien wie Windows.h, die im Platform SDK enthalten sind.

  2. Öffnen Sie ein neues Windows-Anwendungsprojekt, indem Sie im Menü "Datei" auf "Neu" und dann auf "Projekt" klicken. Das Dialogfeld Neues Projekt wird angezeigt.

  3. Wählen Sie windows-Anwendung aus der Liste der Visual Basic-Projektvorlagen aus. Das neue Projekt wird angezeigt.

  4. Fügen Sie der Klasse oder dem Modul, in der Sie die DLL verwenden möchten, die folgende Declare Funktion hinzu:

    Declare Auto Function MBox Lib "user32.dll" Alias "MessageBox" (
        ByVal hWnd As Integer,
        ByVal txt As String,
        ByVal caption As String,
        ByVal Typ As Integer) As Integer
    

Teile der Declare-Anweisung

Die Declare Anweisung enthält die folgenden Elemente.

Automatischer Modifizierer

Der Auto Modifizierer weist die Laufzeit an, die Zeichenfolge basierend auf dem Methodennamen gemäß allgemeinen Sprachlaufzeitregeln (oder Aliasnamen bei Angabe) zu konvertieren.

Schlüsselwörter "Lib" und "Alias"

Der Name nach dem Function Schlüsselwort ist der Name, den Ihr Programm für den Zugriff auf die importierte Funktion verwendet. Dies kann mit dem tatsächlichen Namen der Funktion identisch sein, die Sie aufrufen, oder Sie können einen beliebigen gültigen Prozedurnamen verwenden und dann das Alias Schlüsselwort verwenden, um den tatsächlichen Namen der Funktion anzugeben, die Sie aufrufen.

Geben Sie das Lib Schlüsselwort an, gefolgt vom Namen und Speicherort der DLL, die die funktion enthält, die Sie aufrufen. Sie müssen nicht den Pfad für Dateien angeben, die sich in den Windows-Systemverzeichnissen befinden.

Verwenden Sie das Alias Schlüsselwort, wenn der Name der aufgerufenen Funktion kein gültiger Visual Basic-Prozedurname ist oder mit dem Namen anderer Elemente in Ihrer Anwendung in Konflikt steht. Alias gibt den wahren Namen der aufgerufenen Funktion an.

Argument- und Datentypdeklarationen

Deklarieren Sie die Argumente und deren Datentypen. Dieser Teil kann schwierig sein, da die von Windows verwendeten Datentypen nicht visual Studio-Datentypen entsprechen. Visual Basic erledigt viel Arbeit für Sie, indem Argumente in kompatible Datentypen konvertiert werden, ein Prozess, der als Marshalling bezeichnet wird. Sie können explizit steuern, wie Argumente ge marshallt werden, indem Sie das MarshalAsAttribute im System.Runtime.InteropServices Namespace definierte Attribut verwenden.

Hinweis

In früheren Versionen von Visual Basic können Sie Parameter As Anydeklarieren, was bedeutet, dass Daten eines beliebigen Datentyps verwendet werden können. Visual Basic erfordert, dass Sie für alle Declare Anweisungen einen bestimmten Datentyp verwenden.

Windows-API-Konstanten

Einige Argumente sind Kombinationen von Konstanten. Die in dieser exemplarischen Vorgehensweise gezeigte MessageBox-API akzeptiert beispielsweise ein ganzzahliges Argument namens Typ, das steuert, wie das Meldungsfeld angezeigt wird. Sie können den numerischen Wert dieser Konstanten ermitteln, indem Sie die #define Anweisungen in der Datei "WinUser.h" untersuchen. Die numerischen Werte werden in der Regel als Hexadezimalzahl angezeigt, daher können Sie einen Rechner verwenden, um sie hinzuzufügen und in eine Dezimalzahl zu konvertieren. Wenn Sie z. B. die Konstanten für das Ausrufeformat MB_ICONEXCLAMATION 0x00000030 und die Formatvorlage MB_YESNO "Ja/Nein" 0x00000004 kombinieren möchten, können Sie die Zahlen hinzufügen und ein Ergebnis von 0x00000034 oder 52 Dezimalzahl erhalten. Obwohl Sie das Dezimalergebnis direkt verwenden können, ist es besser, diese Werte als Konstanten in Ihrer Anwendung zu deklarieren und mit dem Or Operator zu kombinieren.

So deklarieren Sie Konstanten für Windows-API-Aufrufe
  1. Konsultieren Sie die Dokumentation für die Windows-Funktion, die Sie aufrufen. Ermitteln Sie den Namen der von ihr verwendeten Konstanten und den Namen der H-Datei, die die numerischen Werte für diese Konstanten enthält.

  2. Verwenden Sie einen Text-Editor, z. B. Editor, um den Inhalt der Headerdatei (H-Datei) anzuzeigen und die Werte zu ermitteln, die den von Ihnen verwendeten Konstanten zugeordnet sind. Beispielsweise verwendet die MessageBox API die Konstante MB_ICONQUESTION , um ein Fragezeichen im Meldungsfeld anzuzeigen. Die Definition für MB_ICONQUESTION befindet sich in WinUser.h und wird wie folgt angegeben:

    #define MB_ICONQUESTION 0x00000020L

  3. Fügen Sie ihrer Klasse oder Ihrem Modul entsprechende Const Anweisungen hinzu, um diese Konstanten für Ihre Anwendung verfügbar zu machen. Beispiel:

    Const MB_ICONQUESTION As Integer = &H20
    Const MB_YESNO As Integer = &H4
    Const IDYES As Integer = 6
    Const IDNO As Integer = 7
    
So rufen Sie die DLL-Prozedur auf
  1. Fügen Sie dem Startformular für Ihr Projekt eine Schaltfläche hinzu Button1 , und doppelklicken Sie dann auf die Schaltfläche, um den zugehörigen Code anzuzeigen. Der Ereignishandler für die Schaltfläche wird angezeigt.

  2. Fügen Sie dem Click Ereignishandler Code für die hinzugefügte Schaltfläche hinzu, um die Prozedur aufzurufen und die entsprechenden Argumente bereitzustellen:

    Private Sub Button1_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button1.Click
    
        ' Stores the return value.
        Dim RetVal As Integer
        RetVal = MBox(0, "Declare DLL Test", "Windows API MessageBox",
            MB_ICONQUESTION Or MB_YESNO)
    
        ' Check the return value.
        If RetVal = IDYES Then
            MsgBox("You chose Yes")
        Else
            MsgBox("You chose No")
        End If
    End Sub
    
  3. Führen Sie das Projekt aus, indem Sie F5 drücken. Das Meldungsfeld wird mit den Schaltflächen " Ja " und "Nein " angezeigt. Klicken Sie auf eine der optionen.

Marshallen von Daten

Visual Basic konvertiert automatisch die Datentypen von Parametern und Rückgabewerten für Windows-API-Aufrufe. Sie können jedoch das MarshalAs Attribut verwenden, um explizit nicht verwaltete Datentypen anzugeben, die von einer API erwartet werden. Weitere Informationen zum Interop-Marshalling finden Sie unter Interop Marshaling.

So verwenden Sie Declare und MarshalAs in einem API-Aufruf
  1. Bestimmen Sie den Namen der Funktion, die Sie aufrufen möchten, sowie deren Argumente, Datentypen und Rückgabewert.

  2. Um den Zugriff auf das MarshalAs Attribut zu vereinfachen, fügen Sie oben im Code für die Klasse oder das Modul eine Imports Anweisung hinzu, wie im folgenden Beispiel gezeigt:

    Imports System.Runtime.InteropServices
    
  3. Fügen Sie der verwendeten Klasse oder dem verwendeten Modul einen Funktionsprototyp für die importierte Funktion hinzu, und wenden Sie das MarshalAs Attribut auf die Parameter oder den Rückgabewert an. Im folgenden Beispiel wird ein API-Aufruf, der den Typ void* erwartet, als AsAny gemarshallt.

    Declare Sub SetData Lib "..\LIB\UnmgdLib.dll" (
        ByVal x As Short,
        <MarshalAsAttribute(UnmanagedType.AsAny)>
            ByVal o As Object)
    

API-Aufrufe mit DllImport

Das DllImport Attribut bietet eine zweite Möglichkeit, Funktionen in DLLs ohne Typbibliotheken aufzurufen. DllImport entspricht ungefähr der Verwendung einer Declare Anweisung, bietet aber mehr Kontrolle darüber, wie Funktionen aufgerufen werden.

Sie können DllImport mit den meisten Windows-API-Aufrufen verwenden, solange der Aufruf auf eine freigegebene (manchmal statische genannte) Methode verweist. Methoden, die eine Instanz einer Klasse erfordern, können nicht verwendet werden. Im Gegensatz zu den Declare-Anweisungen können DllImport-Aufrufe das MarshalAs-Attribut nicht verwenden.

So rufen Sie eine Windows-API mit dem DllImport-Attribut auf

  1. Öffnen Sie ein neues Windows-Anwendungsprojekt, indem Sie im Menü "Datei" auf "Neu" und dann auf "Projekt" klicken. Das Dialogfeld Neues Projekt wird angezeigt.

  2. Wählen Sie windows-Anwendung aus der Liste der Visual Basic-Projektvorlagen aus. Das neue Projekt wird angezeigt.

  3. Fügen Sie dem Startformular eine Schaltfläche mit dem Namen Button2 hinzu.

  4. Doppelklicken Sie, Button2 um die Codeansicht für das Formular zu öffnen.

  5. Um den Zugriff zu DllImportvereinfachen, fügen Sie oben im Code für die Startformularklasse eine Imports Anweisung hinzu:

    Imports System.Runtime.InteropServices
    
  6. Deklarieren Sie eine leere Funktion vor der End Class Anweisung für das Formular, und benennen Sie die Funktion MoveFile.

  7. Wenden Sie die Modifizierer Public und Shared auf die Funktionsdeklaration an und legen Sie Parameter für MoveFile basierend auf den Argumenten fest, die die Windows-API-Funktion verwendet:

    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    

    Ihre Funktion kann über einen beliebigen gültigen Prozedurnamen verfügen; das DllImport Attribut gibt den Namen in der DLL an. Es behandelt auch die Interoperabilitäts-Marshalling für die Parameter und Rückgabewerte, sodass Sie Visual Studio-Datentypen auswählen können, die den von der API verwendeten Datentypen ähneln.

  8. Wenden Sie das DllImport Attribut auf die leere Funktion an. Der erste Parameter ist der Name und speicherort der DLL, die die funktion enthält, die Sie aufrufen. Sie müssen nicht den Pfad für Dateien angeben, die sich in den Windows-Systemverzeichnissen befinden. Der zweite Parameter ist ein benanntes Argument, das den Namen der Funktion in der Windows-API angibt. In diesem Beispiel erzwingt das DllImport Attribut, dass Aufrufe an MoveFile in KERNEL32.DLL an MoveFileW weitergeleitet werden. Die MoveFileW Methode kopiert eine Datei vom Pfad src zum Pfad dst.

    <DllImport("KERNEL32.DLL", EntryPoint:="MoveFileW", SetLastError:=True,
        CharSet:=CharSet.Unicode, ExactSpelling:=True,
        CallingConvention:=CallingConvention.StdCall)>
    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    
  9. Fügen Sie dem Button2_Click Ereignishandler Code hinzu, um die Funktion aufzurufen:

    Private Sub Button2_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button2.Click
    
        Dim RetVal As Boolean = MoveFile("c:\tmp\Test.txt", "c:\Test.txt")
        If RetVal = True Then
            MsgBox("The file was moved successfully.")
        Else
            MsgBox("The file could not be moved.")
        End If
    End Sub
    
  10. Erstellen Sie eine Datei mit dem Namen Test.txt, und platzieren Sie sie im Verzeichnis "C:\Tmp" auf Der Festplatte. Erstellen Sie bei Bedarf das Tmp-Verzeichnis.

  11. Drücken Sie F5, um die Anwendung zu starten. Das Hauptformular wird angezeigt.

  12. Klicken Sie auf Schaltfläche2. Die Meldung "Die Datei wurde erfolgreich verschoben" wird angezeigt, wenn die Datei verschoben werden kann.

Siehe auch