DOBON.NETプログラミング道掲示板

■34647 / 親記事)  .Net 5.0 におけるDLL参照問題?
  
□投稿者/ あばば無人君 一般人(24回)-(2021/02/20(Sat) 12:41:50)
  • アイコン環境/言語:[Windows10(2004) 64bit、.Net 5.0、VS2019(16.8.5)Com版、C#] 
    分類:[.NET] 

    いつも本掲示板でお勉強させていただいております。

    さてタイトルの件ですが、現在以下2つのプロジェクトがあります。
    ・プロジェクトA:DLL
    ・プロジェクトB:プロジェクトAを参照するWinFormアプリ(EXE)

    プロジェクトBは上記の通り依存関係(昔のVSで言う"参照")の
    設定にて、プロジェクトAの出力ディレクトリにあるDLLを
    参照しています。

    この状態でビルド後プロジェクトBの出力ディレクトリを見ると
    BのEXEだけでなくAのDLL+PDBも存在していました。

    Aの出力ディレクトリにあるDLL+PDBとバイナリ比較しましたが
    差異は有りませんでした。また、EXEは普通に実行できました。

    問題はここからなのですが、ビルド後Bの出力ディレクトリに
    AのDLL+PDBをコピーさせない様にするため、Bの依存関係にある
    Aのプロパティを表示し、「ローカルにコピー」をいいえに
    設定しました。

    この状態でビルドすると想定通りBの出力ディレクトリに
    AのDLL+PDBは配置されなくなりました。
    もちろんEXEの実行にも失敗します。
    (イベントビューアーのアプリケーションログにエラーが出る)

    ところがAの出力ディレクトリにあるDLL+PDBをコピーして
    Bの出力ディレクトリに持ってきても、EXEの実行に失敗します。

    AのDLL+PDBを持ってくれば「ローカルにコピー」をいいえに
    する前と同じ状態になっている筈なのに何故実行に失敗するのか
    理由が分かりません。
    (昔の.Net Frameworkで同じことをしたら実行できた様な気が…)

    理由が分かる方がいらっしゃいましたら教えて頂きたいです。
    また、コピーしてきてからEXEを動かせる様にする方法も
    ご存知でしたら併せて教えて頂きたいです。

    以上です。宜しくお願い致します。

マルチポストを報告
違反を報告
引用返信 削除キー/
■34648 / ResNo.1)  Re[1]: .Net 5.0 におけるDLL参照問題?
□投稿者/ あばば無人君 一般人(25回)-(2021/02/20(Sat) 12:54:55)
  • アイコンすみません、補足です。
    EXEの実行失敗ですが、イベントビューアーの内容は以下です。

    Application: ProjectB.exe
    CoreCLR Version: 5.0.321.7212
    .NET Version: 5.0.3
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.IO.FileNotFoundException: Could not load file or assembly 'ProjectA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. 指定されたファイルが見つかりません。
    File name: 'ProjectA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
    at ProjectB.Form1..ctor()
    at ProjectB.Program.Main() in パスは見せられないよ!\ProjectB\Program.cs:line 20

違反を報告
引用返信 削除キー/
■34649 / ResNo.2)  Re[1]: .Net 5.0 におけるDLL参照問題?
□投稿者/ Azulean 大御所(525回)-(2021/02/20(Sat) 15:47:13)
  • アイコン2021/02/20(Sat) 15:48:14 編集(投稿者)

    .NET Core / .NET 5 以降においては .NET Framework での常識はある程度捨てないといけません。

    No34647に返信(あばば無人君さんの記事)
    > AのDLL+PDBを持ってくれば「ローカルにコピー」をいいえに
    > する前と同じ状態になっている筈なのに何故実行に失敗するのか
    > 理由が分かりません。
    > (昔の.Net Frameworkで同じことをしたら実行できた様な気が…)

    ローカルコピーを「いいえ」にすると、deps.json に依存関係が記述されなくなります。
    deps.json に書かれていないアセンブリはアプリと同じフォルダーであっても読み込まれなくなります。

    deps.json 自体が存在しなければ、.NET Framework 時代に近い動きになるかもしれませんが…。

    参考
    https://github.com/dotnet/cli/blob/v2.0.0/Documentation/specs/corehost.md#assembly-resolution


    とりあえず、ローカルコピー「いいえ」でなんとかするやり方はやめた方が良いと思います。
    そのプロジェクト A から先に依存するパッケージの情報なども引き継がれなくなるので、.NET 5 として作っていく上でダメージ大きいと予想されるため。
