中国DOS联盟论坛

China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --
Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
Guest | Log in | Register | Members | Search | China DOS Union
中国DOS联盟论坛
The time now is 2026-09-26 19:44
47,813 topics / 349,918 posts / today 0 new / 48,276 members
DOS批处理 & 脚本技术(批处理室) » [Discussion] [NT] A simple way to expand variables contained inside an expanded variable?
Printable Version  818 / 4
Floor1 BatMan Posted 2008-01-05 13:55
初级用户 Posts 24 Credits 54
  When using BAT, I need to access the My Documents directory. I found that no system environment variable points there, and my My Documents has been customized so it is not at the system default location %USERPROFILE%\My Documents, so I read the value of Personal under HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders from the registry and assign it to a variable for use.

  This method works well on my machine, but on other machines where the My Documents location has not been customized, the value obtained from the registry is %USERPROFILE%\My Documents, and I want to expand it once more so it becomes a value without any unexpanded variables, such as C:\Documents And Settings\UserName\My Documents.

  My current solution is as follows. It feels a bit verbose, and I hope to see a more concise way to achieve the same effect. Also, if there is a simpler way to get the My Documents directory, please do share it. Thanks!

@ECHO OFF
FOR /F "tokens=2*" %%I IN ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" ^| FIND /i "Personal"') DO SET "Personal=%%J"

CALL :ExpandPathMacro "%Personal%" Personal

ECHO %Personal%
PAUSE
@ECHO ON
@GOTO :EOF

:: Expand path macro, parameter 1 is the string to be expanded, parameter 2 is the return variable name
:ExpandPathMacro
SETLOCAL ENABLEDELAYEDEXPANSION
SET "EPM=%~1"
SET "EPM=!EPM:%%=?!"
SETLOCAL ENABLEEXTENSIONS & ENDLOCAL & SET "EPM=%EPM:?=!%"
ENDLOCAL & SET "%2=%EPM%"
GOTO :EOF


[ Last edited by BatMan on 2008-1-5 at 02:15 PM ]
Floor2 BatMan Posted 2008-01-05 16:50
初级用户 Posts 24 Credits 54
I played around with it a bit more myself and found a simpler method: modify the ExpandPathMacro function to:

:ExpandPathMacro
SET "%~2=%~1"
GOTO :EOF

It's already much simpler. Is there any way to do it directly at the same statement level without calling a function?
Floor3 qzwqzw Posted 2008-01-05 21:13
银牌会员 Posts 636 Credits 2,343
You're taking too much of a detour.
There are two more direct methods.

One is to add a call in front of SET "Personal=%%J"
making it CALL SET "Personal=%%J"
Then all the other expansion code can be omitted.

The other is to read the value under Shell Folders
instead of under User Shell Folders.
Please note the difference between the values in the two.
The main differences are the type and whether expansion is involved.

Also, I found a problem with reg query under 03.
Not sure whether it's a bug.
When querying values under reg query user shell folders,
all values of type reg_expand_sz are displayed as reg_sz.
If a value contains expansion symbols such as %,
it reports “ERROR: More data is available.”
and then does not display those reg_expand_sz values containing expansion symbols.
Floor4 BatMan Posted 2008-01-05 21:37
初级用户 Posts 24 Credits 54
Originally posted by qzwqzw at 2008-1-5 21:13:
You're taking too much of a detour.
There are two more direct methods.

One is to add a call in front of SET "Personal=%%J"
making it CALL SET "Personal=%%J"
Then all the other expansion code can be omitted.

The other is ...


Thanks, post #3! Learned something!

  Also, on the XP Sp2 machine at my company I have seen some values under User Shell Folders appear as REG_SZ and some as REG_EXPAND_SZ. I haven't looked into the cause or impact.
Floor5 qzwqzw Posted 2008-01-05 21:44
银牌会员 Posts 636 Credits 2,343
It should be that some software or individuals modified them later on,
and did not follow Windows conventions when making the changes.
[ Contact the Union admin team - 中国DOS联盟 - Standard version ]
Sponsored by ifanr Inc | © 2001–2023