none
ClickOnceで発行すると、参照プロジェクトのコンテンツが配布されない RRS feed

  • 質問

  • いつもお世話になります。

    概要:
    VS2013、C#5で開発しています。

    メインのプロジェクト(A、アセンブリはA.exeとします)があり、それをテストするための別プロジェクト(B、アセンブリはB.exeとします)を作っています。

    A.exeは、テキストファイル(contents.txtとします)に依存しており、contents.txtはプロジェクトAの配布時に出力ディレクトリにコピーされるように設定されています(ビルドアクション:コンテンツ、出力ディレクトリにコピー:常にコピーする)。

    さて、プロジェクトBからAを参照し、発行したところ、出力ディレクトリにB.exeはコピーされますが、contents.txtがコピーされません。

    contents.txtを配布するためには、プロジェクトBでAと同様の設定を繰り返す必要があるでしょうか、それとも別の方法がありますか?




    • 編集済み terasato 2014年10月15日 0:50
    2014年10月14日 1:00

回答

  • ClickOnceで発行をすると参照しているプロジェクトのコンテンツが含まれないということですよね?
    #発行じゃなくただのビルドであれば参照プロジェクトのコンテンツも出力されるんですけどね。

    MSDNにClickOnce アプリケーションにデータ ファイルを含めるという方法がありますが簡単じゃないですね。

    一番簡単な方法は、プロジェクトBにcontents.txtを「既存の項目の追加」からファイル選択ダイアログで「リンクとして追加」します。
    そしてビルドアクションを「コンテンツ」として出力ディレクトリにコピーを「コピーする」に設定してやると含まれるようになります。
    プロジェクトBのプロパティの発行ページで、アプリケーションファイルを開いて一覧に含まれているのが確認できます。

    そのほかにも、コンテンツファイルが大量にあって、いちいちBプロジェクトでリンクを張るのが面倒な場合は、コンテンツファイルだけ別プロジェクトにするという方法もあります。
    これはVisualStudioからは直接設定はできないのですが、プロジェクトから別のプロジェクトを参照してImportをするというプロジェクトファイルの基本機能を使って実現できます。
    #Expressでできるかは試してません

    ソリューションのフォルダ構成が以下になっているとします。

    SolutionFolder
    ├A
    │├A.csproj
    │├contents.csproj
    │└contents.txt
    ├B
    │└B.csproj

    なお、contents.csprojは以下のようなう中身の無い、空っぽのプロジェクトでいいです。

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    </Project>

    ソリューションエクスプローラーから既存のプロジェクトの追加で、contents.csprojを追加します。

    次に、A.csprojをメモ帳か、アンロードしたプロジェクトから開いて以下のようにImport Projectタグを追加し保存します。

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    
      <Import Project="..\A\contents.csproj" /> <!-- contents.csprojがA.csprojに対しての相対参照として -->
    
      <PropertyGroup>
        ... 以下略

    同様にB.csprojもメモ帳か、アンロードしたプロジェクトから開いて以下のようにImport Projectタグを追加し保存します。

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    
      <Import Project="..\A\contents.csproj" /> <!-- contents.csprojがB.csprojに対しての相対参照として -->
    
      <PropertyGroup>
        ... 以下略

    VisualStudioのバージョンによってプロジェクトファイルは微妙に異なりますが、必要なタグは同じです。
    VB.Netなどでもプロジェクトフィルの構造はほぼ同じなので、Importで同じことができます。

    あとは、contentsプロジェクトにコンテンツを既存の項目で追加して行きます。

    このときファイル選択ダイアログで追加ボタンでは無く、追加ボタンのドロップダウンから「リンクとして追加」します。
    コンテンツをすべてcontentsプロジェクトに追加できたら、Aプロジェクトからはコンテンツを削除します。

    こうすることでどちらのプロジェクトも同じコンテンツがインポートされて、ビルドしても同じコンテンツが常に含まれるようになり、ClickOnceに含まれるコンテンツとしても認識されるようになります。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク terasato 2014年10月15日 1:01
    2014年10月14日 12:12