違反を報告
引用返信 削除キー/
■34650 / ResNo.3)  Re[2]: .Net 5.0 におけるDLL参照問題?
□投稿者/ あばば無人君 一般人(26回)-(2021/02/20(Sat) 18:39:20)
  • アイコンAzuleanさん、ご返信ありがとうございます。

    > ローカルコピーを「いいえ」にすると、deps.json に依存関係が記述されなくなります。
    > deps.json に書かれていないアセンブリはアプリと同じフォルダーであっても読み込まれなくなります。

    上記ですが、個人的にはう〜んって感じです。
    VisualStudio上ではローカルコピーを「いいえ」にしていても
    プロジェクトAのDLLにある関数などは使える(ビルドも通る)のに、
    いざ実際にEXEを起動しようとするとdeps.jsonに記述が無いから
    DLLがあっても読み込まない→そして起動に失敗するって、これでは
    ローカルコピーの設定が何のためにあるのかわかりません。

    こんな開発者を混乱させる動きにするぐらいならそもそも
    ローカルコピーの設定自体無い方がよい気がしました。
    何か意味/メリットってありますかね…?


    > とりあえず、ローカルコピー「いいえ」でなんとかするやり方はやめた方が良いと思います。

    現状そうするしかありませんね…。
    ローカルコピーはありにして、他のDLLやEXEを全て手動で纏める
    開発方針にします。


    他の記述含めご返信、ありがとうございました。
    (愚痴っぽくなってしまい申し訳ありませんでした)

違反を報告
引用返信 削除キー/
■34651 / ResNo.4)  Re[3]: .Net 5.0 におけるDLL参照問題?
□投稿者/ Azulean 大御所(526回)-(2021/02/20(Sat) 18:51:12)
  • アイコンNo34650に返信(あばば無人君さんの記事)
    > VisualStudio上ではローカルコピーを「いいえ」にしていても
    > プロジェクトAのDLLにある関数などは使える(ビルドも通る)のに、
    > いざ実際にEXEを起動しようとするとdeps.jsonに記述が無いから
    > DLLがあっても読み込まない→そして起動に失敗するって、これでは
    > ローカルコピーの設定が何のためにあるのかわかりません。

    お望みのことを満たすための機能ではないということでしょう。

    ・ビルド時に参照する DLL と、実行時に使う DLL が異なるとき
     →その DLL は別途インストールするなど、アプリケーションの固有 DLL ではない。

    ・ソリューションが何十ものプロジェクトで構成されていて、個別にコピーしているとディスクコピーが多くてビルドが長くなる
     →アプリケーションプロジェクトだけコピーするようにしたい


    「同一ソリューションでプロジェクト参照して何もいじらない」がスタンダードな使い方です。
    ローカルコピーをいじる必要なんて .NET Framework 時代でもほぼなかったはずですので。
違反を報告
引用返信 削除キー/
■34652 / ResNo.5)  Re[4]: .Net 5.0 におけるDLL参照問題?
□投稿者/ あばば無人君 一般人(27回)-(2021/02/21(Sun) 13:02:55)
  • アイコンAzuleanさん、ご返信ありがとうございます。

    > ・ビルド時に参照する DLL と、実行時に使う DLL が異なるとき
    >  →その DLL は別途インストールするなど、アプリケーションの固有 DLL ではない。

    上記ですが、私の知識不足かご記載の内容が理解できません。

    ビルド時に参照するDLLと、実行時に使うDLLが異なっていても
    いなくても、deps.jsonに記述が無ければEXEの起動に失敗する
    結果は一緒ではないでしょうか?

    別途インストールするDLLだと、deps.jsonに記述が無くても
    EXEの起動が成功するケースがあったりするのでしょうか?


    > ・ソリューションが何十ものプロジェクトで構成されていて、個別にコピーしているとディスクコピーが多くてビルドが長くなる
    >  →アプリケーションプロジェクトだけコピーするようにしたい

    なるほど!ビルド時間は盲点でした。
    コピーの工程が無くなればビルド時間が短くなるという
    メリットはありますね。

    ただ、deps.jsonに記述が無いのでEXEの起動に失敗するという
    結果は変わらない様な気がしますが。


    > 「同一ソリューションでプロジェクト参照して何もいじらない」がスタンダードな使い方です。

    確かにスタンダードの1つです。
    ですが、フレームワークとなるDLLの開発と、そのDLLを使った
    業務案件の開発などとで、ソリューションが異なることもよくある
    ケースかと思います。


    > ローカルコピーをいじる必要なんて .NET Framework 時代でもほぼなかったはずですので。

    それを言ってしまうと、前回の私の投稿にある
    > ローカルコピーの設定自体無い方がよい気がしました。
    と、同じ感じになりませんか?


    …なんかいまいち会話が噛み合っていない様な気がします。

