1

「.file_5」拡張子をアプリケーションに関連付け、Delphi で ParamStr(1) 関数を使用して、以下のコードを使用してエクスプローラーでファイルをダブルクリックしたときに、ファイルのパスとファイル名を含むメッセージ ボックスを表示しました。

procedure TForm1.FormCreate(Sender: TObject);
 var
  TheFile : string;
begin
  TheFile := ParamStr(1);  //filename for the file that was loaded
  ShowMessage(TheFile);
end;

これは機能しますが、ファイルを元の場所とは別の場所に移動すると、表示されるメッセージが正しくありません。

例: (test.file_5 を使用)

ファイルの元の場所は C:\ ドライブで、ダブルクリックするとアプリケーションが起動し、次のようなメッセージ ボックスが表示されます。

C:\test.file_5

正解です。たとえば、同じファイルをプログラム ファイル フォルダーなどのスペースを含むディレクトリに移動すると、表示される Messagbox は表示されません。

C:\Program Files\test.file_5

私が期待するように、むしろ

C:\PROGRA~1.FILE_

これは明らかに私が求めている情報ではないので、私の質問は、ParamStr() 関数を使用して、スペースを含むディレクトリを考慮する方法、またはスペースを含むディレクトリで動作するより良い関数を使用することです。彼ら。

4

3 に答える 3

15

これは必ずしも間違っているわけではありません...エクスプローラーが長いファイル名ではなく短いファイル名をプログラムに渡しているだけです。短い名前と長い名前を参照してください。

両方の名前を使用してファイルを開くか、長いファイル名のみを使用することに関心がある場合は、ShowMessage (または実際にファイルを操作する) の前に短いファイル名から長いファイル名に変換できます。Windows.pas で定義されているGetLongPathName API呼び出しを使用します。

function ShortToLongFileName(const ShortName: string): string;
var
  outs: array[0..MAX_PATH] of char;
begin
  GetLongPathName(PChar(ShortName), OutS, MAX_PATH);
  Result := OutS;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  TheFile : string;
begin
  TheFile := ParamStr(1);  //filename for the file that was loaded
  TheFile := ShortToLongFileName(TheFile);
  ShowMessage(TheFile);
end;

Windows Vista でテストしたところ、GetLongPathName は、短いファイル名または既に長いファイル名を指定しても機能します (ファイルが存在する場合は明らかに)。

于 2010-11-03T06:32:51.810 に答える
7

関連付けの設定が間違っています。.file_5 を double_clicking する代わりに

C:\YourPath\YourApp.exe %1

関連付けは次のように設定する必要があります。

"C:\YourPathYourApp.exe" "%1"

%1 を二重引用符で囲んでいることに注意してください。これにより、Windows が短いパスとファイル名を渡す代わりに、含まれているスペースが保持されます。

于 2010-11-03T13:17:03.080 に答える
-1

この関数を使用して自分で解決しました。


Function GetLongPathAndFilename(Const S : String) : String;

Var srSRec : TSearchRec; iP,iRes : Integer; sTemp,sRest : String; Bo : Boolean;

Begin Result := S + ' [directory not found]'; // Check if file exists Bo := FileExists(S); // Check if directory exists iRes := FindFirst(S + '*.*',faAnyFile,srSRec); // If both not found then exit If ((not Bo) and (iRes <> 0)) then Exit; sRest := S; iP := Pos('\',sRest); If iP > 0 then Begin sTemp := Copy(sRest,1,iP - 1); // Drive sRest := Copy(sRest,iP + 1,255); // Path and filename End else Exit; // Get long path name While Pos('\',sRest) > 0 do begin iP := Pos('\',sRest); If iP > 0 then Begin iRes := FindFirst(sTemp + '\' + Copy(sRest,1,iP - 1),faAnyFile,srSRec); sRest := Copy(sRest,iP + 1,255); If iRes = 0 then sTemp := sTemp + '\' + srSRec.FindData.cFileName; End; End; // Get long filename If FindFirst(sTemp + '\' + sRest,faAnyFile,srSRec) = 0 then Result := sTemp + '\' + srSRec.FindData.cFilename; SysUtils.FindClose(srSRec); End;

于 2010-11-03T06:24:58.370 に答える