PowerShell Cookbook

Search

Categories

 

On this page

Archive

Blogroll

Disclaimer
I work for Microsoft.

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 257
This Year: 8
This Month: 2
This Week: 0
Comments: 785

Sign In

 Tuesday, January 17, 2006
Tuesday, January 17, 2006 6:31:10 PM (Pacific Standard Time, UTC-08:00) ( )

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.]

Thursday, February 16, 2006 9:56:31 AM (Pacific Standard Time, UTC-08:00)
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
Richard Siddaway
Thursday, February 16, 2006 5:48:10 PM (Pacific Standard Time, UTC-08:00)
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.
Friday, December 22, 2006 6:46:04 AM (Pacific Standard Time, UTC-08:00)
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"))
Friday, December 22, 2006 8:09:27 PM (Pacific Standard Time, UTC-08:00)
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.
Wednesday, March 25, 2009 6:10:29 AM (Pacific Daylight Time, UTC-07:00)
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
Harkamal
Name
E-mail
Home page

Comment (Some html is allowed: b, blockquote@cite, em, i, strike, strong, sub, super, u)  

Enter the code shown (prevents robots):