<?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>Media And Microcode : .NET</title><link>http://blogs.msdn.com/mediaandmicrocode/archive/tags/.NET/default.aspx</link><description>Tags: .NET</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Microcode: Exploring More of .NET with Get-Assembly</title><link>http://blogs.msdn.com/mediaandmicrocode/archive/2008/11/08/microcode-exploring-more-of-net-with-get-assembly.aspx</link><pubDate>Sat, 08 Nov 2008 03:46:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9053397</guid><dc:creator>JamesBrundage</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/mediaandmicrocode/comments/9053397.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mediaandmicrocode/commentrss.aspx?PostID=9053397</wfw:commentRss><description>&lt;p&gt;In a previous post, I introduced a function called &lt;a href="http://blogs.msdn.com/mediaandmicrocode/archive/2008/10/23/microcode-powershell-scripting-tricks-exploring-net-types-with-a-get-type-function-and-reflection.aspx"&gt;Get-Type&lt;/a&gt;, which allows you to see all of the types currently loaded by .NET.&amp;#160; What it doesn't do is help you find assemblies, the DLL files containing new types.&amp;#160; So while there might be 19000-odd types loaded when I launch the Windows PowerShell Integrated Script Editor (aka Graphical PowerShell), it's the tip of the iceberg for what .NET can do.&lt;/p&gt;  &lt;p&gt;Since the Iceberg is so huge, you probably do not want to try to load every bit of the iceberg just to see what it contains.&amp;#160; So you're left with a classic &lt;a href="http://en.wikipedia.org/wiki/Schr%C3%B6dinger%27s_cat"&gt;Schr&amp;#246;dinger's Cat&lt;/a&gt; problem (observing something may change what you observe).&lt;/p&gt;  &lt;p&gt;Luckily, assemblies are located in a common spot on the filesystem, so it's actually really easy to find all of the assemblies that exist for public consumption without loading them.&amp;#160; This will catch assemblies installed for public use, but it will not catch an assembly that lives in the same directory as a program.&lt;/p&gt;  &lt;p&gt;In this post, I'll show you how to write a Get-Assembly function, and use it with the Object Pipeline to explore and load up specific assemblies.&amp;#160; Since Assemblies exist underneath the Windows Directory, I can search the directory with Get-ChildItem (or dir, if you prefer).&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Get-ChildItem (Join-Path $env:Windir &amp;quot;Assembly&amp;quot;) -recurse -filter &amp;quot;*.dll&amp;quot;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If you run this, you should notice two things.&amp;#160; First, there's a lot of output that goes by far too quickly to be useful to a person. Second, there's a bunch of files DLLs, and some files named something like &lt;em&gt;Assembly.Ni.Dll&lt;/em&gt;.&amp;#160; We cannot load those assemblies, so we'll remove them from the list by adding on a Where-Object.&amp;#160; Then, to make loading up the assembly easier, I'll pipe each result to Add-Member in order to add a method to load the assembly.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;function Get-Assembly()        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get-ChildItem (Join-Path $env:Windir &amp;quot;Assembly&amp;quot;) -recurse -filter &amp;quot;*.dll&amp;quot; |         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where-Object {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ! $_.Name.Substring(0,$_.Name.IndexOf($_.Extension)).EndsWith(&amp;quot;.ni&amp;quot;)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } | Add-Member ScriptMethod Load -passThru {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Reflection.Assembly]::LoadFrom($this.FullName)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This Get-Assembly gets rid of the DLLs we can't use, but it's still not ideal for human consumption because of how files are displayed.&amp;#160; Files from different directories show up with a header for that directory, so running this produces a lot of white space when you're really interested in the name or the full path. Luckily, I can always summarize the object with Select-Object.&amp;#160; The next bit will sort all of the assemblies by their name and output just that property.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Get-Assembly |        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Sort-Object Name |         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Select-Object Name&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I can also use the Get-Assembly command to load up assemblies to explore with Get-Type.&amp;#160; This next statement will walk through all of the assemblies related to Linq and load them up:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Get-Assembly |        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Where-Object { $_.Name -like &amp;quot;*Linq*&amp;quot; } |         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Foreach-Object { $_.Load() } &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I can also save the loaded assemblies into a variable so I can use them later.&amp;#160; For instance, I'll save the Linq assemblies and then use Get-Type to look through each of the types in those assemblies.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;$assemblies = Get-Assembly |        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Where-Object { $_.Name -like &amp;quot;*Linq*&amp;quot; } |         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Foreach-Object { $_.Load() }         &lt;br /&gt;&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Get-Type | Where-Object {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $type = $_         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $assemblies | Where-Object { $type.Assembly -eq $_ }         &lt;br /&gt;}&lt;/em&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Get-Type and Get-Assembly work well together as a way to explore all that .NET has to offer.&amp;#160; On my box, there's over 500 assemblies, of which only 41 are currently loaded in PowerShell.&amp;#160; If 41 assemblies contain about 20000 types, imagine just how many pre-canned solutions exist in .NET just waiting for you to use.&lt;/p&gt;  &lt;p&gt;Hope this Helps,&lt;/p&gt;  &lt;p&gt;James Brundage [MSFT]&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Download scripts:&lt;/b&gt;&lt;/p&gt;  &lt;table border='1'&gt;&lt;theader&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Module Name&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Scripts&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt; &lt;/theader&gt;&lt;/tbody&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;DotNet&lt;/td&gt;        &lt;td&gt;&lt;a href="http://cid-2b8a402d0ba15e82.skydrive.live.com/self.aspx/PowerShell%20Scripts/DotNet/Get-Assembly.ps1"&gt;Get-Assembly&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&amp;#160;&lt;/td&gt;        &lt;td&gt;&lt;a href="http://cid-2b8a402d0ba15e82.skydrive.live.com/self.aspx/PowerShell%20Scripts/DotNet/Get-Type.ps1"&gt;Get-Type&lt;/a&gt;&lt;/td&gt;    &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9053397" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Get-Type/default.aspx">Get-Type</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Get-Assembly/default.aspx">Get-Assembly</category></item><item><title>Microcode: Scripting Tricks : Exploring WPF Routed Events with PowerShell</title><link>http://blogs.msdn.com/mediaandmicrocode/archive/2008/10/20/microcode-scripting-tricks-exploring-wpf-routed-events-with-powershell-and-get-member-where-object-and-group-object.aspx</link><pubDate>Mon, 20 Oct 2008 03:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9006725</guid><dc:creator>JamesBrundage</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/mediaandmicrocode/comments/9006725.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mediaandmicrocode/commentrss.aspx?PostID=9006725</wfw:commentRss><description>&lt;P&gt;Both WPF and PowerShell are both full of great little touches.&amp;nbsp; One of WPF's nice touches is &lt;A href="http://msdn.microsoft.com/en-us/library/ms742806.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms742806.aspx"&gt;Routed Events&lt;/A&gt;.&amp;nbsp; Routed Events allow you to capture events raised by child controls or parent controls.&amp;nbsp; This can be incredibly useful, because it allows you write less code (which I believe is generally good) by re-using handlers.&lt;/P&gt;
&lt;P&gt;A good example of why you might want to do this is wanting to have more than one button in a user interface that updates a database.&amp;nbsp; What each button might do may be different, but they all to connect to a database.&amp;nbsp; This means you could write either write three longer (and less portable) methods that connect to the database and perform an operation, or three shorter ( and more portable ) methods that just perform the operation on a database and one operation that connects to the database.&amp;nbsp;&amp;nbsp; By having each of the buttons go through a routed event on a container, you can write one short routing handler that connects to the database, looks at where the message came from, and performs the operation.&lt;/P&gt;
&lt;P&gt;WPF comes with an amazing number of controls, and a pretty nice selection of Routed Events.&amp;nbsp; The WPF team was event nice enough to have a manager for these routed events, which means that we can explore them dynamically using PowerShell.&lt;/P&gt;
&lt;P&gt;The event manager is available in the class &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.eventmanager(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.eventmanager(VS.85).aspx"&gt;System.Windows.EventManager&lt;/A&gt;.&amp;nbsp; Let's start exploring it with PowerShell.&amp;nbsp; To do this, make sure you've loaded the WPF assembly into PowerShell&amp;nbsp; by using the line [Reflection.Assembly]::LoadWithPartialName("PresentationCore"). We can omit the System namespace when referring to a type in PowerShell, so we can call it [Windows.EventManager] from now on.&amp;nbsp; We can use Get-Member -static to see what this class can do.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;[Windows.EventManager] | Get-Member -static&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It has the following methods:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Equals (every .NET object has this static member) &lt;/LI&gt;
&lt;LI&gt;GetRoutedEvents()&lt;/LI&gt;
&lt;LI&gt;GetRoutedEventsForOwner(Type ownerType)&lt;/LI&gt;
&lt;LI&gt;ReferenceEquals (every .NET object has this static member)&lt;/LI&gt;
&lt;LI&gt;RegisterClassHandler (Type classType, RoutedEvent routedEvent, Delegate handler)&lt;/LI&gt;
&lt;LI&gt;RegisterClassHandler (Type classType, RoutedEvent routedEvent, Delegate handler, Boolean handledEventsToo)&lt;/LI&gt;
&lt;LI&gt;RegisterRoutedEvent(String name, RoutingStrategy routingStrategy, Type handlerType, Type ownerType)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Since I'm just exploring, GetRoutedEvents() is the method I'm interested in.&lt;/P&gt;
&lt;P&gt;I can see every routed event with the simple PowerShell one-liner:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;[Windows.EventManager]::GetRoutedEvents()&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Of course we can pipe that to Get-Member in order to see what we've got for every Routed Event:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;[Windows.EventManager]::GetRoutedEvents() | Get-Member&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It's more interesting to me to figure out what events I can bubble up to the parent controls.&amp;nbsp; Since each &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.routedevent.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.routedevent.aspx"&gt;RoutedEvent&lt;/A&gt; has a &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.routedevent.routingstrategy.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.routedevent.routingstrategy.aspx"&gt;RoutingStrategy&lt;/A&gt; property, I can write this as a simple filter using Where-Object:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;[Windows.EventManager]::GetRoutedEvents() | Where-Object { $_.RoutingStrategy -eq "Bubble"&lt;/EM&gt;&lt;EM&gt;} | Sort-Object Name&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Since each RoutedEvent also has a &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.routedevent.handlertype.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.routedevent.handlertype.aspx"&gt;HandlerType&lt;/A&gt; property, I can also see what types of different handlers exist by using&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;[Windows.EventManager]::GetRoutedEvents() | Group-Object HandlerType | Sort-Object Count -descending&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Finally, I can use the EventManager to help guess about what types of controls could fit the bill for whatever I need to do. The next one liner gives me all of the routed events that work with Drag and Drop&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;[Windows.EventManager]::GetRoutedEvents() | Where-Object {$_.Name -like "*Drag*" -or $_.Name -like "*Drop*" }&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Associating these events with a class needs to use some tricks of reflection.&amp;nbsp; In the sample below, I'll look for all drag and drop handlers within PresentationBase (where the EventManager and some base components live) and PresentationFramework (where most of the built-in WPF controls reside):&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;$handlers = [Windows.EventManager]::GetRoutedEvents() | &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Where-Object { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $_.Name -like "*Drag*" -or $_.Name -like "*Drop*" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;$assemblies = [Windows.EventManager].Assembly, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Windows.Window].Assembly &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;$assemblies | Foreach-Object { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $_.GetTypes() | Where-Object { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach ($handler in $handlers) { &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; if ($_.GetEvent($handler.Name)) { &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; return $true &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; } &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; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;}&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The script above takes a bit of explaining.&lt;/P&gt;
&lt;P&gt;I store the Drag and Drop handlers into a variable, and store the assemblies I wanted to search in another variable (to search all of my currently loaded types for these handlers, I'd use just assign $assemblies to &lt;EM&gt;[AppDomain]::CurrentDomain.GetAssemblies()&lt;/EM&gt;).&amp;nbsp; Then I go through each assembly, retrieve the types, and pipe them into Where-Object, which will determine if they meet my criteria.&amp;nbsp; I go through each class and each handler that met my criteria, and use the &lt;A href="http://msdn.microsoft.com/en-us/library/system.type.getevent(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.type.getevent(VS.71).aspx"&gt;GetEvent&lt;/A&gt; method (which is defined on any .NET type definition) to determine if the event is present.&amp;nbsp; If the event is present, I return $true, which makes the Where-Object output the type.&amp;nbsp; If the event's not present, then code will go onto the next handler and the next type.&lt;/P&gt;
&lt;P&gt;These are just a few examples of the ways you can use PowerShell to explore WPF routed events.&amp;nbsp; The techniques used in this post can be used on to explore just about any .NET type.&amp;nbsp; Exploring .NET through reflection is a great way to save time looking things up, and the pathway to using existing .NET code to solve a problem rather than reinventing the wheel.&lt;/P&gt;
&lt;P&gt;Hope this helps,&lt;/P&gt;
&lt;P&gt;James Brundage [MSFT]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9006725" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Sort-Object/default.aspx">Sort-Object</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Group-Object/default.aspx">Group-Object</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Scripting+Tricks/default.aspx">Scripting Tricks</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Where-Object/default.aspx">Where-Object</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Get-Member/default.aspx">Get-Member</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/.NET/default.aspx">.NET</category></item></channel></rss>