30

How should I DLLImport things in VB.NET? An example would be:

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer

End Function

If I put it inside a Class or somewhere else, I get "DLLimport is not defined" I am using Visual Studio 2008 Professional

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MilMike
  • 12,571
  • 15
  • 65
  • 82

5 Answers5

40

You have to add Imports System.Runtime.InteropServices to the top of your source file.

Alternatively, you can fully qualify attribute name:

<System.Runtime.InteropService.DllImport("user32.dll", _
    SetLastError:=True, CharSet:=CharSet.Auto)> _
Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
  • Do you have any book for Visual basic 2015 which only talks about how to use any type of `System.Runtime.InteropService.DllImport` to become master on it? –  Jan 24 '17 at 08:30
8
Imports System.Runtime.InteropServices
Luhmann
  • 3,860
  • 26
  • 33
7

I know this has already been answered, but here is an example for the people who are trying to use SQL Server Types in a vb project:

            Imports System
            Imports System.IO
            Imports System.Runtime.InteropServices

            Namespace SqlServerTypes
                Public Class Utilities



                    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
                    Public Shared Function LoadLibrary(ByVal libname As String) As IntPtr

                    End Function

                    Public Shared Sub LoadNativeAssemblies(ByVal rootApplicationPath As String)
                        Dim nativeBinaryPath = If(IntPtr.Size > 4, Path.Combine(rootApplicationPath, "SqlServerTypes\x64\"), Path.Combine(rootApplicationPath, "SqlServerTypes\x86\"))
                        LoadNativeAssembly(nativeBinaryPath, "msvcr120.dll")
                        LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial140.dll")
                    End Sub

                    Private Shared Sub LoadNativeAssembly(ByVal nativeBinaryPath As String, ByVal assemblyName As String)
                        Dim path = System.IO.Path.Combine(nativeBinaryPath, assemblyName)
                        Dim ptr = LoadLibrary(path)

                        If ptr = IntPtr.Zero Then
                            Throw New Exception(String.Format("Error loading {0} (ErrorCode: {1})", assemblyName, Marshal.GetLastWin32Error()))
                        End If
                    End Sub
                End Class
            End Namespace
Todd Harvey
  • 309
  • 3
  • 4
  • In retrospect, and sorry to somewhat hijack this thread although several of the questions and points are addressed by this code, it's main purpose is to get ReportViewer and SqlServerTypes to work in an old VB project, and that all worked. But I feel that a stubbed out LoadLibrary function that I believe should call into a kernel dll cannot be working correctly, and therefore ReportViewer may not have exercised that function. – Todd Harvey Jun 01 '18 at 12:31
  • I'm glad you did! I came to this while trying to do exactly what you posted. Thanks – starx207 Apr 08 '20 at 15:49
5

I saw in getwindowtext (user32) on pinvoke.net that you can place a MarshalAs statement to state that the StringBuffer is equivalent to LPSTR.

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Ansi)> _
Public Function GetWindowText(hwnd As IntPtr, <MarshalAs(UnManagedType.LPStr)>lpString As System.Text.StringBuilder, cch As Integer) As Integer
End Function
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nap
  • 8,096
  • 13
  • 74
  • 117
1

You can also try this

Private Declare Function GetWindowText Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer

I always use Declare Function instead of DllImport... Its more simply, its shorter and does the same

  • 9
    There are a great number of things you *cannot* do with a Declare statement. None of the interop attributes are available to you. Honestly, this is legacy VB 6 syntax, and I think all new VB.NET code should be written using the standard .NET syntax. – Cody Gray - on strike Jun 15 '16 at 10:17
  • Well, youre right but iam a lazy programmer, so i always try to get the shortest one :) For my projects this one always helped me out – Christopher Aicher Jun 15 '16 at 12:01