c# - proyectos - windows forms c++ visual studio 2017
¿Cómo incluir programáticamente un archivo en mi proyecto? (5)
Como un complemento a la respuesta de Boot750 (primero sugerido como una edición de su respuesta, pero parece que algunos de los pares críticos miopes pensaron que estaba hablando con Boot750, cuando en realidad estaba adoptando su dirección de hablar con el OP):
Debe tener en cuenta que la llamada al new Microsoft.Build.Evaluation.Project(path)
hace que el proyecto se cargue en un caché global mantenido por el ensamblado Microsoft.Build.Evaluation
. Llamar a new Project(path)
nuevamente con la misma ruta, sin descargarlo de la colección global primero / reiniciar su aplicación causará una excepción como:
Un proyecto equivalente (un proyecto con la misma versión global de propiedades y herramientas) ya está presente en la colección del proyecto, con la ruta "YOUR_PATH". Para cargar un equivalente en esta colección de proyectos, descargue este proyecto primero.
incluso si la variable p
ha salido del alcance.
Por lo tanto, es posible que deba adoptar un patrón como este, si planea usar el patrón Cargar / Añadir / Guardar varias veces:
var p =
Microsoft.Build.Evaluation
.ProjectCollection.GlobalProjectCollection
.LoadedProjects.FirstOrDefault(pr => pr.FullPath == projFilePath);
if (p == null)
p = new Microsoft.Build.Evaluation.Project(projFilePath);
Fondo
Estoy creando una aplicación de ayuda que reformatea algunos archivos de código y crea nuevos archivos de código, que se agregarán a mi otro proyecto, para poder usar el nuevo código de inmediato, pero estoy teniendo serias dificultades para agregar ese nuevo archivo de código en mi proyecto automáticamente Por cierto, está en c # y la aplicación de ayuda es WinForms.
Intentos fallidos
La única respuesta de esta pregunta tiene dos formas de hacerlo, pero no pude hacer que ninguna de ellas funcionara. Con el primero no puedo encontrar un ensamblado Microsoft.Build
como referencia, y en el otro claramente no hay suficientes argumentos para una línea de comando.
Pregunta
¿Cómo incluyo un archivo por programación en un proyecto sin el uso de aplicaciones de terceros?
Básicamente, estoy buscando el equivalente de esto:
... Pero hecho usando código.
Requisitos
Estas son las características que supongo que la solución debería ofrecer:
- Seleccione la solución que tiene el proyecto al que estamos agregando el archivo
- Seleccionar el proyecto en el que se agregará el archivo
- Seleccionar el directorio dentro del proyecto
- Y, por supuesto, el archivo que estamos agregando
Progreso
Con la ayuda del usuario @ psubsee2003, pude encontrar el archivo Microsoft.Build.dll
en la carpeta C:/Windows/Microsoft.NET/Framework/v4.0.30319
en mi computadora e importarlo exitosamente cambiando el marco de destino de mi proyecto a la versión 4 completa. perfil , no el perfil de cliente predeterminado.
Y encontré cómo usar el método AddItem
:
var p = new Microsoft.Build.Evaluation.Project(@"C:/projects/MyProject.csproj");
p.AddItem("Compile", @"C:/folder/file.cs");
p.Save();
El archivo aparecerá en la carpeta raíz del proyecto a menos que el proyecto ya tenga una carpeta llamada folder
, en cuyo caso el archivo se colocará allí. Así que, básicamente, el archivo se colocará en la cadena de carpetas más profunda que se encuentre en la ruta del archivo original hacia la carpeta raíz.
Funcionó para mi solo agregarlo a ProjectFolder, y también agregar la carpeta de forma programática como esta.
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();
La forma más sencilla de hacerlo es modificar el archivo de proyecto. Como es solo un archivo MSBUILD, VS recogerá el cambio y le pedirá que vuelva a cargar el proyecto. Cargue el archivo del proyecto como un XML y encuentre el primer <Compile Include="Name of File.cs" />
. Inserta un nuevo <Compile Include="NewFile.CS" />
y listo.
Como otra opción, puede eliminar todas las etiquetas <Compile>
y reemplazarlas por <Compile Include="*.cs" />
Podría usar plantillas de texto T4. Consulte http://msdn.microsoft.com/en-us/library/vstudio/bb126445(v=vs.100).aspx para obtener más información.
Solo para agregar a la respuesta de @ caius-jard
Una vez que el proyecto está en GlobalProjectCollection, se guarda en la memoria y no refleja ningún cambio manual realizado en el proyecto. Esto incluye la actualización del archivo .csproj y el uso de VS para eliminar los archivos generados.
Si elimina el archivo generado y ejecuta nuevamente el código, el proyecto se actualizará para contener 2 del archivo generado. Utilice la función Reevaluate IfNecessary () para actualizar la instancia del proyecto antes de usarlo de la siguiente manera:
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();