我正在尝试为我公司的用户创建一个批处理文件,用于从旧的个人文件夹中迁移文件'网络共享到我们新的OneDrive实现。
问题是,我们的一些用户已将OneDrive的默认同步文件夹更改为他们想要的任何驱动器和路径,而不是保留默认值(* c:\ users \ username *)...例如,我用来测试我的BAT文件正在使用:
D:\ OneDrive - Business
然而,当它包含更多或更少的分隔符时仍然必须工作,例如 C:\ OneDrive 或 C:\这就是我愚蠢存储的东西。
此时,我已尝试使用REG QUERY从注册表中的UserFolder键输出到文本文件以获取路径,现在我尝试从文本文件中提取此路径有问题并将其设置为变量。创建的文本文件如下所示:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\Accounts\Business1
UserFolder REG_SZ D:\OneDrive - Business
我想要做的是设置" D:\ OneDrive - Business"到脚本化MOVE命令中使用的变量。
我的代码非常糟糕,除非有人认为有必要回答我的问题,否则我不会发布它。
我确信至少对你来说,这是孩子的游戏,所以我真的很感激为我提供的任何帮助!
谢谢!
答案 0 :(得分:1)
以下是此任务的一个批处理解决方案:
@echo off
for /F "skip=1 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe QUERY HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1 /v UserFolder 2^>nul') do if /I "%%A" == "UserFolder" if not "%%C" == "" set "UserFolder=%%C" & goto UserFolderSet
echo No user folder for OneDrive found in Windows registry.
goto :EOF
:UserFolderSet
echo Found user folder: "%UserFolder%"
更好的可读性是这个版本完全相同:
@echo off
for /F "skip=1 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe QUERY HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1 /v UserFolder 2^>nul') do (
if /I "%%A" == "UserFolder" (
if not "%%C" == "" (
set "UserFolder=%%C"
goto UserFolderSet
)
)
)
echo No user folder for OneDrive found in Windows registry.
goto :EOF
:UserFolderSet
echo Found user folder: "%UserFolder%"
命令 FOR 在后台命令进程中执行命令 REG ,并捕获其输出,以处理 STDOUT 。
REG 输出错误消息以处理 STDERR 会因为2^>nul
将其重定向到设备 NUL 而被抑制。重定向运算符>
使用插入符^
进行转义,这是解析 FOR 命令行时Windows命令解释器首先将>
解释为文字字符所必需的。但稍后, FOR 2>nul
执行带有>
的 REG 命令行将被解释为重定向运算符。如果Windows注册表中根本不存在注册表值,则可能会出现错误消息。
FOR 通过使用空格和制表符作为分隔符(默认值)将行拆分为子字符串(标记)来处理 REG 命令的捕获输出的每个非空行。< / p>
选项skip=1
指示 FOR 跳过第一行捕获的输出。
选项tokens=1,2*
指示 FOR 第一个空格/制表符分隔符字符串,此处值名称UserFolder
应分配给第一个循环变量A
。
第二个空格/制表符分隔的字符串在此类型REG_SZ
应分配给循环变量B
作为ASCII table中的下一个字符。现在应该清楚为什么循环变量区分大小写,而环境变量不区分大小写。这个循环变量在这里没有进一步处理,尽管在类型为REG_EXPAND_SZ
而不是REG_SZ
的情况下它可能是好的,因为在这种情况下,目录路径最可能包含一个或多个环境变量引用,它们必须是在拥有真实的目录路径之前扩展。
在示例D:\OneDrive - Business
中第二个空格/制表符分隔的字符串之后的空格/制表符后面的字符串应该被分配,而不会在空格/制表符上进一步拆分以循环变量C
,因为{{1在选项字符串*
中的2
之后。
第一个 IF 条件确保在Windows XP上处理正确的行, REG 的输出以一个标题开始,其中只跳过第一行。< / p>
第二个 IF 条件可确保用户文件夹值具有非空值。
最终将感兴趣的字符串分配给环境变量tokens=1,2*
,并退出 FOR 循环,跳转到标签UserFolder
下方的命令。
如果在Windows注册表中找不到注册表值,则会执行 FOR 循环下面的命令。
要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。
UserFolderSet
echo /?
for /?
goto /?
if /?
另请阅读Microsoft有关Using Command Redirection Operators。
的文章答案 1 :(得分:0)
也许:
For /F "EOL=H Tokens=2*" %%A In ('Reg Query "HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1" /V "UserFolder"') Do Set "var=%%B"
Echo(%%var%% = %var%
Pause
答案 2 :(得分:0)
我不会使用文本文件但直接Reg.exe
来读取注册表值
@Echo off
Set "Key=HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business1"
Set "Val=UserFolder"
For /f "Tokens=2* delims= " %%A in (
'Reg query "%Key%" /V %Val% ^|find /i "%Val%" '
) Do Set "%Val%=%%B"
Set %Val%
答案 3 :(得分:0)
您可以将[MSDN]: reg的输出与[MSDN]: findstr合并(以过滤掉一些无用的数据),并使用[SS64]: for迭代剩下的内容。
以下是代码(必须从批文件中运行):
@echo off
set _KEY_NAME=HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\Accounts\Business1
set _VALUE_NAME=UserFolder
set _VALUE_DATA=
for /f "tokens=1,2,*" %%f in ('reg query %_KEY_NAME% /v %_VALUE_NAME% /t REG_SZ 2^>NUL ^| findstr %_VALUE_NAME%') do (
set _VALUE_DATA="%%h"
)
echo Data: %_VALUE_DATA%
这是基于我的机器上的事实( Win10 ),reg query %_KEY_NAME% /v %_VALUE_NAME% /t REG_SZ
( _KEY_NAME 和 _VALUE_NAME 不同的值),输出:
HKEY_CURRENT_USER\SOFTWARE\_DummyKey _DummyValue REG_SZ D:\OneDrive - Business End of search: 1 match(es) found.
@ EDIT0 :在看了@Mofi的解决方案之后,我意识到我没有错误处理。添加了一些。