ConvertTo-ISEAddOn.ps1
function ConvertTo-ISEAddOn { [CmdletBinding(DefaultParameterSetName="CreateOnly")] param( [Parameter(Mandatory=$true, ParameterSetName="DisplayNow")] [string]$DisplayName, [Parameter(Mandatory=$true, ParameterSetName="CreateOnly")] [Parameter(Mandatory=$true, ParameterSetName="DisplayNow")] [ScriptBlock] $ScriptBlock, [Parameter(ParameterSetName="DisplayNow")] [switch] $AddVertically, [Parameter(ParameterSetName="DisplayNow")] [switch] $AddHorizontally, [Parameter(Mandatory=$true, ParameterSetName="DisplayNow")] [switch] $Visible, [Switch] $Force ) begin { if ($psVersionTable.PSVersion -lt "3.0") { Write-Warning "Ise Window Add ons were not added until version 3.0." return } } process { $addOnNumber = Get-Random $addOnType =@" namespace ShowISEAddOns { using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Data; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Threading; using System.Windows.Threading; using System.ComponentModel; using System.Collections.Generic; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Generic; using Microsoft.PowerShell.Host.ISE; using System.Windows.Input; using System.Text; using System.Threading; using System.Windows.Threading; public class ShowUIIseAddOn${addOnNumber} : UserControl, IAddOnToolHostObject { ObjectModelRoot hostObject; #region IAddOnToolHostObject Members public ObjectModelRoot HostObject { get { return this.hostObject; } set { this.hostObject = value; this.hostObject.CurrentPowerShellTab.PropertyChanged += new PropertyChangedEventHandler(CurrentPowerShellTab_PropertyChanged); } } private void CurrentPowerShellTab_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (this.hostObject.CurrentPowerShellTab.CanInvoke) { if (this.Content != null && this.Content is UIElement ) { (this.Content as UIElement).IsEnabled = true; } } } public ShowUIIseAddOn${addOnNumber}() { if (Runspace.DefaultRunspace == null || Runspace.DefaultRunspace.ApartmentState != System.Threading.ApartmentState.STA || Runspace.DefaultRunspace.ThreadOptions != PSThreadOptions.UseCurrentThread) { InitialSessionState iss = InitialSessionState.CreateDefault(); iss.ImportPSModule(new string[] { "ShowUI" }); Runspace rs = RunspaceFactory.CreateRunspace(iss); rs.ApartmentState = System.Threading.ApartmentState.STA; rs.ThreadOptions = PSThreadOptions.UseCurrentThread; rs.Open(); Runspace.DefaultRunspace = rs; rs.SessionStateProxy.SetVariable("psIse", this.HostObject); } PowerShell psCmd = PowerShell.Create().AddScript(@" $($ScriptBlock.ToString().Replace('"','""')) "); psCmd.Runspace = Runspace.DefaultRunspace; try { FrameworkElement ui = psCmd.Invoke<FrameworkElement>()[0]; this.Content = ui; if (ui.GetValue(Control.WidthProperty) != null) { this.Width = ui.Width; } if (ui.GetValue(Control.HeightProperty) != null) { this.Height = ui.Height; } if (ui.GetValue(Control.MinWidthProperty) != null) { this.MinWidth = ui.MinWidth; } if (ui.GetValue(Control.MinHeightProperty) != null) { this.MinHeight = ui.MinHeight; } if (ui.GetValue(Control.MaxWidthProperty) != null) { this.MaxWidth = ui.MaxWidth; } if (ui.GetValue(Control.MaxHeightProperty) != null) { this.MaxHeight = ui.MaxHeight; } } catch { } } public PSObject[] InvokeScript(string script, object parameters) { return (PSObject[])RunOnUIThread( new DispatcherOperationCallback( delegate { PowerShell psCmd = PowerShell.Create(); Runspace.DefaultRunspace.SessionStateProxy.SetVariable("this", this); psCmd.Runspace = Runspace.DefaultRunspace; psCmd.AddScript(script); if (parameters is IDictionary) { psCmd.AddParameters(parameters as IDictionary); } else { if (parameters is IList) { psCmd.AddParameters(parameters as IList); } } Collection<PSObject> results = psCmd.Invoke(); if (psCmd.InvocationStateInfo.Reason != null) { throw psCmd.InvocationStateInfo.Reason; } PSObject[] resultArray = new PSObject[results.Count + psCmd.Streams.Error.Count]; int count = 0; if (psCmd.Streams.Error.Count > 0) { foreach (ErrorRecord err in psCmd.Streams.Error) { resultArray[count++] = new PSObject(err); } } foreach (PSObject r in results) { resultArray[count++] = r; } return resultArray; }), false); } object RunOnUIThread(DispatcherOperationCallback dispatcherMethod, bool async) { if (Application.Current != null) { if (Application.Current.Dispatcher.Thread == Thread.CurrentThread) { // This avoids dispatching to the UI thread if we are already in the UI thread. // Without this runing a command like 1/0 was throwing due to nested dispatches. return dispatcherMethod.Invoke(null); } } Exception e = null; object returnValue = null; SynchronizationContext sync = new DispatcherSynchronizationContext(this.Dispatcher); if (async) { sync.Post( new SendOrPostCallback(delegate(object obj) { try { returnValue = dispatcherMethod.Invoke(obj); } catch (Exception uiException) { e = uiException; } }), null); } else { sync.Send( new SendOrPostCallback(delegate(object obj) { try { returnValue = dispatcherMethod.Invoke(obj); } catch (Exception uiException) { e = uiException; } }), null); } if (e != null) { throw new System.Reflection.TargetInvocationException(e.Message, e); } return returnValue; } #endregion } } "@ $presentationFramework = [System.Windows.Window].Assembly.FullName $presentationCore = [System.Windows.UIElement].Assembly.FullName $windowsBase=[System.Windows.DependencyObject].Assembly.FullName $gPowerShell=[Microsoft.PowerShell.Host.ISE.PowerShellTab].Assembly.FullName $systemXaml=[system.xaml.xamlreader].Assembly.FullName $systemManagementAutomation=[psobject].Assembly.FullName $t = add-type -TypeDefinition $addOnType -ReferencedAssemblies $systemManagementAutomation,$presentationFramework,$presentationCore,$windowsBase,$gPowerShell,$systemXaml -ignorewarnings -PassThru | Select-Object -First 1 if ($addHorizontally) { $exists= $psISE.CurrentPowerShellTab.HorizontalAddOnTools | Where-Object { $_.Name -eq "$displayName" } if ($Exists -and $Force) { $null = $psISE.CurrentPowerShellTab.HorizontalAddOnTools.Remove($exists) } $psISE.CurrentPowerShellTab.HorizontalAddOnTools.Add("$displayName",$t,$true) } elseif ($addVertically) { $exists= $psISE.CurrentPowerShellTab.VerticalAddOnTools | Where-Object { $_.Name -eq "$displayName" } if ($Exists -and $Force) { $null = $psISE.CurrentPowerShellTab.VerticalAddOnTools.Remove($exists) } $psISE.CurrentPowerShellTab.VerticalAddOnTools.Add("$displayName",$t,$true) } else { $t } } } |