4

I am looking to write a batch file that copies a file to the user's Documents folder, but I cannot find the environment variable that indicates it. I can derive the Documents folder from the user profile path, but this is unreliable since Windows can move the Documents folder to any location, by selecting the Location tab + Move in the folder properties.

Anybody know how to find the folder?

Jerry Nixon
  • 31,313
  • 14
  • 117
  • 233
  • 1
    What makes you think there would be an environment variable for this? Also, you can see a list of all current environment variables by typing `set` on the command line. – SomethingDark Jan 19 '16 at 23:35

3 Answers3

7

There is no environment variable for this. You can, instead, look in the Windows Registry in the place where it stores the name of the Documents folder, but even that is deprecated:

@echo off
for /f "tokens=3*" %%p in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v Personal') do (
    set DocumentsFolder=%%p %%q
)
echo %DocumentsFolder%

Note the implicit %%q variable which captures the remainder of the path if there are spaces.

Mike
  • 970
  • 8
  • 13
Klitos Kyriacou
  • 10,634
  • 2
  • 38
  • 70
  • That didn't exist in the systems I looked at. – RLH Jan 20 '16 at 00:02
  • 1
    Works for me as well. My `Documents` Library points to `D:\Documents` and this gave the correct output. It's possible that the Library has to be modified for the HKCU value to be created, though. More testing might be worthwhile. – rojo Jan 20 '16 at 00:24
  • 2
    It may or may not exist but even if it does, you have to also check this key value for customization: `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Personal` – RLH Jan 20 '16 at 00:42
5

Well, what you're asking isn't fool proof. What you're referring to is Libraries. And the problem with Libraries is that there can be more than one folder included in a Library.

However, there is a reasonable way to get what you want. Windows provides ShellSpecialFolder constants you can enumerate using the Shell.Application COM object. The constant for the Documents Library is 0x05. Here's a PowerShell command example:

powershell "(new-object -COM Shell.Application).Namespace(0x05).Self.Path"

My home computer has a 120GB SSD boot drive and a 2TB D: drive. So I have my Documents library pointing to D:\Documents. The command above prints D:\Documents as you'd hope it would.

If you're prefer Windows Script Host over PowerShell (as WSH is much faster), you can write a hybrid batch + JScript script to accomplish the same task.

@if (@CodeSection == @Batch) @then
@echo off & setlocal

rem // cscript re-evaluates this script with the JScript interpreter
cscript /nologo /e:JScript "%~f0"

goto :EOF
@end // end Batch / begin JScript hybrid chimera

WSH.Echo(WSH.CreateObject('Shell.Application').Namespace(0x05).Self.Path);

You might also consider letting the user browse to his desired save location, defaulting to 0x05 for Documents.

Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
3

I don't see a perfectly reliable way to do this in batch. I know this is outside the request but I think this vbscript will work reliably.

Option explicit
Dim objShell
Dim strPath

Set objShell = Wscript.CreateObject("Wscript.Shell")
strPath = objShell.SpecialFolders("MyDocuments")
msgbox strPath
RLH
  • 1,545
  • 11
  • 12
  • 1
    Great minds think alike. :) +1 for also using ShellSpecialFolder constants at the same time as I did. Curiously, your method, `WSH.CreateObject('Wscript.Shell').SpecialFolders('MyDocuments')` has the same output as mine, `WSH.CreateObject('Shell.Application').Namespace(0x05).Self.Path`, and has exactly the same number of characters. – rojo Jan 20 '16 at 00:22