Comment programmer l'inclusion d'un fichier dans mon projet?

arrière-plan

je fais une application d'aide qui reformate certains fichiers de code et crée de nouveaux fichiers de code, qui doivent être ajoutés à mon autre projet, donc je pourrais utiliser le nouveau code tout de suite, mais j'ai de sérieuses difficultés à ajouter ce nouveau fichier de code dans mon projet automatiquement. D'ailleurs c'est en c# et l'application helper est WinForms.

l'Échec des tentatives

cette question ' s seule réponse a deux façons de faire ça, mais je n'ai pas pu les faire marcher. Avec la première, Je ne trouve pas de référence à une assemblée Microsoft.Build , et dans l'autre, il n'y a clairement pas assez d'arguments pour une ligne de commande.

Question

Comment puis-je par programmation inclure un fichier dans un projet sans l'utilisation d'applications tierces?

en gros, je cherche l'équivalent de ceci:

...Mais fait en utilisant le code.

exigences

ce sont les caractéristiques que je suppose que la solution devrait offrir:

  • sélectionner la solution qui a le projet nous ajoutons le fichier à
  • sélectionner projet dans lequel le fichier doit être ajouté
  • sélectionner répertoire dans le cadre du projet
  • et, bien sûr, le fichier que nous ajoutons

Progrès

avec l'aide de l'utilisateur @psubsee2003 j'ai pu trouver le fichier Microsoft.Build.dll dans le dossier C:WindowsMicrosoft.NETFrameworkv4.0.30319 sur mon ordinateur et l'importer avec succès en changeant le cadre cible de mon projet à la version 4 profil complet , pas le Client par défaut profil.

et j'ai trouvé comment utiliser la méthode AddItem :

var p = new Microsoft.Build.Evaluation.Project(@"C:projectsMyProject.csproj");
p.AddItem("Compile", @"C:folderfile.cs");
p.Save();

Le fichier apparaîtra dans le dossier racine du projet, à moins que le projet avait déjà un dossier appelé folder , auquel cas le fichier sera placé là. Donc, fondamentalement, le fichier sera placé dans la chaîne de dossiers la plus profonde trouvée dans le chemin du fichier original allant vers le dossier racine.

31
demandé sur Community 2013-08-31 08:00:43

5 réponses

cela a fonctionné pour moi juste en ajoutant l'it au ProjectFolder, et aussi ajouter le dossier programmatically comme ceci.

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();
23
répondu Boot750 2014-05-08 08:49:57

comme complément à la réponse de Boot750 (d'abord suggéré comme un montage de sa réponse, mais il semble que quelques pairs critiques myopes pensaient que je parlais à Boot750, alors que j'étais en fait en train d'adopter sa direction de parler à L'OP):

vous devez noter que l'appel à new Microsoft.Build.Evaluation.Project(path) fait que le projet est chargé dans un cache global maintenu par l'Assemblée Microsoft.Build.Evaluation . Appelant new Project(path) encore une fois avec le même chemin, sans le décharger de la global collection first/redémarrer votre application provoquera une exception comme:

un projet équivalent (un projet avec la même version globale de propriétés et d'outils) est déjà présent dans la collection de projets, avec le chemin"YOUR_PATH". Pour charger un équivalent dans cette collection de projets, déchargez d'abord ce projet.

, même si la variable p est sortie du champ d'application.

vous pourriez donc besoin d'adopter un modèle plus comme ceci, si vous prévoyez d'utiliser le Load / AddItem / Save pattern de façon répétée:

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

if (p == null)
   p = new Microsoft.Build.Evaluation.Project(projFilePath);
9
répondu Caius Jard 2017-06-29 17:06:48

la façon la plus simple de faire cela est de modifier le fichier du projet. Comme il s'agit simplement d'un fichier MSBUILD, VS récupérera le changement et demandera de recharger le projet. Chargez le fichier de projet en XML et trouvez le premier <Compile Include="Name of File.cs" /> . Insérez un nouveau <Compile Include="NewFile.CS" /> et votre fait.

comme autre option, vous pouvez supprimer toutes les étiquettes <Compile> et les remplacer par <Compile Include="*.cs" />

5
répondu rerun 2017-04-03 19:44:16

juste pour ajouter à la réponse de @caius-jardin

une fois que le projet est dans la collection Globalproject, il est conservé en mémoire et ne reflète aucun changement manuel apporté au projet. Cela inclut la mise à jour du .csproj et en utilisant VS pour supprimer les fichiers générés.

si vous supprimez le fichier généré et exécutez le code à nouveau le projet mettra à jour pour contenir 2 du fichier généré. Utilisez la fonction Reevaluateifnequary () pour mettre à jour l'instance du projet avant d'utiliser comme ceci:

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();
2
répondu Aetbmo 2017-09-13 20:23:09

vous pouvez utiliser des modèles de texte T4. Voir http://msdn.microsoft.com/en-us/library/vstudio/bb126445 (v = 100).aspx pour plus d'informations.

0
répondu tlango 2013-09-10 18:11:43