すべての返信

  • 質問のタイトルと内容に矛盾があると思いませんか? 投稿する前、そして投稿した後にも、自分の書いた文章におかしな点がないか、確認する習慣をつけましょう。
    とりあえず、BがAに依存しているという趣旨のみ汲み取って話を進めますが、まずソリューションエクスプローラーでプロジェクトBを右クリックして、[プロジェクト依存関係]を実行し、プロジェクトAにチェックがなされているかどうか確認してください。参照設定を行なっただけでは、依存関係が適切に設定されないことがあります。
    ちなみにAがDLLの場合は、正しく設定すればAのコンテンツファイルが普通にBの出力先にもコピーされることは確かなので、EXEだからといって挙動が変わることはないと思われますが、Visual C#とVisual C++では出力設定の方法が異なることがあります。複数の言語が混在するソリューションの場合も注意が必要です。まずは開発環境のバージョンと言語をきちんと書きましょう。
    • 編集済み sygh 2014年10月14日 9:07
    2014年10月14日 8:59
  • ClickOnceで発行をすると参照しているプロジェクトのコンテンツが含まれないということですよね?
    #発行じゃなくただのビルドであれば参照プロジェクトのコンテンツも出力されるんですけどね。

    MSDNにClickOnce アプリケーションにデータ ファイルを含めるという方法がありますが簡単じゃないですね。

    一番簡単な方法は、プロジェクトBにcontents.txtを「既存の項目の追加」からファイル選択ダイアログで「リンクとして追加」します。
    そしてビルドアクションを「コンテンツ」として出力ディレクトリにコピーを「コピーする」に設定してやると含まれるようになります。
    プロジェクトBのプロパティの発行ページで、アプリケーションファイルを開いて一覧に含まれているのが確認できます。

    そのほかにも、コンテンツファイルが大量にあって、いちいちBプロジェクトでリンクを張るのが面倒な場合は、コンテンツファイルだけ別プロジェクトにするという方法もあります。
    これはVisualStudioからは直接設定はできないのですが、プロジェクトから別のプロジェクトを参照してImportをするというプロジェクトファイルの基本機能を使って実現できます。
    #Expressでできるかは試してません

    ソリューションのフォルダ構成が以下になっているとします。

    SolutionFolder
    ├A
    │├A.csproj
    │├contents.csproj
    │└contents.txt
    ├B
    │└B.csproj

    なお、contents.csprojは以下のようなう中身の無い、空っぽのプロジェクトでいいです。

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    </Project>

    ソリューションエクスプローラーから既存のプロジェクトの追加で、contents.csprojを追加します。

    次に、A.csprojをメモ帳か、アンロードしたプロジェクトから開いて以下のようにImport Projectタグを追加し保存します。

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    
      <Import Project="..\A\contents.csproj" /> <!-- contents.csprojがA.csprojに対しての相対参照として -->
    
      <PropertyGroup>
        ... 以下略

    同様にB.csprojもメモ帳か、アンロードしたプロジェクトから開いて以下のようにImport Projectタグを追加し保存します。

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    
      <Import Project="..\A\contents.csproj" /> <!-- contents.csprojがB.csprojに対しての相対参照として -->
    
      <PropertyGroup>
        ... 以下略

    VisualStudioのバージョンによってプロジェクトファイルは微妙に異なりますが、必要なタグは同じです。
    VB.Netなどでもプロジェクトフィルの構造はほぼ同じなので、Importで同じことができます。

    あとは、contentsプロジェクトにコンテンツを既存の項目で追加して行きます。

    このときファイル選択ダイアログで追加ボタンでは無く、追加ボタンのドロップダウンから「リンクとして追加」します。
    コンテンツをすべてcontentsプロジェクトに追加できたら、Aプロジェクトからはコンテンツを削除します。

    こうすることでどちらのプロジェクトも同じコンテンツがインポートされて、ビルドしても同じコンテンツが常に含まれるようになり、ClickOnceに含まれるコンテンツとしても認識されるようになります。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク terasato 2014年10月15日 1:01
    2014年10月14日 12:12
  • ご指摘ありがとうございます。DLLでもEXEでも変わらないからいいかと思って放置しておりました。じゃあ各必要もない、ということですね。gekka様の返信も踏まえて、一部編集いたしました。

    お気づきの点がございましたら、またご教授ください。ありがうございました。

    2014年10月15日 0:57
  • 「リンクとして追加」という発送はありませんでした! ありがとうございます。
    プロジェクトBでも「database」ディレクトリを作らないといけない、などの煩雑さはありますが、
    ファイルの同一性を保つことができますし、プロジェクトAにはできるだけ手を入れたくないので、
    こちらの方法を採用したいと思います。

    別プロジェクトを作ってしまう、という方法も目からうろこでした。丁寧に解説してくださってありがとうございました。

    また機会がありましたらよろしくお願い致します。

    2014年10月15日 1:01