かなり有名な問題なのですが、いつも忘れてしまうのでメモしておきます。
ちなみにこの問題はVISTAでは発生しません。XPでは発生します。
現象を確認するため以下のコードをXPで実行します。
1回目のCurrentDirectoryは実行パスのディレクトリが返ります。
2回目のCurrentDirectoryはOpenFileDialogで指定した保存先パスのディレクトリが返ります。
'現在のカレントディレクトリ Console.WriteLine(System.IO.Directory.GetCurrentDirectory) 'ファイルを開くダイアログ Dim path As String = String.Empty Using dialog As New OpenFileDialog If dialog.ShowDialog = Windows.Forms.DialogResult.OK Then path = dialog.FileName End If End Using '現在のカレントディレクトリ Console.WriteLine(System.IO.Directory.GetCurrentDirectory)
たとえば、このような現象で問題になるのは以下のようなコードがあります。
Dim asbl As System.Reflection.Assembly asbl = System.Reflection.Assembly.LoadFrom("ClassLibrary.dll")
相対パスでアセンブリをロードしているのですが、通常はカレントディレクトリが実行パスのディレクトリであるため
実行パスのディレクトリからClassLibrary.dllを探します。
しかしOpenFileDialogやSaveFileDialogを使用した後、カレントディレクトリが保存先のディレクトリに変更されるため
保存先のディレクトリからClassLibrary.dllを探し、ClassLibrary.dllが見つからないのでエラーになります。
この問題を回避するため、OpenFileDialogやSaveFileDialogではRestoreDirectoryプロパティをTrueに設定するようにします。
RestoreDirectoryプロパティはダイアログ ボックスを閉じる前に、現在のディレクトリを復元するかどうかを示す値を取得または設定します。
デフォルトはFalseです。
'現在のカレントディレクトリ Console.WriteLine(System.IO.Directory.GetCurrentDirectory) 'ファイルを開くダイアログ Dim path As String = String.Empty Using dialog As New OpenFileDialog dialog.RestoreDirectory = True If dialog.ShowDialog = Windows.Forms.DialogResult.OK Then path = dialog.FileName End If End Using '現在のカレントディレクトリ Console.WriteLine(System.IO.Directory.GetCurrentDirectory)
一応このプロパティを設定することで問題は起きないはずです。
しかし、そもそもの原因はカレントディレクトリが実行パスのディレクトリだという事を前提にしたプログラムが一番の問題なのだと思います。
実行パスのディレクトリからClassLibrary.dllを探したいのなら、Application.StartupPathを指定しましょう。
Dim asblNm As String = System.IO.Path.Combine(Application.StartupPath, "ClassLibrary.dll") Dim asbl As System.Reflection.Assembly asbl = System.Reflection.Assembly.LoadFrom(asblNm)
0 件のコメント:
コメントを投稿