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.
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.
How would you go about mimicking (or directly using) msbuild's assembly resolution process?
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.
This should show you how to do what you really want, but I think you should use the FXCop answer I provided.
To directly mimic the CLR resolution process you could write a custom MSBuild task although I don't see what it would achieve.
MSBuild doesn't resolve assemblies. They are resolved by the CLR. This article describes how the runtime resolves assemblies: http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx
When you are in Visual Studio the System assemblies come from the filesystem, but when they are loaded at runtime they come from the GAC. http://p3net.mvps.org/Topics/Basics/IntegratingGACWithVS.aspx
If you still have questions please clarify.
This might help: Resolving Binary References in MSBuild
If you get yourself a free copy of Reflector, you can examine the internals of the MSBuild.exe file itself. I notice there is a class
that has a method called
which may help?
Anyway, with reflector you can get the code, and hopefully reuse the system directly.
Why not just call msbuild against your project or solution file, pass it the /v:d extension, and parse the output file for the information you want? For instance, you'll see something like the following for each assembly resolution:
Alternatively, MSBuild delegates the task of resolving assemblies to the Microsoft.Build.Tasks.ResolveAssemblyReference class from the Microsoft.Build.Tasks.v3.5 assembly (in my case, building against the 3.5 framework). You can parse the project file and supply an instance of ResolveAssemblyReference with the appropriate (meta)data, and let it perform the resolution for you - seems perfect, since that's exactly what MSBuild does.
If you target the Framework version you want to be compatible with instead of targeting 3.5, Visual Studio 2008 SP1 and FxCop 1.36 RTM added rule CA 1903: Use only API from targeted framework to ensure you stay compatible with the target framework version. Turning that rule on and treating it as an error will fail your Build and provide the behavior you want.
Here is sample code demonstrating a violation when you are targeting framework version 2: