How do I easily load assemblies, when LoadWithPartialName has been deprecated?
Tuesday, 17 January 2006
There are some very useful parts of the .Net framework (ie: System.Web and System.Windows.Forms) that Monad doesn’t load into its AppDomain by default. In order to use them, you first load them with one of the Load() methods from the System.Reflection.Assembly class.
At first, the easiest approach seems to be LoadWithPartialName. You can simply request “System.Windows.Forms” and be done with it:
MSH:73 C:\temp > [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
GAC Version Location
— ——- ——–
True v2.0.50727 C:\WINNT\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e…
(you can cast the result to [void] if you don’t want your script to belch the loading information.)
However, the documentation shows this handy method as being deprecated.
This is because the API needs to make too many guesses about what you really want. Most people don’t really want “Whatever version of System.Windows.Forms you can scrounge up from the GAC or current directory.” Most people really want “Microsoft’s version of System.Windows.Forms, shipped with .Net 2.0″
This is especially true in the face of breaking changes that may or may not happen to the DLL you want to load. For applications that need to be reliable, LoadWithPartialName will cause problems. Suzanne Cook discusses its implications on her blog entry, “Avoid Partial Binds.”
For scripts that you don’t mind debugging by hand when things break, you can stick with LoadWithPartialName until it’s physically removed from the framework. However, your best bet is to consciously make the decisions that the LoadWithPartialName method makes on your behalf with the following helper script:
## load-assembly.msh
##
## Loads a given assembly by a more friendly name, while still using the strong
## binding characteristics of Assembly.Load.
##
## Assembly.LoadWithPartialName has been deprecated, as it binds only by display
## name. It’s a convenient shortcut, but opens your application and script, and
## environment to all sorts of reliability issues, including:
## backwards incompatibility, forwards incompatibility, breaking changes,
## and subtle assembly dependency problems.
##
################################################################################
param([string] $assemblyName)
## Our assembly name shortcuts
$assemblyMappings = (
(“forms”, “System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″),
(“web”, “System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”)
)
## List the assembly shortcuts we support
if(-not $assemblyName)
{
“Please specify an assembly name. Supported assemblies are: ”
foreach($assembly in $assemblyMappings) { $assembly[0] }
return
}
## Load the assembly they request
## This fails with an error message if this specific assembly version can’t
## be loaded.
foreach($assembly in $assemblyMappings)
{
if($assemblyName -eq $assembly[0])
{
[void] [Reflection.Assembly]::Load($assembly[1])
}
}
[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]


Subscribe to this blog.
No. 1 — February 16th, 2006 at 9:56 am
This has been really useful. One question though – I can’t seem to get this method to work with System.DirectoryServices.ActiveDirectory which works OK with the loadwithpartialname method. I’d be grateful for any ideas
Thanks
No. 2 — February 16th, 2006 at 5:48 pm
Hi Richard;
When you want to add a new type to your load-assembly script, this is how you get the full name:
1) $loadedAssembly = [System.Reflection.Assembly]::LoadWithPartialName("your_assembly_here")
2) $loadedAssembly.FullName
That gives you the fully qualified name of the assembly, which you can add to your list.
No. 3 — December 22nd, 2006 at 6:46 am
I have trouble loading System.Drawing. Any clues? Thanks.
PS C:\> $aa=[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
PS C:\> $aa.Fullname
System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
PS C:\> [void][Reflection.Assembly]::Load(("drawing", "System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"))
Exception calling "Load" with "1" argument(s): "Could not load file or assembly ‘drawing System.Drawing, Version=2.0.0.
0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file specif
ied."
At line:1 char:34
+ [void][Reflection.Assembly]::Load( <<<< ("drawing", "System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken
=b03f5f7f11d50a3a"))
No. 4 — December 22nd, 2006 at 8:09 pm
Hi HC;
The Assembly.Load method accepts the full name of the assembly, so it looks like this:
[Reflection.Assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
The "drawing" shortcut I used in the script just lets you use a shortcut to load the assembly — but it actually uses the full name for the actual call.
No. 5 — March 25th, 2009 at 6:10 am
Good article, I have been a fan of PowerShell Cookbook.
Ok, so once i have an assembly loaded into powershell, say System.Drawing — How can I see which methoda or properties it supports, …can we make use of Get-Member somehow ??
Th
No. 6 — May 28th, 2011 at 6:49 pm
[...] about more of this, you should check into these excellent online posts from Richard Siddaway, Lee Holmes and Doug Finke which I used as a reference to get [...]
No. 7 — June 25th, 2012 at 8:30 am
Watch out — the script is broken — it uses curly non-ASCII double quotes which will not work, and must be fixed before the script can work.