• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:APIの呼び出しDLLファイルの場所を変化させたい)

APIの呼び出しDLLファイルの場所を変化させたい

このQ&Aのポイント
  • VB.NETからDLLを呼び出すため、DLLファイルの場所を変える必要があります。現在はソースコード内のファイル場所を毎回書き換えていますが、hostnameを取得することで環境ごとに呼び出すファイルを変える方法があります。
  • Windowsの環境変数のPATHに書き込みたくないため、プログラム内でDLLファイルの場所を指定したいとのことです。
  • ソースコードの例では、固定変数としてDLLファイルの場所を指定していますが、hostnameを取得して条件分岐させることで可変的にDLLファイルを指定できます。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

前の書き込みの続きです。 ※以下が、サンプルソース(2)です。。 //DllLoader.vb Start// Imports System.Runtime.InteropServices ''' <summary> ''' 動的DLLローダー ''' </summary> ''' <remarks></remarks> Public Class DllLoader   Implements IDisposable   Private Class kernel32API     <DllImport("kernel32", CharSet:=CharSet.Auto, SetLastError:=True)> _     Public Shared Function LoadLibrary(ByVal lpFileName As String) As IntPtr     End Function     <DllImport("kernel32", CharSet:=CharSet.Auto, SetLastError:=True)> _     Public Shared Function FreeLibrary(ByVal hModule As IntPtr) As Boolean     End Function     <DllImport("kernel32", CharSet:=CharSet.Ansi, SetLastError:=True)> _     Public Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr     End Function   End Class   Private _ptrModule As IntPtr = IntPtr.Zero #Region "APIで発生した最後のエラー"   Private _lastErrorNo As Integer = 0   Public ReadOnly Property LastErrorNo() As Integer     Get       Return _lastErrorNo     End Get   End Property #End Region #Region "コンストラクタ"   ''' <summary>   ''' コンストラクタ   ''' </summary>   ''' <param name="p_strDllFullPath">DLLのフルパス</param>   ''' <remarks></remarks>   Public Sub New(p_strDllFullPath As String)     _ptrModule = kernel32API.LoadLibrary(p_strDllFullPath)     If (_ptrModule = IntPtr.Zero) Then       _lastErrorNo = Marshal.GetHRForLastWin32Error       Dim ex As Exception = Marshal.GetExceptionForHR(_lastErrorNo)       Throw ex     End If   End Sub #End Region #Region "ロードしたDLLの解放処理"   ''' <summary>   ''' ロードしたDLLの解放処理   ''' </summary>   ''' <remarks></remarks>   Private Sub FreeLoder()     If (_ptrModule = IntPtr.Zero) Then       Return     End If     If Not kernel32API.FreeLibrary(_ptrModule) Then       _lastErrorNo = Marshal.GetHRForLastWin32Error       Dim ex As Exception = Marshal.GetExceptionForHR(_lastErrorNo)       Throw ex     End If   End Sub #End Region #Region "Delegateの取得"   ''' <summary>   ''' Delegateの取得   ''' </summary>   ''' <param name="p_strProcName">発行を行うメソッド名</param>   ''' <param name="p_typProcType">発行を行うメソッド型</param>   ''' <returns></returns>   ''' <remarks></remarks>   Public Function GetDelegate(ByVal p_strProcName As String, ByVal p_typProcType As Type) As [Delegate]     If (_ptrModule = IntPtr.Zero) Then       Return Nothing     End If     Dim l_ptrProcAddress As IntPtr = kernel32API.GetProcAddress(_ptrModule, p_strProcName)     If (l_ptrProcAddress = IntPtr.Zero) Then       _lastErrorNo = Marshal.GetHRForLastWin32Error       Dim ex As Exception = Marshal.GetExceptionForHR(_lastErrorNo)       Throw ex     End If     Return Marshal.GetDelegateForFunctionPointer(l_ptrProcAddress, p_typProcType)   End Function #End Region #Region "IDisposable Support"   Private disposedValue As Boolean ' 重複する呼び出しを検出するには   Protected Overridable Sub Dispose(disposing As Boolean)     If (Not Me.disposedValue) Then       If (disposing) Then         Call FreeLoder()       End If     End If     Me.disposedValue = True   End Sub   Public Sub Dispose() Implements IDisposable.Dispose     Dispose(True)     GC.SuppressFinalize(Me)   End Sub #End Region End Class //DllLoader.vb End//

ghost305jp
質問者

お礼

ご回答ありがとうございます。 これが、知りたかった質問の内容と一致しております。 これを参考に、したいと思います。 ありがとうございました。

その他の回答 (4)

回答No.4

以前、DllLoaderという動的DLLを起動するライブラリを作ったので、それを張っておきます。 ※参考資料を求めるのであれば、以下のキーワードを参考にしてください。 LoadLibrary GetProcAddress FreeLibrary ※以下が、ライブラリを起動するための構成です。 1.[Class1.vb]→→→→「2のサンプル」の起動 2.[Sample.vb]→→→→「3のDllLoader」呼出実行例 3.[DllLoader.vb]→→→ライブライリの本体 文字制限で全部を張る事ができないので、ソースを分割します。 ※以下が、サンプルソース(1)です。。 //Class1.vb Start// Public Class Class1   Shared Sub Main()     Dim l_SampleStatic As New Sample.静的()     l_SampleStatic.実行()     Dim l_SampleDynamic As New Sample.動的()     l_SampleDynamic.実行()   End Sub End Class //Class1.vb End// //Sample.vb Start// Imports System.Runtime.InteropServices Public Class Sample   <StructLayout(LayoutKind.Sequential)> _   Private Structure RECT     Public left As Int32     Public top As Int32     Public right As Int32     Public bottom As Int32   End Structure   Private Shared Sub 取得情報表示(p_rectWk As RECT)     '取得した情報を出力     Dim l_aryPrms As New List(Of String)()     l_aryPrms.Add(ControlChars.CrLf)     l_aryPrms.Add(p_rectWk.left.ToString())     l_aryPrms.Add(p_rectWk.right.ToString())     l_aryPrms.Add(p_rectWk.top.ToString())     l_aryPrms.Add(p_rectWk.bottom.ToString())     Dim l_strMsg As String = String.Format("Left:{1}{0}Right:{2}{0}Top:{3}{0}Bottom:{4}", l_aryPrms.ToArray())     MsgBox(l_strMsg, MsgBoxStyle.Information, "デスクトップ矩形情報")   End Sub #Region "静的なDLLの利用"   Public Class 静的     <DllImport("user32.dll")> _     Private Shared Function GetWindowRect(ByVal hwnd As IntPtr, ByRef lpRect As RECT) As Integer     End Function     <DllImport("user32.dll")> _     Private Shared Function GetDesktopWindow() As IntPtr     End Function     Public Sub 実行()       '矩形情報を格納する変数       Dim l_rectWk As New RECT       'デスクトップハンドルを取得       Dim l_ptrDeskTop As IntPtr = GetDesktopWindow()       'デスクトップハンドルから矩形を取得       Call GetWindowRect(l_ptrDeskTop, l_rectWk)       Call 取得情報表示(l_rectWk)     End Sub   End Class #End Region #Region "動的なDLLの利用"   Public Class 動的     Private Delegate Function GetWindowRectDelegate(ByVal hwnd As IntPtr, ByRef lpRect As RECT) As Integer     Private Delegate Function GetDesktopWindowDelegate() As IntPtr     Public Sub 実行()       Dim l_strDllPath As String = String.Empty       If Not OpenFileDialog(l_strDllPath) Then         Return       End If       Using l_dll As New DllLoader(l_strDllPath)         'GetDesktopWindow         Dim l_method_GetDesktopWindow As GetDesktopWindowDelegate = l_dll.GetDelegate("GetDesktopWindow", GetType(GetDesktopWindowDelegate))         'GetWindowRect         Dim l_method_GetWindowRect As GetWindowRectDelegate = l_dll.GetDelegate("GetWindowRect", GetType(GetWindowRectDelegate))         '矩形情報を格納する変数         Dim l_rectWk As New RECT         'デスクトップハンドルを取得         Dim l_ptrDeskTop As IntPtr = l_method_GetDesktopWindow.Invoke()         'デスクトップハンドルから矩形を取得         Call l_method_GetWindowRect.Invoke(l_ptrDeskTop, l_rectWk)         Call 取得情報表示(l_rectWk)       End Using     End Sub     Private Function OpenFileDialog(ByRef p_strRetPath As String) As Boolean       Using l_dlgOpen As New OpenFileDialog()         l_dlgOpen.Title = "DLLを指定"         l_dlgOpen.Filter = "user32.dllファイル(user32.dll)|user32.dll|DLLファイル(*.dll)|*.dll"         l_dlgOpen.FileName = "user32.dll"         If Not (l_dlgOpen.ShowDialog() = DialogResult.OK) Then           Return False         End If         p_strRetPath = l_dlgOpen.FileName       End Using       Return True     End Function   End Class #End Region End Class //Sample.vb End//

ghost305jp
質問者

お礼

ご回答ありがとうございます。 これが、知りたかった質問の内容と一致しております。 これを参考に、したいと思います。 ありがとうございました。

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.3

> Windowsの環境変数のPATHに書き込みはしたくありません。 プロセス単位で設定できます。 http://msdn.microsoft.com/ja-jp/library/96xafkes(v=vs.80).aspx

ghost305jp
質問者

お礼

環境変数をプロセス単位でできるのですね。 DOSの頃には無かった機能! 勉強になりました。 ありがとうございました。

回答No.2

> 他の会社がDLLファイルを提供しています。 他社に、環境変数が通るディレクトリにインストールしてもらうよう 依頼するか、自分が作成するexeに同梱させるかのどちらかでしょうね。 ネイティブなDLLを利用するなら、%SystemRoot%\system32にセットアップされるか、 利用者が自分でセットアップしろという感じで説明書があっても いいような気もしますが・・・。

ghost305jp
質問者

お礼

ご回答ありがとうございます。 DLLを自分のアプリの場所にコピーか、PATHの通っている場所にコピーか を含めて検討致します。 ありがとうございました。

回答No.1

ネットワーク越しにDLLを参照するのですか? exeと同一ディレクトリ内にDLLを設置してはいけないのでしょうか?

ghost305jp
質問者

補足

ご回答ありがとうございます。 他の会社がDLLファイルを提供しています。 その為、そのファイルのある場所を指定しています。 でも、よく考えたらDLLをコピーもありですね^^