Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 使用cmd.exe将长文件名转换为短文件名(8.3)_Windows_Batch File_Command Line_Long Filenames_Short Filenames - Fatal编程技术网

Windows 使用cmd.exe将长文件名转换为短文件名(8.3)

Windows 使用cmd.exe将长文件名转换为短文件名(8.3),windows,batch-file,command-line,long-filenames,short-filenames,Windows,Batch File,Command Line,Long Filenames,Short Filenames,我正在尝试在Windows上将长文件名转换为短文件名(8.3) 带有命令行参数的批处理文件按预期工作: short.bat: 调用short.bat C:\Documents and Settings\User\NTUSER.DAT返回C:\DOCUM~1\User\NTUSER.DAT 但是,我不喜欢为此使用额外的.bat文件。我宁愿使用ruby脚本中的整个命令调用cmd.exe。 我该怎么做 作为中间步骤,我尝试对批处理文件中的路径进行硬编码,但不起作用: short1.bat: echo%

我正在尝试在Windows上将长文件名转换为短文件名(8.3)

带有命令行参数的批处理文件按预期工作:

short.bat:

调用
short.bat C:\Documents and Settings\User\NTUSER.DAT
返回
C:\DOCUM~1\User\NTUSER.DAT

但是,我不喜欢为此使用额外的.bat文件。我宁愿使用ruby脚本中的整个命令调用
cmd.exe
。 我该怎么做

作为中间步骤,我尝试对批处理文件中的路径进行硬编码,但不起作用:

short1.bat:

echo%filename%
有效,但
echo%~sfilename%
给出以下错误:

The following usage of the path operator in batch-parameter
substitution is invalid: %~sfilename%

For valid formats type CALL /? or FOR /?
如果short1.bat有效,我如何将其转换为一个可以用
cmd.exe\c…
调用的一行程序


但是,还有另一个问题(),具体是询问当前目录的路径。

将filename.txt替换为要转换为8.3的文件名

dir /x filename.txt
然后,必须将结果拆分为空格作为分隔符(\s在正则表达式中)。
那么带~的值就是您的短文件名。如果文件名开头很短,则找不到包含~~的字符串。

以下是在注册表中读取“appdata\local”文件夹位置并将其转换为短路径的示例:

cmd /c for %A in ("C:\Documents and Settings\User\NTUSER.DAT") do @echo %~sA
cls
@echo off
cd /d "%~dp0"
chcp 65001 >nul

for /f "skip=1" %%a in ('"wmic useraccount where name='%USERNAME%' get sid"') do (
    for %%b in (%%a) do set current_SID=%%b
)
set current_username=%USERNAME%
set current_userprofile=%USERPROFILE%

set key_to_read=HKEY_USERS\%current_SID%\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
set value_to_read=Local AppData
rem If value_to_read contains ? space(s) set tokens to 2+?
for /f "usebackq eol= tokens=3,* delims= " %%a in (`reg query "%key_to_read%" /v "%value_to_read%" 2^>nul ^| find "%value_to_read%"`) do (
    set value_type=%%a
    set data_read=%%b
)
set data_read=%data_read:USERPROFILE=current_userprofile%
call set "data_read=%data_read%"
set current_local_appdata=%data_read%

set current_local_appdata_temp=%current_local_appdata%\Temp
echo %current_local_appdata_temp%

for %%a in ("%current_local_appdata_temp%") do set "current_local_appdata_temp_short=%%~sa"
echo %current_local_appdata_temp_short%

pause
exit

我手头没有现成的Windows,但请尝试
%filename:~s%
(与子字符串表示法类似,
%filename:~0,1%
)。如果这行得通,我会回答的。@ChrisMorgan-绝对不行。不行。@dbenham:不行?好吧。值得一试。你为什么还需要这个短名字?这是传统的功能,除非绝对必要,否则最好避免使用。@dbenham-长文件名必须用引号括起来,这可能很难传递到诸如psexec之类的常见例程中-这是一种效率很低的方法。我认为,调用批处理脚本将大大提高效率。这在本地驱动器上可以正常工作,但在映射的网络驱动器上则不行。有什么想法吗?@user1251007-你使用的是什么版本的Windows?有一个已知的XP错误处理8.3名称和~s修饰符:@user1251007-此外,管理员可以为给定驱动器禁用生成8.3文件名。你能确认DIR/X在你的网络驱动器上提供了短文件名吗?@user1251007-我敢肯定你被卡住了,除非你能让你的管理员在你的网络驱动器上启用短文件名。但是短名称被禁用可能是有原因的。@AKhudairy-这个问题是关于使用
cmd/c
的命令行解决方案的。在批处理文件中,您必须将所有百分比增加一倍-您所需要的是%%a in(“此处的某个路径\some file.ext”)的
,请执行echo%%~sA
,不幸的是,您的答案没有回答问题。因此,将来可能会将其删除。然而,它可能对其他人有用。我建议你问一个新问题(即使你知道答案),然后自己直接回答这个问题。
cmd /c for %A in ("C:\Documents and Settings\User\NTUSER.DAT") do @echo %~sA
cls
@echo off
cd /d "%~dp0"
chcp 65001 >nul

for /f "skip=1" %%a in ('"wmic useraccount where name='%USERNAME%' get sid"') do (
    for %%b in (%%a) do set current_SID=%%b
)
set current_username=%USERNAME%
set current_userprofile=%USERPROFILE%

set key_to_read=HKEY_USERS\%current_SID%\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
set value_to_read=Local AppData
rem If value_to_read contains ? space(s) set tokens to 2+?
for /f "usebackq eol= tokens=3,* delims= " %%a in (`reg query "%key_to_read%" /v "%value_to_read%" 2^>nul ^| find "%value_to_read%"`) do (
    set value_type=%%a
    set data_read=%%b
)
set data_read=%data_read:USERPROFILE=current_userprofile%
call set "data_read=%data_read%"
set current_local_appdata=%data_read%

set current_local_appdata_temp=%current_local_appdata%\Temp
echo %current_local_appdata_temp%

for %%a in ("%current_local_appdata_temp%") do set "current_local_appdata_temp_short=%%~sa"
echo %current_local_appdata_temp_short%

pause
exit