2009-05-09 15 views
4

GetShortPathName()が動作していないようにパスの入力文字列を返している:送られたとおりにGetShortPathName、予期しない結果

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 

:MUCH読み取り後の溶液

/実験は、これを行うための唯一確実な方法は、オートメーションを使用しているようです。 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 

をご提案ありがとうございました。


私はまだ8.3のパス/ファイル名を確実に作成する方法を見つけようとしています。

GETSHORTPATHNAMEを使用する以外にこれを行う方法はありますか?

解決済み。上記を参照してください

これは、MSがこれをCOM deciplesでのみサポートしているようです...なぜ、今はC APIで信頼性が低いのか不思議です。

+0

あなたはあなたを悩ましているコードを逐語的に投稿できますか? – dirkgently

+0

DWORD WINAPI GetShortPathName( __in LPCTSTR lpszLongPath、 __out LPTSTR lpszShortPath、 __in DWORD cchBuffer ); しかし、言及されたようにここでの呼び出しは問題ではありません... –

+0

関数宣言はそれほど役に立ちません。問題を再現する簡単な例を提供できる場合は、役立つかもしれません。 – dirkgently

答えて

9

ファイル名に既存の短縮名がなく、XP SP3がファイルの短縮名を自動的に作成していないためです。

このレジストリ設定(存在する場合)をチェックすると、現在設定されているレジストリ設定を確認できます。

ます。HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \コントロール\ FileSystemの\ NtfsDisable8dot3NameCreationの

NtfsDisable8dot3NameCreationのが1に設定されている場合、あなたは、次の動作を取得します:フォルダ/ファイルが既に短い名前を持っている場合は、「例えば、

をProgram Files "を選択すると、そのフォルダ/ファイルの短い名前が返されます。しかし、短い名前が存在しない場合は、そのオブジェクトに存在する唯一の名前であるため、ファイルの長い名前を取得します。短い名前が無効になっている場合、取得する短い名前はありません。

+0

はい、それは1に設定されていますが、この設定では、すべてのNTFSファイル名をディスク上および8.3として作成することができます(これは明らかに望ましくありません)。 「ファイルの短い名前を作成する」と言うと、HDで新しい8.3ファイル名を作成するか、GetShortPathName()の呼び出しで返されるファイル名を作成するだけですか? このフラグがこれを制御している場合、なぜ1に設定された場合、いくつかのパスで8.3を返しますか? –

+0

私は私の答えにいくつかの情報を追加しました。短い名前の作成が無効な場合、GetShortPathName()は短い名前を作成しないため、すでに存在する場合は短い名前しか取得できません。 – Steven

+0

ああ。ありがとうございました。そして、この設定の範囲を明確にするために、ハードドライブ上に作成するすべてのファイルを、それ以降の短い名前で見つけるつもりはありませんか? –

2

前述のドキュメントによれば、NtfsDisable8dot3NameCreationが0の場合にのみ短い名前が生成されます。値が変更された場合、長い名前のファイル/ディレクトリがいくつかある可能性があります。これは、GetShortPathNameを呼び出すと、ディレクトリの名前とファイルの長い名前を短縮できる理由を説明します。

私はこれを確認することができませんでしたが、Windowsで特別なロジックがあると思われます。これは、 "Documents and Settings"などの重要なディレクトリに対して短い名前を作成するものです。

+2

8.3の名前生成を無効にする前に、「ドキュメントと設定」がインストール中に作成される可能性があります。それは特別な魔法を必要としません。 – MSalters

2

SetFileShortNameを試しましたか?

+0

ありがとうございます。いいアイデア... http://msdn.microsoft.com/en-us/library/tes8ehwe(VS.85).aspx(おそらくpInvokeを使っているCOMオブジェクト) - 設定するShortNameがあると仮定します。確実にXPでショートネームを作るには? –

+0

http://en.wikipedia.org/wiki/8.3_filenameでは、短いファイル名の表記規則について説明しています。 SetFileShortNameの戻りコードをチェックするループでこれを実装し、失敗した場合は最後にカウントを増やしてからやり直してください。 – jdigital