在批处理脚本中,如何获取文件的长名称?

问题描述

| 如何获得文件或目录的长路径? 我需要一个临时目录的路径,其中没有ѭ0。
%TEMP%
解析为
C:\\Users\\YKAGAN~1\\AppData\\Local\\Temp
我如何获得
C:\\Users\\ykaganovich\\AppData\\Local\\Temp
?     

解决方法

试试我刚刚写的这个程序。 来源(D):
import core.stdc.wchar_,core.sys.windows.windows;
extern (C) int __wgetmainargs(out int pargc,out wchar** pargv,out wchar** penvp,int dowildcard,out int startinfo);
extern (Windows) BOOL Wow64DisableWow64FsRedirection(out void* OldValue);
extern (Windows) HMODULE LoadLibraryW(in LPCWSTR lpFileName);
extern (Windows) DWORD GetLongPathNameW(in LPCWSTR lpszShortPath,LPWSTR lpszLongPath,in DWORD cchBuffer);
pragma(startaddress,wmainCRTStartup);
pragma(lib,\"msvcrt.lib\");
void* disableWow64Redirection()
{
    auto pKernel32 = LoadLibraryW(\"kernel32.dll\");
    void* old;
    auto fn = cast(typeof(&Wow64DisableWow64FsRedirection))GetProcAddress(cast(HMODULE)pKernel32,\"Wow64DisableWow64FsRedirection\");
    if (fn != null) { if (!fn(old)) { } }
    else { old = null; }
    FreeLibrary(pKernel32);
    return old;
}
int wmainCRTStartup()
{
    disableWow64Redirection();
    int argc,si; wchar** wargv,wenvp;
    __wgetmainargs(argc,wargv,wenvp,si);
    wchar[32 * 1024] buffer = void; //big enough for all valid paths
    foreach (i; 1 .. argc)
    {
        auto len = GetLongPathNameW(wargv[i],buffer.ptr,buffer.length - 1);
        buffer.ptr[len] = \'\\0\';
        if (i > 1) { wprintf(\" \"); }
        wprintf(\"%s\",len > 0 ? buffer.ptr : wargv[i]);
    }
    return 0;
}
用法:
name <short-name>
哎呀,这是C版本:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
typedef BOOL (WINAPI * PWow64DisableWow64FsRedirection)(void** OldValue);
int _tmain(int argc,TCHAR *wargv[])
{
    int i;
    wchar_t buffer[32 * 1024]; //big enough for all valid paths
    PWow64DisableWow64FsRedirection fn =
        (PWow64DisableWow64FsRedirection)GetProcAddress(
        GetModuleHandle(_T(\"kernel32.dll\")),\"Wow64DisableWow64FsRedirection\");
    if (sizeof(size_t) > 4 && fn != NULL) //Remove if WOW64 wanted
    { void* old; Wow64DisableWow64FsRedirection(&old); }
    for (i = 1; i < argc; i++)
    {
        DWORD len = GetLongPathNameW(wargv[i],buffer,ARRAYSIZE(buffer) - 1);
        buffer[len] = _T(\'\\0\');
        if (i > 1) { wprintf(_T(\" \")); }
        wprintf(_T(\"%s\"),len > 0 ? buffer : wargv[i]);
    }
    return 0;
}
    ,编辑:根据乔伊的建议,使用
for /r /d
更新了解决方案: 这是一种非常贪婪的方式,但是它有效:
pushd c:\\

for /r /d %%D in (.) do (
    if /i %%~sD equ %TMP% (
        @echo %%~dpfD
        popd
        exit /b
    )
)
首先是“ 9”,然后是“ 10”。
for /r /d (.)
将遍历目录树。 我们遍历目录列表,将短名称(
%%~sD
)与变量
TMP
中的名称进行比较。如果它们相等,我们将打印出扩展的长名称,还原原始工作目录,然后退出脚本。 需要使用
%%dpfD
而不是
%%D
;出于某些原因,路径名末尾加上了
%%D
。 我最初尝试使用
if %%~sD==%TMP%
,但是没有用。 我在WindowsXP和Windows 7中对此进行了测试,并且两者均可工作。需要一段时间才能运行,但最终完成了工作。