# encoding: ascii
# api: powershell
# title: jumper.psm1
# description: Usage:
# version: 0.1
# type: class
# author: greg zakharov
# license: CC0
# function: Push-Path
# x-poshcode-id: 5169
# x-archived: 2016-03-18T21:35:04
# x-published: 2016-05-20T13:55:00
#
# PS> Import-Module jumper
# #now u r ready to jump. for example
# PS> jumper X:\bin
# #or
# PS> Push-Path X:\bin
# #jump to a registry path
# PS> jumper hkcu\software\microsoft\windows\currentversion
# #or
# PS> Push-Path hkcu\software\microsoft\windows\currentversion
# P.S. to Jeff Hicks about asylum. It was a joke :)
#
#requires -version 2.0
if (!(Test-Path alias:jumper)) { Set-Alias jumper Push-Path }
$asm = Add-Type -MemberDefinition @'
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
internal static extern IntPtr OpenProcess(
UInt32 dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)]Boolean bInheritHandle,
UInt32 dwProcessId
);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr FindWindow(
String lpClassName,
String lpWindowName
);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
String lpszClass,
String lpszWindow
);
[DllImport("user32.dll")]
internal static extern UInt32 GetWindowThreadProcessId(
IntPtr hWnd,
out UInt32 lpwdProcessId
);
[DllImport("user32.dll")]
internal static extern IntPtr SendMessage(
IntPtr hWnd,
UInt32 Msg,
IntPtr wParam,
IntPtr lParam
);
[DllImport("user32.dll")]
internal static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean ShowWindow(
IntPtr hWnd,
UInt32 nCmdShow
);
const UInt32 SW_SHOW = 0x00000005;
const UInt32 SYNCHRONIZE = 0x00100000;
public static void RegJump(String path) {
IntPtr RegEditMain;
IntPtr RegEditHwnd;
UInt32 ProcessId = 0;
IntPtr hndl;
RegEditMain = FindWindow("RegEdit_RegEdit", null);
if (RegEditMain == IntPtr.Zero) {
Process.Start("regedit.exe");
Thread.Sleep(100); //make a pause before next step
RegEditMain = FindWindow("RegEdit_RegEdit", null);
}
if (RegEditMain == IntPtr.Zero) {
Console.WriteLine("Unable to launch regedit.");
Environment.Exit(1);
}
ShowWindow(RegEditMain, SW_SHOW);
RegEditHwnd = FindWindowEx(RegEditMain, IntPtr.Zero, "SysTreeView32", null);
SetFocus(RegEditHwnd);
if (GetWindowThreadProcessId(RegEditHwnd, out ProcessId) != 0) {
hndl = OpenProcess(SYNCHRONIZE, false, ProcessId);
for (Int32 i = 0; i < 30; i++)
SendMessage(RegEditHwnd, (UInt32)0x100, (IntPtr)0x25, IntPtr.Zero);
//jump
Char[] c = path.ToCharArray();
for (Int32 i = 0; i < c.Length; i++) {
if (c[i].Equals('\\'))
SendMessage(RegEditHwnd, (UInt32)0x100, (IntPtr)0x27, IntPtr.Zero);
else
SendMessage(RegEditHwnd, (UInt32)0x102, (IntPtr)c[i], IntPtr.Zero);
}
SetForegroundWindow(RegEditMain);
SetFocus(RegEditMain);
CloseHandle(hndl);
}
}
'@ -Name Jumper -NameSpace NativeMethods -Using System.Diagnostics, System.Threading -PassThru
function Push-Path {
<#
.NOTES
Author: greg zakharov
#>
param(
[Parameter(Mandatory=$true)]
[String]$Path
)
begin {
function Test-PathAndJump([String]$Path) {
try {
[void][IO.Directory]::GetAccessControl($Path)
[void][Diagnostics.Process]::Start('explorer.exe', '/n, ' + $Path)
}
catch [Management.Automation.MethodInvocationException] {
Write-Host Requesting path access is not allowed.
}
}
}
process {
if (Test-Path $Path) { Test-PathAndJump $Path }
else {
if (Test-Path ($key = 'Registry::' + $Path.ToUpper())) {
try {
$key = '\' + (gi -ea 1 $key).Name + '\'
$asm::RegJump($key)
}
catch { $_.Exception.Message }
}
}
}
end {''}
}
Export-ModuleMember -Alias jumper -Function Push-Path