web-dev-qa-db-ja.com

プロジェクトにファイルをプログラムで含める方法は?

バックグラウンド

いくつかのコードファイルを再フォーマットし、他のプロジェクトに追加する新しいコードファイルを作成するヘルパーアプリケーションを作成しているので、すぐに新しいコードを使用できますが、その新しいコードファイルを追加するのは大変です私のプロジェクトに自動的に。ちなみに、C#にあり、ヘルパーアプリはWinFormsです。

失敗した試行

この質問 の唯一の答えはそれを行う2つの方法がありますが、私はそれらのどれも機能させることができませんでした。最初の例では、参照するMicrosoft.Buildアセンブリが見つかりません。もう1つでは、コマンドラインに十分な引数がありません。

質問

サードパーティのアプリケーションを使用せずに、プログラムでファイルをプロジェクトに含めるにはどうすればよいですか?

基本的に、私はこれと同等のものを探しています:

...しかし、コードを使用して行われます。

必要条件

これらは、ソリューションが提供するはずの機能です。

  • ファイルを追加するprojectを持つsolutionを選択します
  • ファイルを追加するprojectを選択します
  • プロジェクト内でdirectoryを選択します
  • そして、もちろん、追加するfileファイル

進捗

ユーザー@ psubsee2003の助けを借りて、コンピューターのMicrosoft.Build.dllフォルダーでC:\Windows\Microsoft.NET\Framework\v4.0.30319ファイルを見つけ、プロジェクトのターゲットフレームワークをバージョン4Fullに変更することで正常にインポートできましたデフォルトのクライアントプロファイルではなく、profile

そして、AddItemメソッドの使用方法を見つけました。

var p = new Microsoft.Build.Evaluation.Project(@"C:\projects\MyProject.csproj");
p.AddItem("Compile", @"C:\folder\file.cs");
p.Save();

プロジェクトにfolderという名前のフォルダーが既にある場合を除き、ファイルはプロジェクトのルートフォルダーに表示されます。その場合、ファイルはそこに配置されます。そのため、基本的にファイルは、ルートフォルダーに向かう元のファイルのパスにある最も深いフォルダーチェーンに配置されます。

37
user1306322

ProjectFolderに追加するだけで機能し、このようにプログラムでフォルダーを追加することもできました。

var p = new Microsoft.Build.Evaluation.Project(@"C:\projects\BabDb\test\test.csproj");
        p.AddItem("Folder", @"C:\projects\BabDb\test\test2");
        p.AddItem("Compile", @"C:\projects\BabDb\test\test2\Class1.cs");
        p.Save();
26
Boot750

Boot750の回答の補足として(最初に彼の回答の編集として提案されましたが、スタンドアロンとして再投稿されました)

new Microsoft.Build.Evaluation.Project(path)を呼び出すと、実際にプロジェクトが_Microsoft.Build.Evaluation_アセンブリによって維持されるグローバルキャッシュにロードされることに注意してください。最初にグローバルコレクションからアンロードせずに同じパスでnew Project(path)を再度呼び出すと、アプリを再起動すると、次のような例外が発生します。

同等のプロジェクト(同じグローバルプロパティとツールバージョンを持つプロジェクト)は、パス "YOUR_PATH"でプロジェクトコレクションに既に存在します。このプロジェクトコレクションに同等のものをロードするには、まずこのプロジェクトをアンロードします。

変数pが範囲外になった場合でも。

したがって、Load/AddItem/Saveパターンを繰り返し使用する場合は、次のようなパターンを採用する必要があります。

_ var p =
Microsoft.Build.Evaluation
  .ProjectCollection.GlobalProjectCollection
    .LoadedProjects.FirstOrDefault(pr => pr.FullPath == projFilePath);

if (p == null)
   p = new Microsoft.Build.Evaluation.Project(projFilePath);
_
10
Caius Jard

これを行う最も簡単な方法は、プロジェクトファイルを変更することです。これは単なるMSBUILDファイルであるため、VSは変更を取得し、プロジェクトをリロードするように要求します。プロジェクトファイルをXMLとしてロードし、最初の<Compile Include="Name of File.cs" />を見つけます。新しい<Compile Include="NewFile.CS" />と完了を挿入します。

別のオプションとして、すべての<Compile>タグを削除し、<Compile Include="*.cs" />で置き換えることができます

6
rerun

@ caius-jardからの応答に追加するだけです

プロジェクトがGlobalProjectCollectionに格納されると、プロジェクトはメモリに保持され、プロジェクトに加えられた手動の変更は反映されません。これには、.csprojファイルの更新と、VSを使用した生成ファイルの削除が含まれます。

生成されたファイルを削除してコードを再度実行すると、プロジェクトは更新され、生成されたファイルが2つ含まれます。 ReevaluateIfNecessary()関数を使用して、次のように使用する前にプロジェクトのインスタンスを更新します。

var p = Microsoft.Build.Evaluation
        .ProjectCollection.GlobalProjectCollection
        .LoadedProjects.FirstOrDefault(pr => pr.FullPath == projFilePath);

if (p == null)
    p = new Microsoft.Build.Evaluation.Project(projFilePath);

// Update instance of project
p.ReevaluateIfNecessary();

// Check folder is not already in the project
var folderLoc = @"C:\projects\BabDb\test\test2";
if(p.Items.FirstOrDefault(i => i.EvaluatedInclude == folderLoc) == null)
    p.AddItem("Folder", folderLoc);

// Check file is not already in the project
var fileLoc = @"C:\projects\BabDb\test\test2\Class1.cs";
if(p.Items.FirstOrDefault(i => i.EvaluatedInclude == fileLoc) == null)
    p.AddItem("Compile", fileLoc);

p.Save();
5
Aetbmo

T4テキストテンプレートを使用できます。詳細については、 http://msdn.Microsoft.com/en-us/library/vstudio/bb126445(v = vs.100).aspx を参照してください。

0
tlango