tipos sirve saber que para objetivos objetivo nikon macro lentes lente focal distancia con compatibles compatible compatibilidad como canon camara msbuild

msbuild - sirve - objetivo zoom



¿Cómo consultar el archivo MSBUILD para la lista de objetivos compatibles? (5)

Me encantó la idea de usar PowerShell, pero la solución XML pura no funciona porque solo genera los objetivos definidos en ese archivo de proyecto, y no las importaciones. Por supuesto, el código de C # al que todos se refieren es completamente simple, y con .Net 4.5 son dos líneas (la primera de las cuales debería considerar agregar a su perfil):

Add-Type -As Microsoft.Build New-Object Microsoft.Build.Evaluation.Project $Project | Select -Expand Targets

Sí. De Verdad. Eso es todo.

Dado que el resultado es muy detallado, es posible que desee restringir lo que está viendo:

New-Object Microsoft.Build.Evaluation.Project $Project | Select -Expand Targets | Format-Table Name, DependsOnTargets -Wrap

Sin embargo, hay una condición.

Cuando carga compilaciones como esas, se quedan en GlobalProjectCollection siempre que deje abierta la ventana de PowerShell y no pueda volver a abrirlas hasta que las descargue. Para descargarlos:

[Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.UnloadAllProjects()

Teniendo en cuenta eso, podría valer la pena incluir eso en una función que puede aceptar rutas parciales y relativas o incluso archivos de proyecto canalizados como entrada:

Add-Type -As Microsoft.Build Update-TypeData -DefaultDisplayPropertySet Name, DependsOnTargets -TypeName Microsoft.Build.Execution.ProjectTargetInstance function Get-Target { param( # Path to project file (supports pipeline input and wildcards) [Parameter(ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=1)] [Alias("PSPath")] [String]$Project, # Filter targets by name. Supports wildcards [Parameter(Position=2)] [String]$Name = "*" ) begin { # People do funny things with parameters # Lets make sure they didn''t pass a Project file as the name ;) if(-not $Project -and $Name -ne "*") { $Project = Resolve-Path $Name if($Project) { $Name = "*" } } if(-not $Project) { $Project = Get-Item *.*proj } } process { Write-Host "Project: $_ Target: $Name" Resolve-Path $Project | % { # Unroll the ReadOnlyDictionary to get the values so we can filter ... (New-Object Microsoft.Build.Evaluation.Project "$_").Targets.Values.GetEnumerator() } | Where { $_.Name -like $Name } } end { [microsoft.build.evaluation.projectcollection]::globalprojectcollection.UnloadAllProjects() } }

Y ahora ni siquiera necesita formatear Format-Table ...

Apéndice:

Obviamente, puede agregar cualquier cosa que desee al resultado con Update-TypeData, por ejemplo, si desea ver Condiciones, o quizás BeforeTargets o AfterTargets ...

Incluso podría extraer información anidada. Por ejemplo, podría reemplazar la llamada a Update-TypeData anterior con estos dos:

Update-TypeData -MemberName CallTargets -MemberType ScriptProperty -Value { $this.Children | ? Name -eq "CallTarget" | %{ $_.Parameters["Targets"] } } -TypeName Microsoft.Build.Execution.ProjectTargetInstance Update-TypeData -DefaultDisplayPropertySet Name, DependsOnTargets, CallTargets -TypeName Microsoft.Build.Execution.ProjectTargetInstance

Verá que el primero agrega una propiedad CallTargets calculada que enumera los elementos secundarios directos y busca tareas de CallTarget para imprimir sus Objetivos, y luego solo incluimos ese elemento en DefaultDisplayPropertySet .

NOTA: Tomaría mucha lógica sobre esto para ver cada objetivo que se va a ejecutar cuando se construye un objetivo en particular (para eso, tendríamos que procesar recursivamente los DependsOnTargets y también tendríamos que buscar cualquier objetivo que tenga este objetivo en sus BeforeTargets o AfterTargets (también de manera recursiva), y eso es antes de que lleguemos a tareas que realmente pueden llamar objetivos, como CallTargets y MSBuild ... y todas estas cosas pueden depender de condiciones tan complejas que es imposible decir qué va a pasar sin realmente ejecutarlo;)

¿Hay alguna manera de preguntarle a msbuild qué objetivos de compilación proporciona el soporte de archivos msbuild? Si no hay forma de hacerlo en el símbolo del sistema? ¿Puede ser que se podría hacer programáticamente?

¿No hay forma de hacerlo además de analizar msbuild XML?


Ciertamente MS proporciona la API para hacer esto sin analizar el xml usted mismo. Busque microsoft.build.buildengine

Adaptado de algún código C # encontrado en msdn ... por lo general vale la pena explorarlo. Necesita hacer referencia al dll de microsoft.build.engine para que esto se compile. Reemplace la versión del marco y la ruta a continuación con sus valores. Esto funcionó en un archivo de proyecto de muestra, aunque la lista puede ser más larga de lo esperado.

using System; using Microsoft.Build.BuildEngine; class MyTargets { static void Main(string[] args) { Engine.GlobalEngine.BinPath = @"C:/Windows/Microsoft.NET/Framework/v2.0.NNNNN"; Project project = new Project(); project.Load(@"c:/path/to/my/project.proj"); foreach (Target target in project.Targets) { Console.WriteLine("{0}", target.Name); } } }


Actualizado para .NET Framework 4, ya que lo anterior ha quedado en desuso. Importar microsoft.build.dll y el código es el siguiente:

using System; using Microsoft.Build.Evaluation; class MyTargets { static void Main(string[] args) { Project project = new Project(args[0]); foreach (string target in project.Targets.Keys) { Console.WriteLine("{0}", target); } } }


Te sugiero que uses PowerShell:

Select-Xml ` -XPath //b:Target ` -Path path-to-build-file ` -Namespace @{ b = ''http://schemas.microsoft.com/developer/msbuild/2003'' } | Select-Object -ExpandProperty Node | Format-Table -Property Name, DependsOnTargets -AutoSize

La consulta XPath encontrará todos los elementos de Target y mostrará el nombre de destino y las dependencias en formato de tabla. Aquí hay una muestra que selecciona los 10 primeros objetivos de Microsoft.Web.Publishing.targets :

PS C:/Program Files (x86)/MSBuild/Microsoft/VisualStudio/v11.0/Web> Select-Xml ` -XPath //b:Target ` -Path Microsoft.Web.Publishing.targets ` -Namespace @{ b = ''http://schemas.microsoft.com/developer/msbuild/2003'' } | Select-Object -ExpandProperty Node | Sort-Object -Property Name | Select-Object -First 10 | Format-Table -Property Name, DependsOnTargets -AutoSize Name DependsOnTargets ---- ---------------- _CheckPublishToolsUpToDate _CheckRemoteFx45 _CleanWPPIfNeedTo _DetectDbDacFxProvider _WPPCopyWebApplication $(_WPPCopyWebApplicationDependsOn) AddContentPathToSourceManifest $(AddContentPathToSourceManifestDepe... AddDeclareParametersItems $(AddDeclareParametersItemsDependsOn) AddDeclareParametersItemsForContentPath $(AddDeclareParametersItemsForConten... AddDeclareParametersItemsForIis6 $(AddDeclareParametersItemsForIis6De... AddDeclareParametersItemsForIis7 $(AddDeclareParametersItemsForIis7De...


Aquí está el fragmento de código para obtener todos los objetivos en el orden en que se ejecutan.

static void Main(string[] args) { Project project = new Project(@"build.core.xml"); var orderedTargets = GetAllTargetsInOrderOfExecution(project.Targets, project.Targets["FinalTargetInTheDependencyChain"]).ToList(); File.WriteAllText(@"orderedTargets.txt", orderedTargets.Select(x => x.Name).Aggregate((a, b) => a + "/r/n" + b)); } /// <summary> /// Gets all targets in the order of their execution by traversing through the dependent targets recursively /// </summary> /// <param name="allTargetsInfo"></param> /// <param name="target"></param> /// <returns></returns> public static List<ProjectTargetInstance> GetAllTargetsInOrderOfExecution(IDictionary<string, ProjectTargetInstance> allTargetsInfo, ProjectTargetInstance target) { var orderedTargets = new List<ProjectTargetInstance>(); var dependentTargets = target .DependsOnTargets .Split('';'') .Where(allTargetsInfo.ContainsKey) .Select(x => allTargetsInfo[x]) .ToList(); foreach (var dependentTarget in dependentTargets) { orderedTargets = orderedTargets.Union(GetAllTargetsInOrderOfExecution(allTargetsInfo, dependentTarget)).ToList(); } orderedTargets.Add(target); return orderedTargets; }