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, afin que je puisse utiliser le nouveau code tout de suite, mais j'ai de la difficulté à ajouter ce nouveau fichier de code dans mon projet automatiquement. Au fait, c'est en c # et l'application d'assistance est WinForms.
Cette question La seule réponse a deux façons de le faire, mais je n'ai pu en faire fonctionner aucune. Avec le premier, je ne trouve pas de Microsoft.Build
Assembly à référencer, et dans l'autre il n'y a clairement pas assez d'arguments pour une ligne de commande.
Comment inclure par programmation un fichier dans un projet sans utiliser d'applications tierces?
Fondamentalement, je cherche l'équivalent de ceci:
... Mais fait en utilisant du code.
Ce sont les fonctionnalités que je suppose que la solution devrait offrir:
Avec l'aide de l'utilisateur @ psubsee2003, j'ai pu trouver le Microsoft.Build.dll
fichier dans C:\Windows\Microsoft.NET\Framework\v4.0.30319
dossier sur mon ordinateur et l'importer avec succès en modifiant le cadre cible de mon projet en version 4 Profil complet , pas le profil client par défaut.
Et j'ai trouvé comment utiliser la méthode AddItem
:
var p = new Microsoft.Build.Evaluation.Project(@"C:\projects\MyProject.csproj");
p.AddItem("Compile", @"C:\folder\file.cs");
p.Save();
Le fichier apparaîtra dans le dossier racine du projet sauf si le projet avait déjà un dossier appelé folder
, auquel cas le fichier y sera placé. Donc, fondamentalement, le fichier sera placé dans la chaîne de dossiers la plus profonde trouvée dans le chemin du fichier d'origine vers le dossier racine.
Cela a fonctionné pour moi juste en l'ajoutant au ProjectFolder, et également ajouter le dossier par programme 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();
En complément de la réponse de Boot750 (d'abord suggéré comme une modification de sa réponse, mais republié en tant que version autonome)
Vous devez noter que l'appel à new Microsoft.Build.Evaluation.Project(path)
provoque le chargement du projet dans un cache global géré par l'assembly Microsoft.Build.Evaluation
. Appeler à nouveau new Project(path)
avec le même chemin, sans le décharger d'abord de la collection globale/redémarrer votre application provoquera une exception comme:
Un projet équivalent (un projet avec les mêmes propriétés globales et la même version 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 hors de portée.
Vous devrez donc peut-être adopter un modèle plus semblable à celui-ci, si vous prévoyez d'utiliser le modèle Load/AddItem/Save à plusieurs reprises:
var p =
Microsoft.Build.Evaluation
.ProjectCollection.GlobalProjectCollection
.LoadedProjects.FirstOrDefault(pr => pr.FullPath == projFilePath);
if (p == null)
p = new Microsoft.Build.Evaluation.Project(projFilePath);
La façon la plus simple de procéder consiste à modifier le fichier Project. Comme il ne s'agit que d'un fichier MSBUILD, VS récupérera la modification et vous invitera à recharger le projet. Chargez le fichier de projet au format XML et recherchez le premier <Compile Include="Name of File.cs" />
. Insérez un nouveau <Compile Include="NewFile.CS" />
et vous avez terminé.
Comme autre option, vous pouvez supprimer tous les <Compile>
balises et remplacez-les par <Compile Include="*.cs" />
Juste pour ajouter à la réponse de @ caius-jard
Une fois que le projet est dans GlobalProjectCollection, il est conservé en mémoire et ne reflète aucune modification manuelle apportée au projet. Cela inclut la mise à jour du fichier .csproj et l'utilisation de VS pour supprimer les fichiers générés.
Si vous supprimez le fichier généré et exécutez à nouveau le code, le projet sera mis à jour pour contenir 2 du fichier généré. Utilisez la fonction ReevaluateIfNecessary () pour mettre à jour l'instance du projet avant de l'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();
Vous pouvez utiliser des modèles de texte T4. Voir http://msdn.Microsoft.com/en-us/library/vstudio/bb126445 (v = vs.100) .aspx pour plus d'informations.