PoshCode Logo PowerShell Code Repository

HuddledTricks by Jaykul 6 years ago (modification of post by Joel Bennett view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1741"></script>download | new post

I just added a bunch of tricks, including Ghosting windows (and unghosting), as well as messing with aero peek

  1. #Requires -version 2.0
  2. ## Stupid PowerShell Tricks
  3. ###################################################################################################
  4. add-type @"
  5. using System;
  6. using System.Runtime.InteropServices;
  7. public class Tricks {
  8.   [DllImport("user32.dll")]
  9.   private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
  10.  
  11.   [DllImport("user32.dll", SetLastError = true)]
  12.   private static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);
  13.  
  14.   [DllImport("user32.dll")]
  15.   static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  16.  
  17.   [DllImport("user32.dll")]
  18.   static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
  19.  
  20.   [DllImport("user32.dll")]
  21.   [return: MarshalAs(UnmanagedType.Bool)]
  22.   static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SWP uFlags);  
  23.  
  24.   [DllImport("dwmapi.dll", PreserveSig = false)]
  25.   public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
  26.  
  27.   const int GWL_EXSTYLE = -20;
  28.   const int WS_EX_LAYERED = 0x80000;
  29.   const int WS_EX_TRANSPARENT = 0x20;
  30.   const int LWA_ALPHA = 0x2;
  31.   const int LWA_COLORKEY = 0x1;
  32.  
  33.   static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
  34.   static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
  35.   static readonly IntPtr HWND_TOP = new IntPtr(0);
  36.   static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
  37.  
  38.   [Flags]
  39.   enum SWP : uint {
  40.      NOSIZE = 0x0001,
  41.      NOMOVE = 0x0002,
  42.      NOZORDER = 0x0004,
  43.      NOREDRAW = 0x0008,
  44.      NOACTIVATE = 0x0010,
  45.      FRAMECHANGED = 0x0020,  /* The frame changed: send WM_NCCALCSIZE */
  46.      SHOWWINDOW = 0x0040,
  47.      HIDEWINDOW = 0x0080,
  48.      NOCOPYBITS = 0x0100,
  49.      NOOWNERZORDER = 0x0200,  /* Don't do owner Z ordering */
  50.      NOSENDCHANGING = 0x0400,  /* Don't send WM_WINDOWPOSCHANGING */
  51.   }
  52.   [Flags]
  53.   public enum DwmWindowAttribute
  54.   {
  55.      NCRenderingEnabled = 1,
  56.      NCRenderingPolicy,
  57.      TransitionsForceDisabled,
  58.      AllowNCPaint,
  59.      CaptionButtonBounds,
  60.      NonClientRtlLayout,
  61.      ForceIconicRepresentation,
  62.      Flip3DPolicy,
  63.      ExtendedFrameBounds,
  64.      HasIconicBitmap,
  65.      DisallowPeek,
  66.      ExcludedFromPeek,
  67.      Last
  68.   }
  69.  
  70.   [Flags]
  71.   public enum DwmNCRenderingPolicy
  72.   {
  73.      UseWindowStyle,
  74.      Disabled,
  75.      Enabled,
  76.      Last
  77.   }
  78.  
  79.         public static void ShowWindow(IntPtr hWnd) { ShowWindowAsync(hWnd,5); }
  80.         public static void HideWindow(IntPtr hWnd) { ShowWindowAsync(hWnd,0); }
  81.   public static void GhostWindow(IntPtr hWnd, int percent) {
  82.      SetWindowLong(hWnd, GWL_EXSTYLE, (IntPtr)(GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT));
  83.      // set transparency to X% (of 255)
  84.      if(percent > 100) { percent = 100; }
  85.      byte alpha = (byte)(255 * (percent/100.0));
  86.      SetLayeredWindowAttributes(hWnd, 0, alpha, LWA_ALPHA);
  87.      SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP.NOSIZE | SWP.NOMOVE);
  88.   }
  89.   public static void UnGhostWindow(IntPtr hWnd) {
  90.      SetWindowLong(hWnd, GWL_EXSTYLE, (IntPtr)(GetWindowLong(hWnd, GWL_EXSTYLE) &~WS_EX_LAYERED &~WS_EX_TRANSPARENT));
  91.      SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP.NOSIZE | SWP.NOMOVE);
  92.   }
  93.  
  94.   public static void RemoveFromAeroPeek(IntPtr Hwnd) //Hwnd is the handle to your window
  95.   {
  96.      int renderPolicy = (int)DwmNCRenderingPolicy.Enabled;
  97.      DwmSetWindowAttribute(Hwnd, (int)DwmWindowAttribute.ExcludedFromPeek, ref renderPolicy, sizeof(int));
  98.   }
  99.   public static void RestoreToAeroPeek(IntPtr Hwnd) //Hwnd is the handle to your window
  100.   {
  101.      int renderPolicy = (int)DwmNCRenderingPolicy.Disabled;
  102.      DwmSetWindowAttribute(Hwnd, (int)DwmWindowAttribute.ExcludedFromPeek, ref renderPolicy, sizeof(int));
  103.   }
  104. }
  105. "@
  106.  
  107. $dictionary = [System.Collections.Generic.Dictionary``2]
  108. $list = [System.Collections.Generic.List``1]
  109. $string = [String]
  110. $intPtr = [IntPtr]
  111.  
  112. $intPtrList = $list.AssemblyQualifiedName -replace "1,","1[[$($intPtr.AssemblyQualifiedName)]],"
  113. $windows = new-object ($dictionary.AssemblyQualifiedName -replace "2,","2[[$($string.AssemblyQualifiedName)],[$intPtrList]],")
  114.  
  115.  
  116.  
  117. function Remove-GhostWindow {
  118. <#
  119. .SYNOPSIS
  120.    Un-ghost a window
  121. .PARAMETER Handle
  122.    The window handle to a specific window we want to hide.
  123. .PARAMETER Name
  124.    The name of a running process whos windows you want to hide.
  125. .EXAMPLE
  126.    Get-Process PowerShell | Hide-Window; Sleep 5; Show-Window
  127.    
  128.    Hides the PowerShell window(s) for 5 seconds
  129. #>
  130. [CmdletBinding()]
  131. PARAM (
  132.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  133.    [Alias("MainWindowHandle","Handle")]
  134.    [IntPtr]$WindowHandle=[IntPtr]::Zero
  135. ,
  136.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  137.    [Alias("ProcessName")]
  138.    [String]$Name
  139. )
  140. PROCESS {
  141.         (Resolve-Window $WindowHandle $Name) | ForEach-Object { [Tricks]::UnGhostWindow( $_ ) }
  142. }
  143. }
  144.  
  145.  
  146. function Set-GhostWindow {
  147. <#
  148. .SYNOPSIS
  149.    Make a window partially transparent and click-through
  150. .PARAMETER Handle
  151.    The window handle to a specific window we want to hide.
  152. .PARAMETER Name
  153.    The name of a running process whos windows you want to hide.
  154. .PARAMETER Percent
  155.    The percentage (from 0 to 100) of opacity you want to use (defaults to 80)
  156. .EXAMPLE
  157.    Get-Process PowerShell | Hide-Window; Sleep 5; Show-Window
  158.    
  159.    Hides the PowerShell window(s) for 5 seconds
  160. #>
  161. [CmdletBinding()]
  162. PARAM (
  163.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  164.    [Alias("MainWindowHandle","Handle")]
  165.    [IntPtr]$WindowHandle=[IntPtr]::Zero
  166. ,
  167.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  168.    [Alias("ProcessName")]
  169.    [String]$Name
  170. ,
  171.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  172.    [ValidateRange(0,100)]
  173.    [int]$Percent = 80
  174. )
  175. PROCESS {
  176.         (Resolve-Window $WindowHandle $Name) | ForEach-Object { [Tricks]::GhostWindow( $_, $Percent ) }
  177. }
  178. }
  179.  
  180. function Hide-Window {
  181. <#
  182. .SYNOPSIS
  183.    Hide a window
  184. .DESCRIPTION
  185.    Hide a window by handle or by process name. Hidden windows are gone: they don't show up in alt+tab, or on the taskbar, and they're invisible. The only way to get them back is with ShowWindow.
  186.    Windows hidden by Hide-Window are pushed onto a stack so they can be retrieved by Show-Window. Since they're invisible, they're very hard to find otherwise.
  187. .NOTES
  188.    See also Show-Window
  189. .PARAMETER WindowHandle
  190.    The window handle to a specific window we want to hide.
  191. .PARAMETER Name
  192.    The name of a running process whos windows you want to hide.
  193. .EXAMPLE
  194.    Get-Process PowerShell | Hide-Window; Sleep 5; Show-Window
  195.    
  196.    Hides the PowerShell window(s) for 5 seconds
  197. #>
  198. [CmdletBinding()]
  199. PARAM (
  200.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  201.    [Alias("MainWindowHandle","Handle")]
  202.    [IntPtr]$WindowHandle=[IntPtr]::Zero
  203. ,
  204.    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  205.    [Alias("ProcessName")]
  206.    [String]$Name
  207. )
  208. PROCESS {
  209.         (Push-Window $WindowHandle $Name) | ForEach-Object { [Tricks]::HideWindow( $_ ) }
  210. }
  211. }
  212.  
  213. function Show-Window {
  214. <#
  215. .SYNOPSIS
  216.    Show a window
  217. .DESCRIPTION
  218.    Show a window by handle or by process name. If you call it without any parameters, will show all hidden windows.
  219. .NOTES
  220.    See also Hide-Window
  221. .PARAMETER WindowHandle
  222.    The window handle to a specific window we want to show.
  223. .PARAMETER Name
  224.    The name of a running process whos windows you want to show.
  225. .EXAMPLE
  226.    Get-Process PowerShell | Hide-Window; Sleep 5; Show-Window
  227.    
  228.    Hides the PowerShell window(s) for 5 seconds
  229. #>
  230. [CmdletBinding()]
  231.  
  232. PARAM (
  233. [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  234. [Alias("MainWindowHandle","Handle")]
  235. [IntPtr]$WindowHandle=[IntPtr]::Zero
  236. ,
  237. [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
  238. [Alias("ProcessName")]
  239. [String]$Name
  240. )
  241. PROCESS {
  242.         (Pop-Window $WindowHandle $Name) | ForEach-Object { [Tricks]::ShowWindow( $_ ) }
  243. }
  244. }
  245.  
  246.  
  247. ## PRIVATE
  248. FUNCTION Push-Window {
  249.    [CmdletBinding()]
  250.         PARAM ([IntPtr]$Handle,[String]$ProcessName)
  251.         if(!$ProcessName) { $ProcessName = "--Unknown--" }
  252.  
  253.    $Handles = Resolve-Window $Handle $ProcessName
  254.  
  255.         $windows[$ProcessName].AddRange($Handles)
  256.         write-output $Handles
  257. }
  258.  
  259. FUNCTION Resolve-Window  {
  260.    [CmdletBinding()]
  261.         PARAM ([IntPtr]$Handle,[String]$ProcessName)
  262.         if(!$ProcessName) { $ProcessName = "--Unknown--" }
  263.         [IntPtr[]]$Handles = @($Handle)
  264.    
  265.         if(!$Windows.ContainsKey($ProcessName)) {
  266.                 $windows.Add($ProcessName, (New-Object $intPtrList))
  267.         }
  268.         if($Handle -eq [IntPtr]::Zero) {
  269.                 [IntPtr[]]$Handles = @(Get-Process $ProcessName | % { $_.MainWindowHandle } )
  270.         }
  271.    return $Handles
  272. }
  273.  
  274. ## PRIVATE
  275. FUNCTION Pop-Window {
  276.    [CmdletBinding()]
  277.         PARAM ([IntPtr]$Handle,[String]$ProcessName)
  278.        
  279.         [IntPtr[]]$Handles = @($Handle)
  280.         if(!$ProcessName) { $ProcessName = "--Unknown--" }
  281.    
  282.         if(($Handle -eq [IntPtr]::Zero) -and $windows[$ProcessName] ) {
  283.                 write-output $windows[$ProcessName]
  284.                 $Null = $windows[$ProcessName].Clear()
  285.         } elseif($Handle -ne [IntPtr]::Zero){
  286.                 $Null = $windows[$ProcessName].Remove( $Handle )
  287.         }
  288.  
  289.         write-output $Handles
  290. }
  291.  
  292. Add-Type -Assembly System.Windows.Forms
  293. function Wiggle-Mouse {
  294. <#
  295. .SYNOPSIS
  296.    Wiggle the mouse until you Ctrl+Break to stop the script.
  297. .DESCRIPTION
  298.    Wiggle-Mouse randomly moves the mouse by a few pixels every few milliseconds until you stop the script.
  299. .PARAMETER Variation
  300.    The maximum distance to move the mosue in any direction.  Values that are too small aren't noticeable, and values that are too big make the user "loose" the mouse and they have no idea what happened.
  301. .PARAMETER Name
  302.    The name of a running process whos windows you want to hide.
  303. .EXAMPLE
  304.    Get-Process PowerShell | Hide-Window; Wiggle-Mouse -Duration 5;  Get-Process PowerShell | Show-Window
  305.    
  306.    Hides the PowerShell window and wiggle the mouse for five seconds ... :D
  307. #>
  308. [CmdletBinding()]
  309. PARAM (
  310. [Parameter(Position=0)][Int]$Variation=80,
  311. [Parameter(Position=1)][Int]$Sleep=400,
  312. [Parameter(Position=2)][Int]$Duration=0
  313. )
  314.    if(!$Duration) { Write-Host "Ctrl+C to stop wiggling :)" }
  315.         $screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
  316.         $random = new-object Random
  317.    $Duration *= -1000
  318.         While($Duration -le 0) {
  319.                 [Windows.Forms.Cursor]::Position ="$(
  320.                         $random.Next(   [Math]::Max( $screen.Left, ([System.Windows.Forms.Cursor]::Position.X - $Variation) ),
  321.                                                                 [Math]::Min( $screen.Right, ([System.Windows.Forms.Cursor]::Position.X + $Variation) )  )
  322.                                                         ),$(
  323.                         $random.Next(   [Math]::Max( $screen.Top, ([System.Windows.Forms.Cursor]::Position.Y - $Variation) ),
  324.                                                                 [Math]::Min( $screen.Bottom, ([System.Windows.Forms.Cursor]::Position.Y + $Variation) ) )
  325.                                                         )"
  326.                 sleep -milli $Sleep
  327.       $Duration += $Sleep
  328.         }
  329. }
  330.  
  331. [Reflection.Assembly]::Load("UIAutomationClient, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
  332. function global:Select-Window {
  333. PARAM( [string]$Title="*",
  334.        [string]$Process="*",
  335.        [switch]$Recurse,
  336.        [System.Windows.Automation.AutomationElement]$Parent = [System.Windows.Automation.AutomationElement]::RootElement )
  337. PROCESS {
  338.    $search = "Children"
  339.    if($Recurse) { $search = "Descendants" }
  340.    
  341.    $Parent.FindAll( $search, [System.Windows.Automation.Condition]::TrueCondition ) |
  342.    Add-Member -Type ScriptProperty -Name Title     -Value {
  343.                $this.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::NameProperty)} -Passthru |
  344.    Add-Member -Type ScriptProperty -Name Handle    -Value {
  345.                $this.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::NativeWindowHandleProperty)} -Passthru |
  346.    Add-Member -Type ScriptProperty -Name ProcessId -Value {
  347.                $this.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::ProcessIdProperty)} -Passthru |
  348.  
  349.    Where-Object {
  350.       ((Get-Process -Id $_.ProcessId).ProcessName -like $Process) -and ($_.Title -like $Title)
  351.    }
  352. }}
  353.  
  354.  
  355. function Remove-AeroPeek {
  356. PARAM(
  357.    [string]$Title="*",
  358.    [string]$Process="*"
  359. )
  360. PROCESS {
  361.    Foreach($window in Select-Window -Process $Process -Title $Title) {
  362.       [Tricks]::RemoveFromAeroPeek( $window.Handle )
  363.    }
  364. }
  365. }
  366. function Restore-AeroPeek {
  367. PARAM(
  368.    [string]$Title="*",
  369.    [string]$Process="*"
  370. )
  371. PROCESS {
  372.    Foreach($window in Select-Window -Process $Process -Title $Title) {
  373.       [Tricks]::RestoreToAeroPeek( $window.Handle )
  374.    }
  375. }
  376. }
  377. # Remove-AeroPeek "Miranda IM"
  378. # Remove-AeroPeek -Process Rainlendar2
  379.  
  380. Export-ModuleMember Select-Window, Show-Window, Hide-Window, Wiggle-Mouse, Set-GhostWindow, Remove-GhostWindow, Remove-AeroPeek

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me