違反を報告
引用返信 削除キー/
■34653 / ResNo.6)  Re[5]: .Net 5.0 におけるDLL参照問題?
□投稿者/ Azulean 大御所(527回)-(2021/02/21(Sun) 16:42:43)
  • アイコン2021/02/21(Sun) 16:48:49 編集(投稿者)

    No34652に返信(あばば無人君さんの記事)
    > …なんかいまいち会話が噛み合っていない様な気がします。

    私は「こう思う」と主張しているだけで、合意を得たいわけでもないですし、開発チームの思いを代弁できるわけでもありませんので、その点は理解いただければ。

    とりあえず、「.NET 5 世代でローカルコピーを触ることはほぼない」言えると思います。
    (有用なケースは、ビルド時間短縮の工夫で存在するとは思います)


    > ビルド時に参照するDLLと、実行時に使うDLLが異なっていても
    > いなくても、deps.jsonに記述が無ければEXEの起動に失敗する
    > 結果は一緒ではないでしょうか?

    アプリケーションと一緒にインストールするとは限らないのでは?と考えてこのように書きましたが、GAC の概念が廃止されていることを考えると、このシナリオは存在しないかもしれません。
    調査不足ですみません。。。

    (ADDITIONAL_DEPS で無理矢理追加することはできそうですが、一般的とは言えないかもしれません)
    https://docs.microsoft.com/ja-jp/dotnet/core/dependency-loading/default-probing#host-configured-probing-properties


    > ただ、deps.jsonに記述が無いのでEXEの起動に失敗するという
    > 結果は変わらない様な気がしますが。

    「アプリケーションプロジェクトだけコピーするようにしたい」で示したつもりでしたが、書き方を改めると「アプリケーションプロジェクトで参照し、ローカルコピーする」ということです。
    ビルドイベントや手作業のコピーの話ではありません。

    > ですが、フレームワークとなるDLLの開発と、そのDLLを使った
    > 業務案件の開発などとで、ソリューションが異なることもよくある
    > ケースかと思います。

    その DLL だけのコピーで異なるソリューションへ配布・連携してしまうと、外部依存関係が引き継がれないので、DLL 単位での配布・連携はそろそろやめた方が良いかもしれません。
    .NET 5 の開発では NuGet パッケージに依存することが多いため、その外部依存関係をきちんと伝搬しないと、deps.json に記載がなくて実行時エラーになりかねません。

    ソリューションを分けないといけなくなったら、ローカルの NuGet パッケージ作らないといけないかもしれませんね。

    なお、本格的に業務で取り組む状況になっていないので、最適論はわかりません。
    .NET 5 のサポートも来年 1 月で終わる短期ものなので(LTS ではないので)、移行する企業は少ないのではないでしょうか?


    > それを言ってしまうと、前回の私の投稿にある
    >>ローカルコピーの設定自体無い方がよい気がしました。
    > と、同じ感じになりませんか?

    「安易に使うと起動しない exe になるなら、そんな設定見せるべきじゃない」は極端じゃないですか?
    ビルド時間短縮に効果のある技としては使えるので、わかっていて使う人が使うには良いでしょう。
    (このプロパティの存在を知っていて使っている人は .NET 開発者の中で多数派とは言えないはず…)

    あくまで私は「このように思う」を書いているのであって、機能の存在意義を議論したいわけではありません。
    もし、存在意義がないから機能をなくすべきでは…と提案したいのであれば、Developer Community に挙げてください。
違反を報告
引用返信 削除キー/
■34654 / ResNo.7)  Re[6]: .Net 5.0 におけるDLL参照問題?
□投稿者/ あばば無人君 一般人(28回)-(2021/02/22(Mon) 11:57:04)
  • アイコンAzuleanさん、ご返信ありがとうございます。

    > アプリケーションと一緒にインストールするとは限らないのでは?と考えてこのように書きましたが、GAC の概念が廃止されていることを考えると、このシナリオは存在しないかもしれません。

    GACの概念、廃止になったのですね。恥ずかしながら知りませんでした。
    確かにGACがあれば、deps.jsonに記述が無くてもEXEは起動しそうですね。



    > 「アプリケーションプロジェクトだけコピーするようにしたい」で示したつもりでしたが、書き方を改めると「アプリケーションプロジェクトで参照し、ローカルコピーする」ということです。
    > ビルドイベントや手作業のコピーの話ではありません。

    上記、理解いたしました。


    > 「安易に使うと起動しない exe になるなら、そんな設定見せるべきじゃない」は極端じゃないですか?
    > ビルド時間短縮に効果のある技としては使えるので、わかっていて使う人が使うには良いでしょう。

    確かに早計でした。撤回します。

    (ビルド時間短縮で使ったとして、結局そのままだと
    deps.jsonに記述が無いのでEXEの起動に失敗するから
    自分で記述を追加しないといけない手間を考えると
    個人的にはやはりメリットは見えませんが…)



    だいぶ話が逸れてしまいましたが、私の3つ目の投稿の通り、
    > ローカルコピーはありにして、他のDLLやEXEを全て手動で纏める
    > 開発方針にします。
    として本件は解決済みとさせていただきます。

    何度もご回答いただきありがとうございました。

解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -