问题描述
我写一个验证工具,用于检查项目中的引用文件的版本。我想使用的MSBuild使用相同的解决过程。
I am writing a validation tool that checks the versions of files referenced in a project. I want to use the same resolution process that MSBuild uses.
例如,的Assembly.Load(..)需要一个完全合格的程序集名称。然而,在项目文件中,我们可能只有类似的System.Xml。的MSBuild可能使用该项目的目标框架版本和其他一些启发,决定要加载哪个的System.Xml版本。
For example, Assembly.Load(..) requires a fully-qualified assembly name. However, in the project file, we may only have something like "System.Xml". MSBuild probably uses the project's target framework version and some other heuristics to decide which version of System.Xml to load.
您会如何去模仿(或直接使用)的MSBuild的装配解决过程?
How would you go about mimicking (or directly using) msbuild's assembly resolution process?
在换句话说,在运行时,我想借此字符串的System.Xml,用在.csproj的文件中找到的其他信息一起找到同一个文件的MSBuild会找到的。
In other words, at run-time, I want to take the string "System.Xml", along with other info found in a .csproj file and find the same file that msbuild would find.
推荐答案
我今天有这个问题,我发现这是如何的老博客文章要做到这一点:
I had this problem today, and I found this old blog post on how to do it:
的
我尝试过了,作品大!我修改了代码找到4.5.1版本的组件时可能的,这就是我现在:
I tried it out, works great! I modified the code to find 4.5.1 versions of assemblies when possible, this is what I have now:
#if INTERACTIVE
#r "Microsoft.Build.Engine"
#r "Microsoft.Build.Framework"
#r "Microsoft.Build.Tasks.v4.0"
#r "Microsoft.Build.Utilities.v4.0"
#endif
open System
open System.Reflection
open Microsoft.Build.Tasks
open Microsoft.Build.Utilities
open Microsoft.Build.Framework
open Microsoft.Build.BuildEngine
/// Reference resolution results. All paths are fully qualified.
type ResolutionResults = {
referencePaths:string array
referenceDependencyPaths:string array
relatedPaths:string array
referenceSatellitePaths:string array
referenceScatterPaths:string array
referenceCopyLocalPaths:string array
suggestedBindingRedirects:string array
}
let resolve (references:string array, outputDirectory:string) =
let x = { new IBuildEngine with
member be.BuildProjectFile(projectFileName, targetNames, globalProperties, targetOutputs) = true
member be.LogCustomEvent(e) = ()
member be.LogErrorEvent(e) = ()
member be.LogMessageEvent(e) = ()
member be.LogWarningEvent(e) = ()
member be.ColumnNumberOfTaskNode with get() = 1
member be.ContinueOnError with get() = true
member be.LineNumberOfTaskNode with get() = 1
member be.ProjectFileOfTaskNode with get() = "" }
let rar = new ResolveAssemblyReference()
rar.BuildEngine <- x
rar.IgnoreVersionForFrameworkReferences <- true
rar.TargetFrameworkVersion <- "v4.5.1"
rar.TargetedRuntimeVersion <- "v4.5.1"
rar.TargetFrameworkDirectories <- [||] //[|@"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\"|]
rar.Assemblies <- [|for r in references -> new Microsoft.Build.Utilities.TaskItem(r) :> ITaskItem|]
rar.AutoUnify <- true
rar.SearchPaths <- [| "{CandidateAssemblyFiles}"
"{HintPathFromItem}"
"{TargetFrameworkDirectory}"
// "{Registry:Software\Microsoft\.NetFramework,v3.5,AssemblyFoldersEx}"
"{AssemblyFolders}"
"{GAC}"
"{RawFileName}"
outputDirectory |]
rar.AllowedAssemblyExtensions <- [| ".exe"; ".dll" |]
rar.TargetProcessorArchitecture <- "x86"
if not (rar.Execute()) then
failwith "Could not resolve"
{
referencePaths = [| for p in rar.ResolvedFiles -> p.ItemSpec |]
referenceDependencyPaths = [| for p in rar.ResolvedDependencyFiles -> p.ItemSpec |]
relatedPaths = [| for p in rar.RelatedFiles -> p.ItemSpec |]
referenceSatellitePaths = [| for p in rar.SatelliteFiles -> p.ItemSpec |]
referenceScatterPaths = [| for p in rar.ScatterFiles -> p.ItemSpec |]
referenceCopyLocalPaths = [| for p in rar.CopyLocalFiles -> p.ItemSpec |]
suggestedBindingRedirects = [| for p in rar.SuggestedRedirects -> p.ItemSpec |]
}
[<EntryPoint>]
let main argv =
try
let s = resolve([| "System"
"System.Data"
"System.Core, Version=4.0.0.0"
"Microsoft.SqlServer.Replication" |], "")
printfn "%A" s.referencePaths
finally
ignore (System.Console.ReadKey())
0
这篇关于该MSBuild的过程极似大会决议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!