What's the environment variable for the path to the desktop?

Viewed 235076

I'm writing a Windows batch file and want to copy something to the desktop. I think I can use this:

%UserProfile%\Desktop\

However, I'm thinking, that's probably only going to work on an English OS. Is there a way I can do this in a batch file that will work on any internationalized version?

UPDATE

I tried the following batch file:

REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop
FOR /F "usebackq tokens=3 skip=4" %%i in (`REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop`) DO SET DESKTOPDIR=%%i
FOR /F "usebackq delims=" %%i in (`ECHO %DESKTOPDIR%`) DO SET DESKTOPDIR=%%i
ECHO %DESKTOPDIR%

And got this output:

S:\>REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
    Desktop    REG_EXPAND_SZ    %USERPROFILE%\Desktop


S:\>FOR /F "usebackq tokens=3 skip=4" %i in (`REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folder
s" /v Desktop`) DO SET DESKTOPDIR=%i

S:\>FOR /F "usebackq delims=" %i in (`ECHO ECHO is on.`) DO SET DESKTOPDIR=%i

S:\>SET DESKTOPDIR=ECHO is on.

S:\>ECHO ECHO is on.
ECHO is on.
18 Answers

To be safe, you should use the proper APIs in Powershell (or VBScript)
Using PowerShell:

[Environment]::GetFolderPath("Desktop")

Copy something using Powershell:

Copy-Item $home\*.txt ([Environment]::GetFolderPath("Desktop"))

Here is a VBScript-example to get the desktop path:

dim WSHShell, desktop, pathstring, objFSO
set objFSO=CreateObject("Scripting.FileSystemObject")
Set WSHshell = CreateObject("WScript.Shell")
desktop = WSHShell.SpecialFolders("Desktop")
pathstring = objFSO.GetAbsolutePathName(desktop)
WScript.Echo pathstring

Not only would that not work for an International version of Windows, it would fail if the user had edited the Registry to make their Desktop folder reside somewhere else. You can query the Registry for the file location using the REG command:

REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop

To get this into a variable use something like this:

FOR /F "usebackq tokens=3 skip=4" %%i in (`REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop`) DO SET DESKTOPDIR=%%i
FOR /F "usebackq delims=" %%i in (`ECHO %DESKTOPDIR%`) DO SET DESKTOPDIR=%%i
ECHO %DESKTOPDIR%

you could also open a DOS command prompt and execute the set command.

This will give you an idea what environment variables are available on your system.

E.g. - since you where specifically asking for a non-english Windows - heres is an example of my own German Edition (Window7-64bit) :

set > env.txt
type env.txt

ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\SOF\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=VMSOF
ComSpec=C:\Windows\system32\cmd.exe
FP_NO_HOST_CHECK=NO
HOMEDRIVE=C:
HOMEPATH=\Users\SOF
LOCALAPPDATA=C:\Users\SOF\AppData\Local
LOGONSERVER=\\VMSOF
NUMBER_OF_PROCESSORS=2
OS=Windows_NT
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\CMake 2.8\bin;C:\Program Files (x86)\emacs-22.3\bin;C:\Program Files (x86)\GnuWin32\bin;
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=AMD64 Family 15 Model 67 Stepping 3, AuthenticAMD
PROCESSOR_LEVEL=15
PROCESSOR_REVISION=4303
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
PUBLIC=C:\Users\Public
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\SOF\AppData\Local\Temp
TMP=C:\Users\SOF\AppData\Local\Temp
USERDOMAIN=VMSOF
USERNAME=SOF
USERPROFILE=C:\Users\SOF
VBOX_INSTALL_PATH=C:\Program Files\Sun\VirtualBox\
VS90COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\
windir=C:\Windows

If you wish to use the

[Environment]::GetFolderPath("Desktop")

from within a cmd.exe, you may do so (thanks to MS User Marian Pascalau on this thread)

set dkey=Desktop
set dump=powershell.exe -NoLogo -NonInteractive "Write-Host $([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::%dkey%))"
for /F %%i in ('%dump%') do set dir=%%i

echo Desktop directory is %dir%

This is not a solution but I hope it helps: This comes close except that when the KEY = %userprofile%\desktop the copy fails even though zdesktop=%userprofile%\desktop. I think because the embedded %userprofile% is not getting translated.

REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop>z.out
for /f "tokens=3 skip=4" %%t in (z.out) do set zdesktop=%%t
copy myicon %zdesktop%
set zdesktop=
del z.out

So it sucessfully parses out the REG key but if the key contains an embedded %var% it doesn't get translated during the copy command.

@Dave Webb's answer is probably the way to go. The only other thing I can think of are the CSIDLs:

CSIDL_DESKTOPDIRECTORY

The file system directory used to physically store file objects on the desktop (which should not be confused with the desktop folder itself). A typical path is C:\Documents and Settings\username\Desktop.

I have no idea how to get hold of those from the command line, though.

Quite old topic. But I want to give my 2 cents...

I've slightly modified tomasz86 solution, to look in the old style "Shell Folders" instead of "User Shell Folders", so i don't need to expand the envvar %userprofile%

Also there is no dependency from powershell/vbscript/etc....

for /f "usebackq tokens=2,3*" %%A in (`REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Desktop"`) do if %%A==REG_SZ  set desktopdir=%%B
echo %desktopdir%

Hope it helps.

TL;DR

%HOMEDRIVE%%HOMEPATH%\Desktop seems to be the safest way.

Discussion

Assumptions about which drive a thing is on are quite fragile in Windows as it lacks a unified directory tree where mounts would map to directories internally. Therefore the %HOMEDRIVE% variable is important to reference to make sure you're on the right one (it isn't always C:\!).

Non-English locales will usually have localized names for things like "Desktop" and "Pictures" and whatnot, but fortunately they are all aliases that point to Desktop, which seems to be the underlying canonical directory name regardless of locale (we use this safely here in Japan, Thailand, Israel and the US).

The big quirk comes with determining whether %UserProfile% points to the user's actual profile base dir, or their Desktop or somewhere completely different. I'm not really a Windows dev, but what I've found is the profile dir is for settings, but the %HOMEPATH% is for the user's own files, so this points to the directory root that leads to Desktop/Downloads/Pictures/etc. This tends to make %HOMEDRIVE%%HOMEPATH%\Desktop the safest way.

Related