#How to navigate to specified directories within an already open file explorer window using PS

23 messages · Page 1 of 1 (latest)

golden stratus
#

If I just used Invoke-Item . it would open a new explorer.exe window

dim ginkgo
#

Probably impossible

simple adder
#

Not impossible at all:

$filePath = Convert-Path path\to\file.ext
explorer.exe "/select,""$filePath"""
golden stratus
simple adder
#

Try this:

# define target file 
$targetFile = Get-Item .\path\to\file.ext

# conditionally define helper class with bindings for calling shell32.dll
try {
    # test if type already exists
    $null = [Type]'SHFolderHelper'
} catch {
Add-Type @'
using System;
using System.Runtime.InteropServices;

public static class SHFolderHelper {
    [DllImport("shell32.dll")]
    public static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags);

    [DllImport("shell32.dll")]
    public static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, out IntPtr pidl, uint sfgaoIn, out uint psfgaoOut);
}
'@
}

# get PIDL for folder
$targetFolder = $targetFile.Directory
$folderPIDL = [IntPtr]::Zero
[SHFolderHelper]::SHParseDisplayName($targetFolder.FullName, [IntPtr]::Zero, [ref]$folderPIDL, 0, [ref]$null)
if ($folderPIDL -eq [IntPtr]::Zero) { return }

try {
    # get PIDL for file object
    $filePIDL = [IntPtr]::Zero
    [SHFolderHelper]::SHParseDisplayName($targetFile.FullName, [IntPtr]::Zero, [ref]$filePIDL, 0, [ref]$null)
    try {
        if ($folderPIDL -ne [IntPtr]::Zero -and $filePIDL -ne [IntPtr]::Zero) {
            # Open + Select
            [SHFolderHelper]::SHOpenFolderAndSelectItems($folderPIDL, 1, @($filePIDL), 0) |Out-Null
        }
    }
    finally {
        if ($filePIDL -ne [IntPtr]::Zero) {
            # clean up file PIDL
            [System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($filePIDL)
        }
    }
}
finally {
    if ($folderPIDL -ne [IntPtr]::Zero) {
        # clean up folder PIDL
        [System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($folderPIDL)
    }
}
golden stratus
#
Type [SHFolderHelper] not found.
At character C:\Users\sdsadas\Downloads\main.ps1:26:1
+ [SHFolderHelper]::SHParseDisplayName($targetFolder.FullName, [IntPtr] ...
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (SHFolderHelper:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound
simple adder
#

Edited, try again

golden stratus
simple adder
#

What did you put as the file path?

#

C:\something.ext?

#

There's no explicit error handling for the target file in the snippet above, so if you ran it as-is, with $targetFile = Get-Item .\path\to\file.ext and no such file exists it won't be able to select it

golden stratus
simple adder
#

Curious. If I run it twice in a row it re-uses the same window

#

Win10 or 11?

golden stratus
simple adder
#

Yeah, I run the code once, explorer window pops up with file select. I then Alt+Tab back to the powershell window, run the code again, and the exact same explorer window is reused

golden stratus
#

but is there a way to actually move to a directory in an already opened powershell window

simple adder
#

You mean like Set-Location/cd?

#

I guess you could interact with existing windows and forcefully navigate them to the desired location:

$sh = New-Object -ComObject Shell.Application
$windows = @($sh.Windows())
if ($windows = @($sh.Windows())) {
  $targetFolderUri = [uri]$targetFolder.FullName

  if ($targetWindow = $windows |? LocationURL -eq $targetFolderUri |Select -First 1) {
    # window with target folder already open, proceed
  }
  else {
    # windows exist, but none in the correct folder
    $windows[0].Navigate2($targetFolderUri)
  }
}

# proceed to open+select
golden stratus