私は次のプロジェクト構造を持っています:
_Library1 <--[project reference]-- Library2 <--[ref]-- Executable
-------- -------- ----------
ContentFile .cs files .cs files
.cs files
_
すべてのプロジェクト参照にはCopyLocal = trueがあります。
プロジェクトをビルドすると、ContentFile
は_Library2
_の出力ディレクトリにコピーされますが、Executable
の出力ディレクトリにはコピーされません。つまり、実行可能ファイルにContentFile
がない場合アプリケーションが実行されます。
コンテンツファイルが_Library2
_の出力ディレクトリにコピーされているのに、Executable
にはコピーされていないのはなぜですか?後者にもコピーする方法はありますか(人々はそれを忘れると確信しているので、ビルドイベントなしでそれを行いたいです)?
私は合理的で保守可能なソリューションを探しています。新しいプロジェクトまたはの新しい間接的に参照されるコンテンツファイルを追加するときに最小限の労力で済むため、単にそれを忘れることはほとんどありません。
ビルド後のイベントの使用(_xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug
_など)。プロジェクトの出力ディレクトリをデフォルト(プロジェクトごと)ではなく$(SolutionDir)/bin/...
に手動で設定すると、どちらもすぐに大きな混乱になります。 「メインプロジェクト」にリンクとしてコンテンツファイルを追加するのも面倒でした。 C#の出力ファイルのデフォルト設定がVisual C++と同じ(つまり、_$SolutionDir/$Platform/$Configuration
_)であれば問題ありませんが、そうではありません。
また、標準のMSBuildプロシージャをまったく使用せず、カスタムビルドターゲットを作成することも検討しました(Atmel Studioでgccを使用するなど)が、まったくうまくいきませんでした。さらに、VisualStudioの標準の「ビルド」コマンドと「デバッグ」コマンドを通常どおりに機能させたいと考えています。
これが私がしていることの詳細です。
Executable
プロジェクトの解決策があります。さらに、Plugin
sと呼ぶことができるプロジェクトがたくさんあります。 Executable
は、管理対象プロジェクト参照を介して、これらすべてのPlugin
sを参照します。
プラグインプロジェクトは実行可能ファイルに合わせて調整されますが、再利用可能なコンポーネントが含まれる場合があるため、主な機能はExternal
プロジェクトに実装されることが多く、Plugin
プロジェクトは単なるラッパーのままです(常にではありません)。
上記のExternal
プロジェクトでは、サードパーティが提供するネイティブDLLを使用する場合があります。これらのDLLは、コンテンツファイルとしてExternal
プロジェクトに追加され、_Copy to output dir
_が_Copy always
_に設定されます。したがって、構造は上の図のようになります。
_External <---------------[is not aware of]--------------------+
-------- |
.cs files <--[reference]-- PluginWrapper <--[reference]-- Executable
"Native DLL" ------------- ----------
.cs files .cs files
_
奇妙なことに、「ネイティブDLL」はExternal
の出力ディレクトリ(明らかに)にコピーされますおよびPluginWrapper
's、しかしないExecutable
。
開発者のワークフローは、完全に分離されたエンティティとして機能するExternal
を作成することです(それらはは頻繁に再利用されます)、ラップしますPluginWrapper
を使用して、PluginWrapper
へのプロジェクト参照のみをExecutable
に追加します。これが明らかに非常に珍しいことであるのは奇妙だと思います。
Executable
のMSBuildターゲットXMLを編集して(間接的に参照されるコンテンツファイルも含めるように)、問題を解決できたのではないかと思いました。
提案されているように、DLLを埋め込みリソースとしてプロジェクトに追加することを検討したいと思うかもしれませんが、そのようなネイティブDLLを埋め込むことは私には奇妙に思えます。結局、上の図から「[認識していない]」を削除し、プロジェクト参照をExternal
に追加して開発者のワークフローを変更することは、Brenda Bellが提案したように、最も賢明な解決策かもしれません。理想的ではありません。
アップデート2
埋め込まれたリソースのアイデアがすべての場合に機能するとは限らないことに注意してください。実行可能ファイルのディレクトリ(cwdなどではない)に依存関係を配置する必要がある場合は、インストールフォルダーに管理者権限がないため(埋め込みリソースからファイルを解凍するため)、これが機能しない場合があります。奇妙に聞こえますが、これは私たちが使用していたサードパーティのライブラリの1つで深刻な問題でした。
Library1参照を実行可能プロジェクトに追加します。
編集:
すべてのコンテンツを別のプロジェクトに配置し、そのすべてのエントリを「コンテンツ」と「常にコピー」に設定して、外部および実行可能ファイルからそのプロジェクトを参照できます。
-
コンテンツファイルではなく、埋め込みリソースを探しているIMO。
ライブラリ1をコンパイルすると、コンテンツファイルはそのbinフォルダーに配置されます。ライブラリ2がコンパイルされると、コンパイラは参照されたコードを認識してそれを含めます(Library 1.dll)が、ライブラリ2のどこにも言及されていないため、コンテンツファイルは認識されません。ライブラリ2を実行可能ファイルにリンクする場合も同様です。
コンテンツファイルが比較的小さく(アイコン、テンプレートなど)、ソースコードを紛失した場合に編集する必要がないと思われる場合は、それらをリソースとして埋め込み、コンテンツを返すためのパブリックメソッドを提供できます。 :
public static Stream GetResourceContent(string rName){
string resName = System.Reflection.Assembly
.GetExecutingAssembly().GetManifestResourceNames()
.FirstOrDefault(rn => rn.EndsWith("."+rName));
if(resName!=null)
return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resName);
else
return null;
}
テンプレートなどのコンテンツが変更される可能性がある場合は、実行可能プロジェクトにコピーを含めることを検討してください
もう1つのオプションは、ContentFileをLibrary1 Assembly内のリソースとして埋め込み、Assembly.GetManifestResource()を使用して抽出することです。
詳細については、次のリンクを参照してください。
http://www.attilan.com/2006/08/accessing-embedded-resources-using.html
ブレンダの答えの1つのバリエーションは、Library1のコンテンツファイルを実行可能プロジェクトのリンクとして追加することです。プロジェクトにはまだエントリがありますが、各ファイルの複数のコピーを管理する必要はありません。
XAMLファイルからのみLibrary1を参照している可能性があります。その場合、VisualStudioは使用法を認識しません。コードにも参照を追加します。例: name属性を適用する