C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: DLLが参照できない


(過去ログ 142 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■83515 / inTopicNo.1)  DLLが参照できない
  
□投稿者/ 萌 (11回)-(2017/03/26(Sun) 10:03:25)

分類:[.NET 全般] 

Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
というファイルを
C:\Windows\System32
に置き、参照設定から追加しようとしたのですが
なぜかファイルが間違いなく存在するにも拘わらず
VSからこれらのファイルが見えなくなっています。
全てのファイルを表示にしましたが、見えません
また、これらのファイルだけでなく元から存在する
ファイルに「Microsoft.」がつくもの見えなくなっています。
一体どうやって参照すれば良いですか?
C:\Windows
などの別のフォルダーであれば問題なく参照することができます。
 
引用返信 編集キー/
■83516 / inTopicNo.2)  Re[1]: DLLが参照できない
□投稿者/ Hongliang (514回)-(2017/03/26(Sun) 10:21:03)
64bit版Windowsでは、System32など一部のフォルダは、呼び出すプロセスによってリダイレクトされます。
64bitプロセスからはそのままSystem32が見えますが、32bitプロセスからはSystem32フォルダはSysWow64フォルダにリダイレクトされます。
Visual Studioは32bitプロセスですので、SysWow64フォルダを見に行ったのでしょう。

それはそれとして、.NETのDLLは、WindowsのPATHを参照しません。なので、system32に入っていたからといっても実行時に意味はありません。
開発時にも、あえてsystem32などに入れる意義はないように思います。
引用返信 編集キー/
■83517 / inTopicNo.3)  Re[2]: DLLが参照できない
□投稿者/ 萌 (13回)-(2017/03/26(Sun) 10:32:47)
仰る通り、SysWow64フォルダに入れるとファイルが見えました。


> それはそれとして、.NETのDLLは、WindowsのPATHを参照しません。なので、system32に入っていたからといっても実行時に意味はありません。
> 開発時にも、あえてsystem32などに入れる意義はないように思います。

というのはどういう意味ですか?
参照ファイルのローカルコピーをTrueにしていると
デバッグ用のフォルダー、リリース用のフォルダー全てにDLLファイルがコピーされることになるため
これを避けたいと考えています。

https://okwave.jp/qa/q205996.html
このページにも書かれてあるように
一般的なプログラムは、
参照するDLLはEXEが入ったフォルダーか
C:\Windows
C:\Windows\System32

にDLLが入っていれば自動的に読み込んでくれる仕様になっていますが
これと同じことをVSでするにはどうしたら良いですか?






引用返信 編集キー/
■83519 / inTopicNo.4)  Re[3]: DLLが参照できない
□投稿者/ Azulean (806回)-(2017/03/26(Sun) 15:38:31)
2017/03/26(Sun) 16:04:50 編集(投稿者)

No83517 (萌 さん) に返信
> 参照ファイルのローカルコピーをTrueにしていると
> デバッグ用のフォルダー、リリース用のフォルダー全てにDLLファイルがコピーされることになるため
> これを避けたいと考えています。

なぜ避けたいのでしょうか?
そのアプリケーションを自身で利用するなら別かもしれませんが、他者に配布する際は exe と同じフォルダーに置く方が自然だと思うためです。


> 一般的なプログラムは、
> 参照するDLLはEXEが入ったフォルダーか
> C:\Windows
> C:\Windows\System32
> にDLLが入っていれば自動的に読み込んでくれる仕様になっていますが

その仕様は .NET の DLL には適用されないはずです。


> これと同じことをVSでするにはどうしたら良いですか?

あえて対応するものを挙げるとすれば、GAC ですが、コマンドを打って登録する必要があります。
また、GAC にその DLL の作者以外が登録することはおすすめできません。

ほかにはこの辺もありますが、config ファイルに書かないといけないので、やりたいことに対する手間が見合うのかが疑問ですね…。
https://msdn.microsoft.com/ja-jp/library/cskzh7h6%28v=vs.110%29.aspx
引用返信 編集キー/
■83520 / inTopicNo.5)  Re[4]: DLLが参照できない
□投稿者/ 萌 (15回)-(2017/03/26(Sun) 16:36:31)


No83519 (Azulean さん) に返信

> なぜ避けたいのでしょうか?
> そのアプリケーションを自身で利用するなら別かもしれませんが、他者に配布する際は exe と同じフォルダーに置く方が自然だと思うためです。

作業途中に定期的にバックアップをとりながら行っているため、
ファイルサイズは極力小さくしたいためです。

http://www.transsoft.co.jp/blog/?p=802

自分でも調べてみました
EXEより下の階層にはおけるが、上の階層にはおけないというような説明が見つかりました。

http://d.hatena.ne.jp/haradago/20080602/p1

