Какая переменная среды для пути к рабочему столу?

Я пишу командный файл Windows и хочу скопировать что-то на рабочий стол. Я думаю, что я могу использовать это:

% USERPROFILE%\Desktop\

Тем не менее, я думаю, что это будет работать только на английской ОС. Есть ли способ сделать это в командном файле, который будет работать на любой интернационализированной версии?

ОБНОВИТЬ

Я попробовал следующий пакетный файл:

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%

И получил этот вывод:

S: \> REG QUERY "HKCU \ Software \Microsoft\Windows\CurrentVersion\Explorer\ Папки пользовательских оболочек" /v Рабочий стол

HKEY_CURRENT_USER\ Программное обеспечение \Microsoft\Windows\CurrentVersion\Explorer\ Папки пользовательских оболочек
    Рабочий стол REG_EXPAND_SZ    %USERPROFILE%\ Рабочий стол


S:\>FOR /F "маркеры usebackq =3 skip=4" %i in (HKCU "REG QUERY" \ Программное обеспечение \Microsoft\Windows\CurrentVersion\Explorer\ Папка пользовательской оболочки
s" /v Desktop`) DO SET DESKTOPDIR=%i

S:\>FOR /F "usebackq delims=" %i in (`ECHO ECHO включено`.) DO SET DESKTOPDIR=%i

S:\>SET DESKTOPDIR=ECHO включено.

S:\> ЭХО ЭХО включено.
ЭХО включено.

19 ответов

Решение

Я обнаружил, что лучшее решение - использовать vbscript вместе с командным файлом.

Вот командный файл:

@ECHO OFF
FOR /F "usebackq delims=" %%i in (`cscript findDesktop.vbs`) DO SET DESKTOPDIR=%%i
ECHO %DESKTOPDIR%

Вот файл findDesktop.vbs:

set WshShell = WScript.CreateObject("WScript.Shell")
strDesktop = WshShell.SpecialFolders("Desktop")
wscript.echo(strDesktop)

Могут быть и другие решения, но лично я считаю это менее хакерским.

Я проверил это на английском ПК, а также на французском ПК - похоже, работает (Windows XP).

НТН,

Юлиан Шербаною

Чтобы быть в безопасности, вы должны использовать надлежащие API в Powershell (или VBScript)
Использование PowerShell:

[Environment]::GetFolderPath("Desktop")

Скопируйте что-нибудь с помощью Powershell:

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

Вот пример VBScript для получения пути к рабочему столу:

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

По крайней мере, в Windows XP, Vista и 7 вы можете использовать "%UserProfile%\Desktop" безопасно.

Windows XP en-US расширится до "C:\Documents and Settings\YourName\Desktop"
Windows XP pt-BR расширится до "C:\Documents and Settings\YourName\Desktop"
Windows 7 en-US расширится до "C:\Users\YourName\Desktop"
Windows 7 PT-BR будет расширяться до "C:\Usuarios\YourName\Desktop"

В XP вы не можете использовать это для других папок, кроме рабочего столаMy documents поворачиваясь к Meus Documentos а также Local Settings в Configuracoes locais Лично я считаю, что это плохо при проектировании ОС.

Ответ КБ на использование [Environment]::GetFolderPath("Desktop") очевидно, официальный Windows API для этого.

Однако, если вы работаете в интерактивном режиме по приглашению или просто хотите что-то, что работает на вашем компьютере, символ тильды (~) относится к домашней папке текущего пользователя. Так ~/desktop папка рабочего стола пользователя

Мало того, что это не будет работать для международной версии Windows, оно не будет работать, если пользователь отредактирует реестр, чтобы его папка Desktop находилась где-то еще. Вы можете запросить реестр для определения местоположения файла, используя REG команда:

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%

Вы также можете открыть командную строку DOS и выполнить команду set.

Это даст вам представление о том, какие переменные среды доступны в вашей системе.

Например, поскольку вы специально просили неанглийскую версию Windows, вот пример моего немецкого издания (Window7-64bit):

set> env.txt
введите env.txt

ALLUSERSPROFILE=C:\ProgramData
AppData =C:\Users\SOF\AppData\Roaming
CommonProgramFiles=C:\Program Files\ Общие файлы
CommonProgramFiles(x86)=C:\Program Files (x86)\ Общие файлы
CommonProgramW6432=C:\Program Files\ Общие файлы
COMPUTERNAME=VMSOF
COMSPEC =C:\Windows\system32\cmd.exe
FP_NO_HOST_CHECK= НЕТ
HOMEDRIVE= С:
HOMEPATH=\Users\SOF
LocalAppData =C:\Users\SOF\AppData\Local
LOGONSERVER=\\VMSOF
NUMBER_OF_PROCESSORS=2
OS=Windows_NT
Путь =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, семейство 15, модель 67, шаг 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
ПОДСКАЖИТЕ =$P$G
PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
PUBLIC=C:\Users\Public
Имя_сеанс = Консоль
Системный_диск = С:
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

Если вы хотите использовать

[Environment]::GetFolderPath("Desktop")

изнутри cmd.exe, вы можете это сделать (спасибо пользователю MS Мариану Паскалау в этой теме)

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%

В Windows 7 это возвращает путь к рабочему столу:

FOR / F "usebackq tokens = 3" %% i in (`REG QUERY" HKCU \ Программное обеспечение \Microsoft\Windows\CurrentVersion\Explorer\ Папки пользовательских оболочек " /v Desktop`) DO SET DESKTOPDIR=%%i 
FOR /F "usebackq delims=" %%i in (`ECHO %DESKTOPDIR%`) DO SET DESKTOPDIR=%%i 
ECHO %DESKTOPDIR% 

Это не решение, но я надеюсь, что это поможет: это подходит близко, за исключением того, что когда KEY = %userprofile%\desktop, копия завершается ошибкой, даже если zdesktop=%userprofile%\desktop. Я думаю, потому что встроенный% userprofile% не переводится.

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

Таким образом, он успешно разбирает ключ REG, но если ключ содержит встроенный%var%, он не переводится во время команды копирования.

Хотя я понимаю, что это немного более старый пост, я подумал, что это может помочь людям в аналогичной ситуации. Я сделал быстрый однострочный VBScript для извлечения информации для любой специальной папки (без проверки ошибок), и она работает так:

Создайте файл "GetShellFolder.vbs" со следующей строкой:

WScript.Echo WScript.CreateObject("WScript.Shell").SpecialFolders(WScript.Arguments(0))

Я всегда проверяю, чтобы скопировать cscript.exe (32-разрядная версия) в ту же папку, что и пакетный файл, из которого я запускаю этот файл, я предполагаю, что вы делаете то же самое (у меня были ситуации, когда пользователи каким-то образом удаляли C:\Windows\system32 с их пути либо удалось избавиться от cscript.exe, либо он заражен или иным образом не работает).

Теперь скопируйте файл для копирования в ту же папку и создайте там пакетный файл со следующими строками:

for /f "delims=" %%i in ('^""%~dp0cscript.exe" "%~dp0GetShellFolder.vbs" "Desktop" //nologo^"') DO SET SHELLDIR=%%i
copy /y "%~dp0<file_to_copy>" "%SHELLDIR%\<file_to_copy>"

В приведенном выше коде вы можете заменить "Рабочий стол" любой действительной специальной папкой ("Избранное", StartMenu и т. Д. - полный официальный список находится по адресу https://msdn.microsoft.com/en-us/library/0ea7b5xe%28v=vs.84%29.aspx) и, конечно, <file_to_copy> с фактическим файлом, который вы хотите разместить там. Это избавляет вас от попыток получить доступ к реестру (что вы не можете сделать как пользователь с ограниченными правами в любом случае) и должно быть достаточно простым для адаптации к нескольким приложениям.

Ох, и для тех, кто не знает "%~dp0" это просто каталог, из которого вызывается скрипт. Он работает и для путей UNC, что делает пакетный файл, использующий его, чрезвычайно переносимым. Это, в частности, заканчивается завершающим "\", хотя на первый взгляд может показаться немного странным.

У меня была похожая проблема (и VBScript или PowerShell не было вариантом), и код, который я нашел в этой статье, не работал для меня. У меня были проблемы с версиями ОС и языковыми версиями. После некоторых экспериментов я пришел к этому решению:

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

:reparse
%*
goto :EOF

Этот код работает для меня в английской и польской версиях Windows 7 и Windows XP.

Подпрограмма:reparse допускает отложенное расширение переменных среды.

Многоязычная версия, протестирована на японской ОС
Пакетный файл

set getdesk=REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ Папки оболочки пользователя" /v Рабочий стол
FOR /f "delims=(=" %%G IN ('%getdesk% ^|find "_SZ"') DO set desktop=%%G
установить desktop1=% desktop: * USERPROFILE% \ =%
cd "% userprofile% \% desktop1%"
установить getdesk =
установить desktop1=
установить рабочий стол =

Это должно работать независимо от языковой версии Windows и независимо от того, где находится папка. Также не имеет значения, есть ли пробелы в пути к папке.

FOR /F "tokens=2*" %%A IN ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop^|FIND/I "desktop"') DO SET Desktop=%%B
ECHO %Desktop%

В случае Windows 2000 (и, вероятно, NT 4.0) вам нужно скопировать reg.exe в папку%windir% вручную, поскольку она по умолчанию там недоступна.

Ответ @Dave Webb, вероятно, путь. Единственное, о чем я могу думать, это CSIDL:

CSIDL_DESKTOPDIRECTORY

Каталог файловой системы, используемый для физического хранения файловых объектов на рабочем столе (что не следует путать с самой папкой рабочего стола). Типичный путь - это C:\Documents and Settings\ имя пользователя \Desktop.

Я понятия не имею, как получить их из командной строки, хотя.

Я использую этот код, чтобы получить пути к рабочему столу пользователя и общедоступному рабочему столу из реестра, протестированному на Windows XP SP2 pt-PT и Windows 10 b14393 en-US, поэтому он, вероятно, работает в Vista/7/8 и других языках.

:: get user desktop and public desktop paths
for /f "tokens=* delims= " %%a in ('reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop ^|find /i "REG_"') do set "batch_userdesktop=%%a"
for /f "tokens=* delims= " %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Common Desktop" ^|find /i "REG_"') do set "batch_publicdesktop=%%a"

:: remove everything up to and including "_SZ"
set "batch_userdesktop=%batch_userdesktop:*_sz=%"
set "batch_publicdesktop=%batch_publicdesktop:*_sz=%%

:: remove leading spaces and TABs
:loop
if "%batch_userdesktop:~0,1%"==" " set "batch_userdesktop=%batch_userdesktop:~1%" & goto loop
if "%batch_publicdesktop:~0,1%"==" " set "batch_publicdesktop=%batch_publicdesktop:~1%" & goto loop
if "%batch_userdesktop:~0,1%"=="    " set "batch_userdesktop=%batch_userdesktop:~1%" & goto loop
if "%batch_publicdesktop:~0,1%"=="  " set "batch_publicdesktop=%batch_publicdesktop:~1%" & goto loop

Последние две строки включают TAB внутри " ", некоторые текстовые редакторы добавляют пробелы, когда вы нажимаете TAB, поэтому убедитесь, что у вас есть настоящий TAB вместо пробелов.

Я не уверен, что код требует setlocal enabledelayedexpansion, он является частью моего SETVARS.CMD, который я вызываю из других пакетов для установки общих переменных, таких как архитектура процессора, язык учетной записи, версия Windows и пакет обновления, путь к пользовательскому / общедоступному рабочему столу и т. Д.

TL;DR

кажется самым безопасным способом.

Обсуждение

Предположения о том, на каком диске находится объект, довольно хрупкие в Windows, поскольку в нем отсутствует единое дерево каталогов, в котором монтирования будут отображаться в каталоги внутри. Следовательно %HOMEDRIVE% Переменная важна для ссылки, чтобы убедиться, что вы выбрали правильный (это не всегда C:\!).

Неанглийские языковые стандарты обычно имеют локализованные имена для таких вещей, как «Рабочий стол», «Изображения» и т. Д., Но, к счастью, все они являются псевдонимами, указывающими на Desktop, который, кажется, является основным каноническим именем каталога независимо от локали (мы безопасно используем его здесь, в Японии, Таиланде, Израиле и США).

Большая причуда заключается в том, чтобы определить, %UserProfile%указывает на фактический базовый каталог профиля пользователя, или на его рабочий стол, или на другое место. Я не совсем Windows-разработчик, но я нашел каталог профиля для настроек, но %HOMEPATH%предназначен для собственных файлов пользователя, поэтому он указывает на корень каталога, который ведет к Desktop / Downloads / Pictures / etc. Это приводит к тому, что %HOMEDRIVE%%HOMEPATH%\Desktop самый безопасный способ.

Довольно старая тема. Но я хочу отдать свои 2 цента...

Я немного изменил решение tomasz86, чтобы он выглядел в старом стиле "Папки оболочки" вместо "Папки пользовательской оболочки", поэтому мне не нужно расширять envvar %userprofile%

Также нет зависимости от 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%

Надеюсь, это поможет.

Эти команды напечатают путь к рабочему столу наcmd.exe:

      powershell "[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::Desktop)"
      FOR /F "tokens=2*" %i IN ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Desktop ^| findstr "desktop"') DO echo %j

Я знаю, что это довольно старая тема, но я бы использовал переменную Powershell

$env:UserProfile 

Чтобы использовать его, чтобы попасть на рабочий стол, это будет:

cd $env:UserProfile\desktop

Это работает как локально, так и удаленно в Windows 7. Надеюсь, что это полезно, так как я столкнулся с ситуацией, когда клиентский компьютер не имел значения в $home.

Другие вопросы по тегам