GetShortPathName непредсказуемые результаты - PullRequest
4 голосов
/ 09 мая 2009

GetShortPathName () не работает, как я ожидаю, на XP SP3

http://msdn.microsoft.com/en-us/library/aa364989(VS.85).aspx

возвращает входную строку для таких путей, как:

C:\Test\LongFolderNameToTestWith\BinarySearch.ini

точно как отправлено?

Пока:

C:\Documents and Settings\LocalService\NTUSER.DAT

Делает короткие имена для пути, поэтому я знаю, что правильно вызываю API.

Однако:

C:\Documents and Settings\LocalService\BinarySearch.ini

Не делает короткое имя из имени файла, но делает короткие имена для пути!?

Может ли кто-нибудь помочь мне понять это поведение и, возможно, предложить обходной путь.

Добавлено:

Мне нужно создать путь / имя файла 8.3 для передачи в устаревшее приложение

Как это можно сделать?

Добавлено: РЕШЕНИЕ

После многого чтения / эксперимента кажется, что единственный надежный способ сделать это - использовать автоматизацию:

' ------------------------------------------------------------
' 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

Это работает.

Простая реализация в бейсике будет:

$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

Спасибо всем за ваши предложения.


Я все еще пытаюсь найти способ надежного создания пути / имени файла 8.3.

Есть ли способ сделать это, кроме использования GETSHORTPATHNAME?

решаемая. См. Выше

Кажется, что MS продолжает поддерживать это только для дешифровок COM ... почему это ненадежно в C API остается загадкой.

Ответы [ 3 ]

9 голосов
/ 09 мая 2009

Это потому, что имя файла не имеет существующего короткого имени и XP SP3 не создает автоматически короткое имя для файла.

Вы можете проверить этот параметр реестра (если он существует), чтобы увидеть, что он в данный момент установлен.

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ FileSystem \ NtfsDisable8dot3NameCreation

Когда NtfsDisable8dot3NameCreation установлен в 1, вы получите следующее поведение:

Если папка / файл уже имеет короткое имя, например, «Program Files», то он вернет короткое имя для этой папки / файла. Но если короткое имя не существует, вы получите длинное имя для файла, так как это единственное имя, которое существует для этого объекта. Если короткие имена отключены, коротких имен нет.

2 голосов
/ 16 июня 2009

Вы пробовали SetFileShortName ?

2 голосов
/ 10 мая 2009

В соответствии с цитированной ранее документацией короткие имена будут создаваться только в том случае, если NtfsDisable8dot3NameCreation равно 0. Если значение было изменено, у вас могут быть некоторые файлы / каталоги только с длинными именами. Это объясняет, почему ваш вызов GetShortPathName может содержать короткие имена для каталога и длинные имена для файла.

Я не смог подтвердить это, но я подозреваю, что в Windows может быть особая логика, которая всегда создает короткие имена для критических каталогов, таких как «Документы и настройки», потому что некоторые древние программы могут сломаться, если этого не сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...