DEVPATHに関しても調べてみたのですが
これは、EXEファイルを別の人に配布した場合、
そのPCでも同様の設定を行う必要があるのでしょうか?
それともVSで開発を行うPCだけでしょうか?

C:\Windows\Microsoft.NET\Framework
には
v2やv3,v4などのバージョンがありますが
全てのフォルダーのconfigファイルをいじる必要がありますか?






引用返信 編集キー/
■83521 / inTopicNo.6)  Re[5]: DLLが参照できない
□投稿者/ Azulean (807回)-(2017/03/26(Sun) 16:40:14)
2017/03/26(Sun) 16:40:56 編集(投稿者)

No83520 (萌 さん) に返信
> DEVPATHに関しても調べてみたのですが
> これは、EXEファイルを別の人に配布した場合、
> そのPCでも同様の設定を行う必要があるのでしょうか?
> それともVSで開発を行うPCだけでしょうか?

「開発者向けの高度な機能」と書かれているように、開発者向けであり、利用者に向けて配布する際の機能ではありません。


> C:\Windows\Microsoft.NET\Framework
> には
> v2やv3,v4などのバージョンがありますが
> 全てのフォルダーのconfigファイルをいじる必要がありますか?

そのように迷うなら、そのくらいのファイルサイズは許容しましょうよ。
なお、変にいじると、.NET アプリケーションに影響を与えますのでご留意ください。
引用返信 編集キー/
■83522 / inTopicNo.7)  Re[3]: DLLが参照できない
□投稿者/ 魔界の仮面弁士 (1223回)-(2017/03/26(Sun) 18:49:46)
No83517 (萌 さん) に返信
>>> 仰る通り、SysWow64フォルダに入れるとファイルが見えました。
>> それはそれとして、.NETのDLLは、WindowsのPATHを参照しません。なので、system32に入っていたからといっても実行時に意味はありません。
>> 開発時にも、あえてsystem32などに入れる意義はないように思います。
> というのはどういう意味ですか?

実行時のアセンブリが参照される順番は、
 (1) DEVPATH 環境変数 (既定では探索対象外)
 (2) グローバル アセンブリ キャッシュ
 (3) 構成ファイル(appName.exe.config) の codeBase
 (4) 実行する EXE のある場所
となっています。開発時の参照設定はまた別の話。
実際 SysWow64 に置いただけでは、開発はできても実行はできないですよね。


「開発時」において、参照設定時に C:\YourFolder\Assembly\Microsoft.WindowsAPICodePack.dll が
列挙されるようにしたいのであれば、レジストリの
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v3.5\AssemblyFoldersEx
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.5\AssemblyFoldersEx
などのバージョン別キーの(既定)に、文字列として「C:\YourFolder\Assembly\」のように、
DLL の置いたフォルダー名を登録します。

これにより、参照設定時のダイアログで、[アセンブリ]-[拡張]欄に表示されるようになります。
あくまでも「開発時」のパスであって、「実行時」には関係ないですけれども。
https://msdn.microsoft.com/ja-jp/library/ee722096.aspx



> 参照するDLLはEXEが入ったフォルダーか
> C:\Windows
> C:\Windows\System32

それはアンマネージ DLL の場合の話ですね。

DllImportAttribute や Declare ステートメントによってロードされる Win32 DLL では、
パスを明示せずにファイル名のみで呼び出されることが多いのですが、その場合、
LoadLibrary API の仕様により、
 (1) EXEファイルのあるフォルダー
 (2) Windows のシステムフォルダー(%windir%\SysWow64 / %windir%System32)
 (3) %windir%\System フォルダー(※Win16 用のパスなので現在は使用されない)
 (4) Windows フォルダー(%windir%)
 (5) 環境変数PATH に設定されているフォルダーを前から順番に
という順番でファイルが探索される仕様になっています。

このタイプの DLL としては、UNZIP32.DLL や UNRAR64.DLL などが挙げられますが、
WindowsAPICodePack の DLL は、このパターンには当てはまりません。


> https://okwave.jp/qa/q205996.html
> このページにも書かれてあるように

上記で説明されているのは、vb6jp.dll と mscomctl.ocx ですね。

前者は、Win32 リソースライブラリ、後者は ActiveX コンポーネントであり、
これらもまた、それぞれ別の種類の DLL だったりします。

後者すなわち ActiveX (COM) のコンポーネントでは、まず最初にレジストリ情報が参照され、
そのレジストリに記載されたパスを元にコンポーネントがロードされる仕組みです。

仕組みが複雑なので細かい点は省きますが、ひとまず mscomctl の場合についていえば、
 HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}
にタイプライブラリ情報が記録されており、MSCOMCTL.OCX の場所がここに記載されています。

