Alan Jurgensen
Alan Jurgensen

Reputation: 853

How can I use powershell to call SHGetKnownFolderPath?

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.

Upvotes: 4

Views: 4175

Answers (4)

KeyszerS
KeyszerS

Reputation: 684

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

Upvotes: 1

CBee
CBee

Reputation: 49

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'.

Upvotes: 0

alroc
alroc

Reputation: 28154

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

Upvotes: 0

Roger Lipscombe
Roger Lipscombe

Reputation: 91825

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])

Upvotes: 10

Related Questions