windows GetShortPathName 不可预知的结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/843843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
GetShortPathName unpredictable results
提问by Mike Trader
GetShortPathName() is not working as I expect on XP SP3
GetShortPathName() 在 XP SP3 上无法正常工作
http://msdn.microsoft.com/en-us/library/aa364989(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa364989(VS.85).aspx
Is returning the input string for paths like:
正在返回路径的输入字符串,例如:
C:\Test\LongFolderNameToTestWith\BinarySearch.ini
exactly as sent?
完全按照发送?
Yet:
然而:
C:\Documents and Settings\LocalService\NTUSER.DAT
Does make short names for the path, so I know I am calling the API correctly.
确实为路径命名了短名称,所以我知道我正确地调用了 API。
However:
然而:
C:\Documents and Settings\LocalService\BinarySearch.ini
Does not make a short name out of the filename, but does make short names for the path!?
不会从文件名中创建短名称,但会为路径创建短名称!?
Could someone help me understand this behavior and perhaps suggest a workaround.
有人可以帮助我理解这种行为,并可能提出解决方法。
Added:
添加:
I need to be able to make an 8.3 Path/filename to pass to a legacy app
我需要能够制作 8.3 路径/文件名以传递给旧版应用程序
How can this be done?
如何才能做到这一点?
Added: SOLUTION
补充:解决方案
After MUCH reading/experimenting, it seems that the only reliable way to do this is using automation:
经过大量阅读/实验后,似乎唯一可靠的方法是使用自动化:
' ------------------------------------------------------------
' Library Name: Microsoft Scripting Runtime 1.0
' Library File: C:\WINDOWS\system32\scrrun.dll
' ------------------------------------------------------------
' Version Info:
' -------------
' Company Name: Microsoft Corporation
' File Description: Microsoft (R) Script Runtime
' File Version: 5.7.0.16599
' Internal Name: scrrun.dll
' Legal Copyright: Copyright (C) Microsoft Corp. 1996-2006, All Rights Reserved
' Original Filename: scrrun.dll
' Product Name: Microsoft (R) Script Runtime
' Product Version: 5.7.0.16599
' ------------------------------------------------------------
' ProgID: Scripting.FileSystemObject
' Interface Name: ScriptingFileSystemObject
'
' Interface Prefix: Scripting
This works.
这有效。
A simple implementation in BASIC would be:
BASIC 中的一个简单实现是:
$PROGID_ScriptingFileSystemObject = "Scripting.FileSystemObject"
Interface Dispatch ScriptingFileSystemObject
Member CALL GetFile <&H0000271C>(IN FilePath AS STRING<&H00000000>) AS ScriptingIFile
Member CALL GetFolder<&H0000271D>(IN FolderPath AS STRING<&H00000000>) AS ScriptingIFolder
END Interface
Interface Dispatch ScriptingFile
Member GET ShortPath<&H000003EA>() AS STRING
Member GET ShortName<&H000003E9>() AS STRING
END Interface
Interface Dispatch ScriptingFolder
Member GET ShortPath<&H000003EA>() AS STRING
Member GET ShortName<&H000003E9>() AS STRING
END Interface
'-----------------------------------------------------------------------------
FUNCTION FileShortPath( BYVAL sPathnFile AS STRING, sShort AS STRING ) AS LONG
LOCAL vResult, vFilePath AS Variant
LOCAL fso AS ScriptingFileSystemObject
LOCAL oFile AS ScriptingFile
IF LEN(sPathnFile) = 0 THEN EXIT FUNCTION ' Nothing sent
SET fso = NEW ScriptingFileSystemObject IN $PROGID_ScriptingFileSystemObject
IF IsNothing(fso) THEN FUNCTION = -1 : EXIT FUNCTION
SET oFile = NEW ScriptingFile IN $PROGID_ScriptingFileSystemObject
IF IsNothing(oFile) THEN FUNCTION = -2 : EXIT FUNCTION
vFilePath = sPathnFile
vResult = Empty
OBJECT CALL fso.GetFile(vFilePath) TO vResult
SET oFile = vResult
IF IsNothing(oFile) THEN FUNCTION = -3 : EXIT FUNCTION
vResult = Empty
Object GET oFile.ShortName TO vResult
sShort = VARIANT$(vResult)
vResult = Empty
Object GET oFile.ShortPath TO vResult
sShort = VARIANT$(vResult)
IF LEN(sShort) THEN FUNCTION = 1 ' Success
END FUNCTION
Thank you all for your suggestions.
谢谢大家的建议。
I am still trying to find a way to reliably make an 8.3 Path/filename.
我仍在尝试找到一种可靠地制作 8.3 路径/文件名的方法。
Is there any way to do this apart from using GETSHORTPATHNAME?
除了使用GETSHORTPATHNAME 之外,还有什么方法可以做到这一点吗?
Solved. See above
解决了。看上面
It seems that MS has continued support for this for COM deciples only... why it is now unreliable in the C API remains a mystery.
似乎 MS 仅继续支持 COM deciples ......为什么它现在在 C API 中不可靠仍然是个谜。
回答by Steven
It is because the file name does not have an existing short name and XP SP3 is not automatically creating a short name for the file.
这是因为文件名没有现有的短名称,而且 XP SP3 不会自动为文件创建短名称。
You can check this registry setting (if it exists) to see what it is currently set to.
您可以检查此注册表设置(如果存在)以查看它当前的设置。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation
When NtfsDisable8dot3NameCreation is set to 1 you will get the following behaviour:
当 NtfsDisable8dot3NameCreation 设置为 1 时,您将获得以下行为:
If a folder/file already has a short name, for example "Program Files", then it will return the short name for that folder/file. But if a short name doesn't exist, you will instead get the long name for the file as it is the only name that exists for that object. If short names are disabled then there is no short name to get.
如果文件夹/文件已有短名称,例如“Program Files”,则它将返回该文件夹/文件的短名称。但是,如果短名称不存在,您将获得文件的长名称,因为它是该对象唯一存在的名称。如果禁用短名称,则无法获取短名称。
回答by jdigital
According to the documentation cited earlier, short names will be generated only if the NtfsDisable8dot3NameCreation is 0. If the value was changed, you may have some files/directories with only long names. This would explain why your call to GetShortPathName can short names for the directory and long names for the file.
根据前面引用的文档,仅当 NtfsDisable8dot3NameCreation 为 0 时才会生成短名称。如果更改了值,您可能会有一些只有长名称的文件/目录。这将解释为什么您对 GetShortPathName 的调用可以为目录短名称和长名称。
I haven't been able to confirm this but I suspect there may be special logic in Windows that always creates short names for critical directories such as "Documents and Settings" because some ancient programs might break if this were not done.
我无法确认这一点,但我怀疑 Windows 中可能存在特殊逻辑,总是为关键目录(例如“文档和设置”)创建短名称,因为如果不这样做,一些古老的程序可能会中断。
回答by jdigital
Have you tried SetFileShortName?
你试过SetFileShortName吗?