DLL ごとに共有されるパスであるがゆえに、ActiveX コンポーネントの配置先は、
結果的に SysWow64/System32 が利用されることが多いですが、すべての がそうではなく、
  C:\Program Files (x86)\Common Files\System\ado\msado15.dll
  C:\Program Files (x86)\Common Files\microsoft shared\DAO\dao360.dll
  %ORACLE_HOME%\bin\oip10.dll
のように、システムフォルダ以外に配置されるケースもあります。

いずれにせよ、配置される場所がシステムフォルダーであることが多い上に、
レジストリ登録を伴うという性質上、この手の DLL は『インストーラー』を使って
配置されるのが一般的です。(配置するために管理者権限が必要となるため)

ただし ActiveX コンポーネントであっても、レジストリ登録無しで、かつ、
EXE と同じフォルダーに配置されるという特殊なパターンも一応あったりします。
https://msdn.microsoft.com/ja-jp/library/cc482775.aspx


> 参照ファイルのローカルコピーをTrueにしていると
> デバッグ用のフォルダー、リリース用のフォルダー全てにDLLファイルがコピーされることになるため
> これを避けたいと考えています。

ローカルコピーで配置することを強くお奨めします。

既に紹介されているように、.NET Assembly な DLL を複数のアプリケーションで共有させるためには
GAC すなわちグローバル アセンブリ キャッシュに配置することになります。

ただし厳密名が無いと指定できないため、アセンブリの署名が必要となります。
自身で作成したライブラリであるならともかく、他者作成のライブラリに対して用いる方法ではありません。


http://www.atmarkit.co.jp/fdotnet/technology/idnfw11_03/idnfw11_03_03.html
http://dobon.net/vb/dotnet/deployment/installgac.html

GAC に存在しない場合、構成ファイル(appName.exe.config) の <codeBase href> から
探索させることはできます。この場合、厳密名のあるアセンブリなら任意のパスを使えますが、
厳密名が無い場合は、EXE のある場所のサブフォルダーしか指定できません。

.config を使うパターンについては、このほか、<probing> や <developmentMode> といった
方法がありますが、probing は厳密名の有無に関わらずあくまでもサブフォルダーしか
指定できません。どちらかというと、単一ソリューションに複数のプロジェクトが
含まれるようなケースなどを想定したものでしょう。

<developmentMode> の方は、環境変数 DEVPATH を利用しますが、既に指摘されているように、
あくまでも「開発者向け」の機能であるため、利用者向けに配置するための機能ではありません。
http://d.hatena.ne.jp/tekk/20110403/1301829578


ちなみに今回の目的からは外れてしまうかと思いますが、DLL を共有したいのではなく、
DLL を配布せずに EXE だけの配置にしたいという意図であるのなら、ILMerge を用いて、
EXE の中に DLL を取り込んでしまうという手もあったりします。
https://www.microsoft.com/en-us/download/details.aspx?id=17630
引用返信 編集キー/
■83525 / inTopicNo.8)  Re[4]: DLLが参照できない
□投稿者/ 萌 (18回)-(2017/03/26(Sun) 22:52:03)
No83522 (魔界の仮面弁士 さん) に返信

非常に勉強になりました
.NETではDLLの置き場所を変えるのが非常に面倒だということが理解できました

普通にSystem32フォルダーを読み込める仕様にしてくれたら良かったのに・・・・

VSでアンマネージ DLL を生成することはできないのでしょうか・・・・?

解決済み
引用返信 編集キー/
■83526 / inTopicNo.9)  Re[5]: DLLが参照できない
□投稿者/ Azulean (808回)-(2017/03/26(Sun) 23:05:07)
2017/03/26(Sun) 23:13:00 編集(投稿者)

No83525 (萌 さん) に返信
> 普通にSystem32フォルダーを読み込める仕様にしてくれたら良かったのに・・・・

逆です。
それで過去に困ったからこそ、今のような考え方になっているのです。
(同じ名前の DLL で異なるものが同じ System32 にあると困るという問題がある)


> VSでアンマネージ DLL を生成することはできないのでしょうか・・・・?

C# や VB.NET において、その選択肢はありません。

追伸
上記は、アンマネージ DLL を .NET に依存しないとした場合において。
DllImport や LoadLibrary / GetProcAddress で使えるようにする細工という意味では魔界の仮面弁士さんが示されている情報が頼りになります。
ただし、この手法は 関数エクスポート ベースになるので、クラスをこの形で公開するのはおすすめしませんが…。
解決済み
引用返信 編集キー/
■83527 / inTopicNo.10)  Re[5]: DLLが参照できない
□投稿者/ 魔界の仮面弁士 (1225回)-(2017/03/26(Sun) 23:10:09)
No83525 (萌 さん) に返信
> VSでアンマネージ DLL を生成することはできないのでしょうか・・・・?

仮にそれができたとしても、それは参照設定して使うことはできるものではなく、
Win32 API と同様に、逐次、DllImport で宣言しないと使えない代物に成り下がってしまうのでは?

https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -