Question

I'm a total noob on windows powershell. How can I use psl to call SHGetKnownFolderPath ? I want to then also call SHSetKnownFolderPath if I dont like some of the values back from Get call.

Was it helpful?

Solution

You can use P/Invoke. Lee Holmes has an example of how to do this from PowerShell here. There's an example of how to use SHGetKnownFolderPoath here.

Alternatively, you might just be able to use Environment.GetFolderPath:

PS> [Environment]::GetFolderPath('CommonApplicationData')
C:\ProgramData

You can get the list of available options by the following:

PS> [Enum]::GetNames([Environment+SpecialFolder])

OTHER TIPS

Before you delve into static methods in the Framework, look at the variables in the Env: PSDrive.

get-childitem env:

(get-item env:\CommonProgramFiles).Value

According to this Tutorial (and others) the settings are in the registry:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders]

Those are an easy read in powershell, access them as a drive:

ps> cd hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\
ps> dir

And use the standard powershell tools to read these settings.

NOTE: You can set them with powershell here however that might ruin your day.

If you use the explorer to change the directory, it also moves the directory and stores the settings on multiple locations, like both 'User Shell Folders' and 'Shell Folders'.

Here's a function you can use that will use SHGetKnownFolderPath to convert a well-known folder guid to its current path:

Function GetKnownFolder([string]$KnownFolderCLSID) {
  $KnownFolderCLSID = $KnownFolderCLSID.Replace("{", "").Replace("}", "")
  $GetSignature = @'
    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]public extern static int SHGetKnownFolderPath(
    ref Guid folderId, 
    uint flags, 
    IntPtr token,
    out IntPtr pszProfilePath);
'@
  $GetType = Add-Type -MemberDefinition $GetSignature -Name 'GetKnownFolders' -Namespace 'SHGetKnownFolderPath' -Using "System.Text" -PassThru -ErrorAction SilentlyContinue
  $ptr = [intptr]::Zero
  [void]$GetType::SHGetKnownFolderPath([Ref]"$KnownFolderCLSID", 0, 0, [ref]$ptr)
  $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
  [System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($ptr)
  return $result
}

Usage example:

GetKnownFolder "C4AA340D-F20F-4863-AFEF-F87EF2E6BA25"

Will return

C:\Users\Public\Desktop

Reference for Well-Known folder GUID's can be found at Microsoft

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top