<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Suzanne Cook's .NET CLR Notes : Loader Info</title><link>http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx</link><description>Tags: Loader Info</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Channel 9 Interview</title><link>http://blogs.msdn.com/suzcook/archive/2005/02/11/channel-9-interview.aspx</link><pubDate>Sat, 12 Feb 2005 02:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:371395</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/371395.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=371395</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=371395</wfw:comment><description>&lt;A href="http://blogs.msdn.com/lifeontitan/archive/2004/04/26/120368.aspx" mce_href="http://blogs.msdn.com/lifeontitan/archive/2004/04/26/120368.aspx"&gt;Charles Torre&lt;/A&gt; and &lt;A href="http://scobleizer.com/" mce_href="http://scobleizer.com/"&gt;Robert Scoble&lt;/A&gt; (behind the camera) dropped by my office to chat with me about the loader for MSDN's Channel 9: &lt;A href="http://channel9.msdn.com/ShowPost.aspx?PostID=40856" mce_href="http://channel9.msdn.com/ShowPost.aspx?PostID=40856"&gt;part I&lt;/A&gt; and &lt;A href="http://channel9.msdn.com/ShowPost.aspx?PostID=41389" mce_href="http://channel9.msdn.com/ShowPost.aspx?PostID=41389"&gt;part II&lt;/A&gt;.&lt;BR&gt;&lt;FONT color=white&gt;Also, check out the PDC video I was in for Channel 9: http://channel9.msdn.com/ShowPost.aspx?PostID=79591 &lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=371395" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>New Assembly, Old .NET (and Vice-Versa)</title><link>http://blogs.msdn.com/suzcook/archive/2005/01/26/new-assembly-old-net-and-vice-versa.aspx</link><pubDate>Thu, 27 Jan 2005 01:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:361092</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/361092.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=361092</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=361092</wfw:comment><description>&lt;P&gt;I typically recommend that you build &lt;U&gt;and&lt;/U&gt; test your assemblies against the same version of .NET that you will be running them against. That way, you'll have correct references and avoid surprises from behavior differences between builds.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Older assembly, newer .NET&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;But, sometimes you don't run against the same version that you built against. For example, the latest available CLR is the default when interop causes it to be loaded. Or, if &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/06/20/57191.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/06/20/57191.aspx"&gt;the version of the CLR the assembly was built against&lt;/A&gt; is not available, the latest version can also be used instead. If there is a compatibility problem with that for your application, you can force the use of a preferred CLR version by &lt;A href="http://blogs.msdn.com/suzcook/archive/2004/05/14/132022.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2004/05/14/132022.aspx"&gt;using an app.config&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Compatibility&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Yes, there are going to be behavior differences between versions - no way around it. It is the .NET team's goal to be as backwards compatible as realistically possible between versions. But, some changes are required - new features are added which sometimes require (hopefully minimal) behavior changes&amp;nbsp;in other features. If we were required to never break any app, ever, we wouldn't be able to fix any bugs or add any features for fear that someone, somewhere relied on the broken behavior in some strange way. As Dll Hell has&amp;nbsp;shown in the past, new versions of components aren't &lt;EM&gt;really&lt;/EM&gt; compatible.&amp;nbsp;The only guaranteed 100% compatible version is the same one you tested against.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;V2+ assembly, older .NET&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Say you see a BadImageFormatException for hresult 0x80131107 (CLDB_E_FILE_OLDVER) with message "Version [...] is not a compatible version." That means that you've tried to load an assembly built against a newer version of the CLR than was running.&lt;/P&gt;
&lt;P&gt;This fails because&amp;nbsp;new files can't be opened&amp;nbsp;on an older CLR that does not understand them. You will need to either use the v2 CLR to load the v2/v1 assemblies, or load only v1 assemblies on the v1 CLR. That's just good practice, anyway. If you try to use an older .NET than you built against, a method you built against may not exist, etc.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=361092" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Versioning/Deploying Unmanaged Files</title><link>http://blogs.msdn.com/suzcook/archive/2004/10/28/versioning-deploying-unmanaged-files.aspx</link><pubDate>Fri, 29 Oct 2004 00:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:249280</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/249280.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=249280</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=249280</wfw:comment><description>&lt;P&gt;An unmanaged dll can be wrapped in a managed assembly by adding it as a file of a multi-module assembly. Then, it can be deployed and versioned in the same way as managed assemblies. (So, that assembly could contain nothing but metadata and unmanaged code - no managed code, if you prefer. It can also contain multiple unmanaged files in the same assembly.)&lt;/P&gt;
&lt;P&gt;If your compiler does not support this directly, you can get this to work by adding that file as a&amp;nbsp;linked managed resource. For example, see Visual Studio's /linkresource option (if using it for command line compiling).&lt;/P&gt;
&lt;P&gt;This is useful in the case where DllImport() is used to access a function in that file. That call should be updated with the new assembly's info. For example, in the place of &lt;I&gt;"unmanagedfile.dll"&lt;/I&gt;, change it to include the &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx"&gt;display name&lt;/A&gt; like this: &lt;I&gt;"unmanagedfile.dll, managedassembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&lt;/I&gt;.&lt;/P&gt;
&lt;P&gt;If that unmanaged file needs to be loaded by LoadLibrary() outside of DllImport(), however, it will need to follow the rules of LoadLibrary(), like the usual unmanaged file use outside the CLR. (See &lt;A href="http://blogs.msdn.com/junfeng/archive/2004/07/14/181932.aspx" mce_href="http://blogs.msdn.com/junfeng/archive/2004/07/14/181932.aspx"&gt;Junfeng's blog&lt;/A&gt; for an extra tip regarding that when using v2.)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=249280" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Load(AssemblyName)</title><link>http://blogs.msdn.com/suzcook/archive/2004/08/04/load-assemblyname.aspx</link><pubDate>Wed, 04 Aug 2004 23:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:208232</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/208232.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=208232</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=208232</wfw:comment><description>&lt;P&gt;Calling Load(AssemblyName) is not necessarily the same as calling Load(String). If the AssemblyName.CodeBase is &lt;EM&gt;not&lt;/EM&gt; set, then they do do the same thing. So, if you've set the AssemblyName.Name, CultureInfo, public key token / public key and/or Version properties, it would be the same as if you had specified those properties in a String (as a &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx"&gt;display name&lt;/A&gt;) and passed that to Load(String).&lt;/P&gt;
&lt;P&gt;If the&amp;nbsp;CodeBase is set,&amp;nbsp;but the Name is &lt;EM&gt;not&lt;/EM&gt;, however, then it's the same as calling Assembly.LoadFrom() on that CodeBase.&lt;/P&gt;
&lt;P&gt;When both the CodeBase and the Name are set, then the bind is tried with all the given binding information except the CodeBase (so, again, just like calling Load(String)). If that succeeds, we're done. But, if that fails, then the bind is tried again with just the CodeBase (just like LoadFrom()). If it fails again, then, of course, the whole bind fails. But, if it succeeds, then we verify that the binding properties in the AssemblyName match the found assembly. If they don't match, a FileLoadException will be thrown for hresult FUSION_E_REF_DEF_MISMATCH.&lt;/P&gt;
&lt;P&gt;So, setting both the CodeBase and the Name is useful for when you want to both load an assembly at a given path into the LoadFrom context, and verify that it has the public key token, etc. that you expect. Of course, as described above (and due to &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx"&gt;binding context rules&lt;/A&gt;), keep in mind that just because you call Load(AssemblyName) with a CodeBase, it&amp;nbsp;does not mean that it will be loaded from that path.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=208232" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>App.config Examples</title><link>http://blogs.msdn.com/suzcook/archive/2004/05/14/132022.aspx</link><pubDate>Fri, 14 May 2004 16:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:132022</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>25</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/132022.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=132022</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=132022</wfw:comment><description>&lt;P&gt;Below are three examples of useful &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/06/02/57160.aspx"&gt;application configuration files&lt;/A&gt;.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Forces the v1.0 CLR to be run.&amp;nbsp;If the v1.0 CLR is not installed, the app will fail to run.&lt;BR&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;lt;?xml version ="1.0"?&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;lt;configuration&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;startup&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;requiredRuntime version="v1.0.3705"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;supportedRuntime version="v1.0.3705"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/startup&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;lt;/configuration&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;LI&gt;Redirects &amp;#8220;assemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=25283151a234958d&amp;#8220; to version 2.0.0.0 of that assembly. This is only useful for strongly-named assemblies, since versions don't matter for those that are simply-named.&lt;BR&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;lt;?xml version ="1.0"?&amp;gt; &lt;BR&gt;&amp;lt;configuration&amp;gt; &lt;BR&gt;&amp;lt;runtime&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependentAssembly&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;assemblyIdentity name="assemblyName" culture="" publicKeyToken="25283151a234958d"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependentAssembly&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/assemblyBinding&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;lt;/runtime&amp;gt; &lt;BR&gt;&amp;lt;/configuration&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;LI&gt;Redirects &amp;#8220;assemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8968ee41e78ce97a&amp;#8220; to codebase &amp;#8220;http://www.yourwebsite.com/filename.dll&amp;#8220;. 'Href' can also be set to something like &amp;#8220;file:///c:/localfile/filename.dll&amp;#8220;. Note that redirecting to a codebase causes a System.Net.WebPermission or System.IO.FileIOPermissionAccess.Read + PathDiscovery demand when loading that assembly.&lt;BR&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;lt;?xml version ="1.0"?&amp;gt; &lt;BR&gt;&amp;lt;configuration&amp;gt; &lt;BR&gt;&amp;lt;runtime&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependentAssembly&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;assemblyIdentity name="assemblyName" culture="" publicKeyToken="8968ee41e78ce97a"/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;codeBase version="1.0.0.0"&amp;nbsp;href="http://www.yourwebsite.com/filename.dll"/&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependentAssembly&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/assemblyBinding&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#808080&gt;&amp;lt;/runtime&amp;gt;&lt;BR&gt;&amp;lt;/configuration&amp;gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=132022" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Determining Whether a File Is an Assembly</title><link>http://blogs.msdn.com/suzcook/archive/2004/03/17/determining-whether-a-file-is-an-assembly.aspx</link><pubDate>Thu, 18 Mar 2004 08:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:91715</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/91715.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=91715</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=91715</wfw:comment><description>&lt;P&gt;A file is an assembly if and only if it's managed and it contains an Assembly entry in its CLR metadata. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Determining by hand&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;A fast way to determine whether a file is an assembly is to run ildasm.exe on it. If it immediately gives an error saying that&amp;nbsp;it may not be a PE file, then it's not a managed file. But, if it is an assembly, then ildasm will show an entry for the Assembly definition (“.assembly“ in the MANIFEST window or at the bottom of the original window). &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Determining programmatically&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;From unmanaged code, you can call GetAssemblyFromScope() on the IMetaDataAssemblyImport interface for the file. If it returns S_OK, it's an assembly. If it returns CLDB_E_RECORD_NOTFOUND, it's not an assembly. &lt;/P&gt;
&lt;P&gt;From managed code, if AssemblyName.GetAssemblyName(), Assembly.Load*(), etc. succeeds when given that file, then it's an assembly. If the load failed with a BadImageFormatException, then it may not be an assembly. There are other reasons, however,&amp;nbsp;why that exception may have been thrown (maybe it's an assembly but could not be loaded because it has an incorrect format). Coming soon in v2, if the hresult for&amp;nbsp;BadImageFormatException is COR_E_ASSEMBLYEXPECTED, then it's because it's not an assembly. Catch the exception and call System.Runtime.InteropServices.Marshal.GetHRForException() to get its hresult to find out. &lt;/P&gt;
&lt;P&gt;Note that this assumes that you are not concerned about performance. If you are concerned about that, then the way to optimize for it is to &lt;EM&gt;&lt;U&gt;not&lt;/U&gt; try to determine whether files are assemblies at runtime at all&lt;/EM&gt;. (Some people are concerned about the exception that is thrown if the file is not an assembly. They overlook that in order to determine that it is not one, it has to be loaded and then thrown away, which&amp;nbsp;can be&amp;nbsp;even more expensive than catching an exception!) Instead, require that only assemblies are given to you. Then, if a file is not an assembly, it will be an exceptional situation. That way, you avoid the bad perf of both the exception and the unnecessary file loading.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=91715" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>LoadFile vs. LoadFrom</title><link>http://blogs.msdn.com/suzcook/archive/2003/09/19/loadfile-vs-loadfrom.aspx</link><pubDate>Sat, 20 Sep 2003 04:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57248</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57248.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57248</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57248</wfw:comment><description>&lt;P&gt;Be careful - these aren't the same thing. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;LoadFrom() goes through Fusion and can be redirected to another assembly at a different path but with that same &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx"&gt;identity&lt;/A&gt; if one is already loaded in the LoadFrom context. 
&lt;LI&gt;LoadFile() doesn't bind through Fusion at all - the loader just goes ahead and loads exactly&lt;FONT color=#ff0000&gt;*&lt;/FONT&gt; what the caller requested. It doesn't use either the Load or the LoadFrom context.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So, LoadFrom() usually gives you what you asked for, but not necessarily. LoadFile() is for those who really, really want exactly what is requested. (&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;*&lt;/FONT&gt;&lt;/STRONG&gt;However, starting in v2, policy will be applied to both LoadFrom() and LoadFile(), so LoadFile() won't necessarily be exactly what was requested.&amp;nbsp;Also, starting in v2, if an assembly&amp;nbsp;with its identity is in the GAC,&amp;nbsp;the GAC copy&amp;nbsp;will be used instead. Use ReflectionOnlyLoadFrom() to load exactly what you want -&amp;nbsp;but, note that&amp;nbsp;assemblies loaded that way can't be executed.)&lt;/P&gt;
&lt;P&gt;LoadFile() has a catch. Since it doesn't use a&amp;nbsp;binding context, its dependencies aren't automatically found in its directory. If they aren't available in the Load context, you would have to subscribe to the AssemblyResolve event in order to bind to them. &lt;/P&gt;
&lt;P&gt;So, which one should you use? That depends on &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx"&gt;which binding context is right for you&lt;/A&gt; and whether it matters that the LoadFrom context may redirect the bind. Regarding the latter: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If no other code can load assemblies in your AppDomain, your LoadFrom() call can prevent a redirect&lt;FONT color=#ff0000&gt;*&lt;/FONT&gt; by just not loading anything else with a duplicate identity. 
&lt;LI&gt;If you do need to load a duplicate, you could get away with it by loading it into anything other than the LoadFrom context (or into another AppDomain) instead. 
&lt;LI&gt;But, maybe the redirect is really okay. Are they identical assemblies, just at different paths? If yes, it may be safe to risk the redirect unless its dependencies aren't available in the dir of the first one loaded. 
&lt;LI&gt;Or, are they possibly different bits, just with the same assembly identity? If so, it may be unsafe to risk the redirect: maybe you'll get an more-updated/not-as-updated version which you didn't expect. Or, if it's not strongly-named, maybe this is a third-party's assembly, totally unrelated to the one you expect. &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57248" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>LoadFrom's Second Bind</title><link>http://blogs.msdn.com/suzcook/archive/2003/09/16/loadfrom-s-second-bind.aspx</link><pubDate>Wed, 17 Sep 2003 03:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57247</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57247.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57247</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57247</wfw:comment><description>&lt;P&gt;Pre-v2, when you load an assembly by path through Fusion (LoadFrom(), ExecuteAssembly(), etc.), it can actually cause two binds, not just one. The first bind loads the file at the given path. If that is successful, another bind is done with the &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx"&gt;display name&lt;/A&gt; of that assembly to see if it's available in the Load context. If it's not available, the LoadFrom() call is still successful - we throw away the results of the second bind. If it is available, we check the path returned from the first bind against the path from the second bind. If they're identical, we keep the Load context IAssembly and throw away the LoadFrom one. (That means that that assembly will be in the Load context, not the LoadFrom context.) Otherwise, we keep the LoadFrom context IAssembly. &lt;/P&gt;
&lt;P&gt;This is to ensure that the Load context remains order-&lt;STRONG&gt;in&lt;/STRONG&gt;dependent - an important part of the design for that context. It's an implementation detail, but I bring it up because it has some side-effects that are surprising to customers: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The second bind shows up in the Fusion log. (It's just another bind to Fusion.) It's unsettling to see a failure in the log (for the second bind) when the LoadFrom() call succeeded. 
&lt;LI&gt;Doing a second bind by display name causes probing which slows down the performance of LoadFrom(), especially over http, when the file isn't found immediately. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Fusion has stopping doing the second bind in v2. But, when using an older CLR, customers can avoid both side-effects by putting a redirect from the display name to the codebase in a &lt;A href="http://blogs.msdn.com/suzcook/archive/2004/05/14/132022.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2004/05/14/132022.aspx"&gt;config file&lt;/A&gt;. That will skip probing, helping perf, and, assuming it's the correct codebase, avoid a Fusion log noting an ignorable failure. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57247" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Avoid DevPath</title><link>http://blogs.msdn.com/suzcook/archive/2003/08/15/avoid-devpath.aspx</link><pubDate>Sat, 16 Aug 2003 04:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57238</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57238.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57238</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57238</wfw:comment><description>&lt;P&gt;I hesitate to talk about this because I don't want people who don't know about it to think, "Hey, what's this DevPath thing? I need that." But, maybe if I don't explain how to use it, it will be too much effort for people who don't already know how. :) (And, for those who already know how and are, in fact, using it, hopefully, they'll see this and get off that plan.) &lt;/P&gt;
&lt;P&gt;The intent of DevPath was to make the development environment less painful. Assemblies could be put there and bound to at runtime, ignoring the assembly version and overriding the GAC. &lt;/P&gt;
&lt;P&gt;It turns out that that's badness for several reasons (below). So, DevPath is&amp;nbsp;soon to be&amp;nbsp;deprecated. Don't use it - not even in the development environment. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Why It Should Never Be Used&lt;/B&gt; &lt;BR&gt;Versioning alone is why you should never, &lt;I&gt;ever&lt;/I&gt; use it in a production environment. It subscribes your users to dll hell. See &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/30/57159.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/30/57159.aspx"&gt;Avoid Partial Binds&lt;/A&gt; for details (DevPath causes partial binding, since the version is ignored for the bind). &lt;/P&gt;
&lt;P&gt;It's not good for the dev. env., either - it makes it unnecessarily different from the shipping env., which may lead to uncaught versioning or deployment bugs in the shipping env. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;What to Do Instead&lt;/B&gt; &lt;BR&gt;&lt;I&gt;If DevPath was a development environment-only solution for you:&lt;/I&gt; &lt;BR&gt;I strongly recommend &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57148.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57148.aspx"&gt;not changing your assembly versions between non-shipping builds&lt;/A&gt; instead of using DevPath. &lt;/P&gt;
&lt;P&gt;&lt;I&gt;If you are shipping code relying on DevPath:&lt;/I&gt; &lt;BR&gt;One thing you could do is create a new AppDomain with the ApplicationBase set to the path you care about. Once you do that, see &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/06/12/57169.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/06/12/57169.aspx"&gt;Executing Code in Another Appdomain&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;If there are multiple paths you want to load assemblies from, use PrivateBinPath or multiple AppDomains. If that's not reasonable for you, consider using the &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx"&gt;LoadFrom context&lt;/A&gt;. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57238" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Binding to .NET Frameworks Assemblies</title><link>http://blogs.msdn.com/suzcook/archive/2003/07/30/binding-to-net-frameworks-assemblies.aspx</link><pubDate>Thu, 31 Jul 2003 04:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57235</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57235.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57235</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57235</wfw:comment><description>&lt;P&gt;By "Frameworks assemblies," I mean the assemblies that ship with the CLR. But, I'm not counting &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/06/30/57203.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/06/30/57203.aspx"&gt;mscorlib.dll&lt;/A&gt;, since it's special in a different way. &lt;/P&gt;
&lt;P&gt;With v1.0 SP3 or later, Frameworks assemblies are unified. That means that the version of those assemblies that you request is ignored - you get the version that matches the loaded CLR. This only applies when the assembly is loaded by version - that is, by &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx"&gt;assembly display name&lt;/A&gt; or static reference (AssemblyRef in the CLR metadata). &lt;/P&gt;
&lt;P&gt;For example, if the v1.1 CLR is loaded and you request v1.0's system.dll, then you'll get the v1.1 system.dll back. If you load it by path from c:\foo\system.dll, however, then you'll get c:\foo\system.dll back, not the v1.1 system.dll. &lt;/P&gt;
&lt;P&gt;Those assemblies are unified because the owners of the code feel that they are so closely tied to the CLR/mscorlib.dll that they should not be loaded with a different version than they were built against. Additionally, there are some cases where they expect that only one copy of the Frameworks assemblies be loaded in a given process. &lt;/P&gt;
&lt;P&gt;If the v1.0 (pre-SP3) CLR is loaded, though, you will get the assembly that you ask for. Unification isn't done for Frameworks assemblies in that version. &lt;/P&gt;
&lt;P&gt;Do not rely on this behavior. You should still fully-specify assembly references with the correct version. That's just good practice, in general. Besides, if your assembly is loaded in a CLR later than v2.0, those references may not be unified, so you may get unexpected behavior. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57235" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Assembly Identity</title><link>http://blogs.msdn.com/suzcook/archive/2003/07/21/assembly-identity.aspx</link><pubDate>Tue, 22 Jul 2003 01:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57232</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57232.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57232</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57232</wfw:comment><description>&lt;P&gt;There are two types of assembly identity that the loader deals with: bind-time and after bind-time. The identity is used to determine whether we will consider a certain assembly to be the same thing as an assembly reference or another assembly. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Assembly Binding&lt;/B&gt; &lt;BR&gt;At assembly-bind time, the components of the &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57137.aspx"&gt;assembly display name&lt;/A&gt; determine identity. This will be used to match an assembly reference (the assembly that the user wants to load) to a manifest file. &lt;/P&gt;
&lt;P&gt;Not all of the components matter in all cases. If the assembly is not strongly-named, then the version is ignored for binding. But, if it is strongly-named, the entire version in the assembly reference needs to match the found assembly. &lt;/P&gt;
&lt;P&gt;There are other details about what is and isn't necessary to specify for binding, but &lt;FONT color=#ff0000&gt;please always give the entire display name&amp;nbsp;EVERY time&lt;/FONT&gt;, anyway. &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/30/57159.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/30/57159.aspx"&gt;Otherwise, you are asking for trouble!!&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Comparing Already-Loaded Assemblies&lt;/B&gt; &lt;BR&gt;Unless this comparison is for binding, the path to the manifest file of this assembly is used for determining whether this is the &lt;FONT color=#000000&gt;same&lt;/FONT&gt; assembly as another one. &lt;/P&gt;
&lt;P&gt;For example, path matters when determining whether a type is castable to another type. Even if the assemblies containing the types are identical, if they're loaded from different paths, they're considered different assemblies and therefore their types are different. This is one reason why &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx"&gt;using contexts other than the Load context is risky&lt;/A&gt;. You can get into situations where the same assembly is loaded multiple times in the same appdomain (once in the Load context, once in the LoadFrom context, and even several times in neither context), and their corresponding types won't be castable. &lt;/P&gt;
&lt;P&gt;Some assemblies don't have paths associated with them, such as those loaded by Load(byte[]) or created by Reflection Emit. Those are always just considered different assemblies, even if all of their bytes are identical. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57232" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Unloading an Assembly</title><link>http://blogs.msdn.com/suzcook/archive/2003/07/08/unloading-an-assembly.aspx</link><pubDate>Wed, 09 Jul 2003 05:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57211</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>29</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57211.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57211</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57211</wfw:comment><description>&lt;P&gt;There's no way to unload an individual assembly without unloading all of the appdomains containing it. (See &lt;A href="http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx" mce_href="http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx"&gt;here&lt;/A&gt; for why not.) This can by done by calling AppDomain.Unload() for each AppDomain that has it loaded. (You could also use UnloadDomain() on the v1 unmanaged hosting API, but in general, I recommend using managed code whenever possible.)&lt;/P&gt;
&lt;P&gt;I should point out that this means that even if your managed Assembly/Module/etc. instances go out of scope, GC may clean those instances up. The actual file will remain loaded until you unload all of the appdomain(s) containing it, however. (In general, that's better, anyway. Loading a file, especially by http, is too expensive to be done over and over when it can just be cached.) &lt;/P&gt;
&lt;P&gt;If you want to unload some assemblies but not others, consider creating a new AppDomain (requires ControlAppDomain permission), &lt;A href="http://blogs.msdn.com/suzcook/archive/2003/06/12/57169.aspx" mce_href="http://blogs.msdn.com/suzcook/archive/2003/06/12/57169.aspx"&gt;execute the code&lt;/A&gt; using the temporary ones from within that AppDomain, and then unload that new AppDomain when you're done. I recommend minimizing the number of AppDomains, though, since there is overhead involved in creating them, transitioning between them, and unloading them. So, it's best if you do all of that work at once, in one AppDomain, minimizing the cross-domain communication, and just unload that when possible (as opposed to creating a new AppDomain for each assembly to unload, etc.). &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Gotchas&lt;/B&gt; &lt;BR&gt;Watch out for references to that assembly leaking to other appdomains. If that happens, that assembly will remain loaded if you just unload one AppDomain. For example, passing a Type object to another appdomain will cause its assembly to be loaded there.&lt;/P&gt;
&lt;P&gt;Calling Unwrap()/AppDomain.CreateInstanceAndUnwrap()/etc. may also cause the runtime to try to load the assembly in the calling appdomain. In that case, call CreateInstance*() on a MarshalByRefObject type from a different assembly. For example, using AppDomain.CreateInstanceFrom() on the calling assembly (the one currently calling Unwrap()) may be the most convenient way. Then, call a method on it which will do all of your assembly loading. That way, those assemblies can be loaded in just the target appdomain.&lt;/P&gt;
&lt;P&gt;Also, note that assemblies loaded as domain neutral will not be unloaded until the process exits, since other appdomains are technically still using them. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Alternatives&lt;/B&gt; &lt;BR&gt;But, maybe you don't need to load that Assembly, anyway. If you just need info about it, you could call AssemblyName.GetAssemblyName() with the path to the file. That will temporarily load the file to get the info and then immediately unload it. That call will not cause it to show up as an Assembly in the AppDomain. &lt;/P&gt;
&lt;P&gt;Or, if you're only worried about keeping the file locked, you could use shadow copying. That will make a copy of the file on disk and load it from the new location. The original file will not be locked by that load.&amp;nbsp; To do that, set AppDomainSetup.ShadowCopyFiles to "true" when creating the AppDomain or set AppDomain.ShadowCopyFiles to true after it's already been created. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57211" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Mscorlib.dll</title><link>http://blogs.msdn.com/suzcook/archive/2003/06/30/mscorlib-dll.aspx</link><pubDate>Tue, 01 Jul 2003 02:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57203</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>28</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57203.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57203</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57203</wfw:comment><description>&lt;P&gt;At least for v2 and earlier, mscorlib.dll is a special case. That causes it and its types to be loaded differently from other assemblies. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Loading Mscorlib.dll Without a Path&lt;/B&gt; &lt;BR&gt;It and the execution engine are so closely integrated that it's required that they match each other. So, once a version of the CLR is chosen, the version of mscorlib is also chosen automatically. That means that, when late binding (Assembly.Load(), etc.) for it without a path, the 'official' mscorlib Assembly will always be returned - regardless of the version that was requested. The same thing goes for loading by static reference to it. &lt;/P&gt;
&lt;P&gt;This doesn't mean that it's okay to give an incomplete or incorrect reference for it! If/when mscorlib.dll is factored away from the execution engine, it won't be such a special case and bad references will start to fail to load. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Reflecting On Another Mscorlib.dll&lt;/B&gt; &lt;BR&gt;It's possible to load another mscorlib.dll if it's loaded by path. But, it's not possible to load its types, due to optimizations done by the CLR's execution engine. (Same goes for ReflectionOnlyLoadFrom() on another mscorlib.dll.) This means that even if you rename the mscorlib.dll that you want to reflect over, it may be loaded, but its types will still be unloadable. So, the options for working around this are: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Reflect on the 'official' mscorlib.dll. You could change the version of the CLR that your app loads in order to reflect on the desired mscorlib version. 
&lt;LI&gt;Use the unmanaged metadata API to get the desired info. 
&lt;LI&gt;Create an asmmeta file for the desired mscorlib.dll and parse it at runtime. &lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57203" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Assembly.CodeBase vs. Assembly.Location</title><link>http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx</link><pubDate>Fri, 27 Jun 2003 03:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57198</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57198.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57198</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57198</wfw:comment><description>&lt;P&gt;The CodeBase is a URL to the place where the file was found, while the Location is the path from where it was actually loaded. For example, if the assembly was downloaded from the internet, its CodeBase may start with "http://", but its Location may start with "C:\". If the file was shadow copied, the Location would be the path to the copy of the file in the shadow-copy dir. &lt;/P&gt;
&lt;P&gt;It’s also good to know that the CodeBase is not guaranteed to be set for assemblies in the GAC. Location will always be set for assemblies loaded from disk, however. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57198" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item><item><title>Determining an Image’s CLR Version</title><link>http://blogs.msdn.com/suzcook/archive/2003/06/20/determining-an-image-s-clr-version.aspx</link><pubDate>Sat, 21 Jun 2003 04:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:57191</guid><dc:creator>Suzanne Cook</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/suzcook/comments/57191.aspx</comments><wfw:commentRss>http://blogs.msdn.com/suzcook/commentrss.aspx?PostID=57191</wfw:commentRss><wfw:comment>http://blogs.msdn.com/suzcook/rsscomments.aspx?PostID=57191</wfw:comment><description>&lt;P&gt;To get it programmatically, from managed code, use Assembly.ImageRuntimeVersion. From unmanaged, use mscoree.dll's GetFileVersion(). (From the command line, starting in v2.0, ildasm.exe will show it if you double-click on "MANIFEST" and look for "Metadata version".) Those will give you the CLR version that the image claims it wants. By default, it's the version that the image was compiled against. That's not necessarily what it will be, however, since compilers can be configured to put any string there. &lt;/P&gt;
&lt;P&gt;Also, the CLR version that will be run by an exe is not necessarily the same as what is in its image runtime version. The chosen version can also depend on its hosting application's choice, a config file, environment variables, and registry settings. If you need to override those, you can set the supportedRuntime/requiredRuntime in the app.config for the process exe. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=57191" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/suzcook/archive/tags/Loader+Info/default.aspx">Loader Info</category></item></channel></rss>