プロが教える店舗&オフィスのセキュリティ対策術

VB.NETからDLLを呼び出したいのですが、これが私のコンピューターと
顧客側のコンピュータとで環境が違う為、毎回ファイルの場所を変えて
使用しています。(ソース内のファイル場所を毎回書き換える)

これを、hostnameの取得により、私のパソコンとその他の環境とで
呼び出す状況を変えたいと思っております。
どの様にすれば良いか、教えて下さい。

Windowsの環境変数のPATHに書き込みはしたくありません。
あくまで、プログラム内で終わらせたいのですが・・


(ソース例)
’↓固定変数でないとダメ?
Public Const MyDllFileName As String = "\\ServerName\Kyouyu\MyDllFile.dll"

'Type(1)
Public Declare Function ExportDLL1 Lib MyDllFileName (ByRef MyData As MyStructure) As Integer

'Type(2)
<DllImport(MyDllFileName)> Public Function ExportDLL2(ByRef MyData As MyStructure) As Integer
End Function

A 回答 (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//
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/11/13 10:31

以前、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//
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/11/13 10:31

> Windowsの環境変数のPATHに書き込みはしたくありません。



プロセス単位で設定できます。

http://msdn.microsoft.com/ja-jp/library/96xafkes …
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/11/13 10:29

> 他の会社がDLLファイルを提供しています。



他社に、環境変数が通るディレクトリにインストールしてもらうよう
依頼するか、自分が作成するexeに同梱させるかのどちらかでしょうね。

ネイティブなDLLを利用するなら、%SystemRoot%\system32にセットアップされるか、
利用者が自分でセットアップしろという感じで説明書があっても
いいような気もしますが・・・。
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/11/13 10:28

ネットワーク越しにDLLを参照するのですか?


exeと同一ディレクトリ内にDLLを設置してはいけないのでしょうか?

この回答への補足

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

補足日時:2013/11/11 16:04
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!