Почему ParamStr показывает неправильное имя файла? - PullRequest
1 голос
/ 03 ноября 2010

Я связал расширение ".file_5" с моим приложением, и я использовал функцию ParamStr (1) в Delphi, чтобы показать окно сообщения, содержащее путь и имя файла, когда я дважды щелкаю по нему в проводнике, используякод ниже.

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 () для учета каталогов, в которых есть пробелы, или есть лучшая функция, которую я должен использовать, которая работает с каталогами, в которых есть пробелы.

Ответы [ 3 ]

15 голосов
/ 03 ноября 2010

Это не обязательно неправильно ... просто исследователь передает короткое имя файла вашей программе вместо длинного имени файла.См. короткие и длинные имена .

. Вы можете открыть файл, используя оба имени, или вы можете конвертировать из короткого в длинное имя файла перед ShowMessage (или фактически манипулировать файлом), если вы 'Вы заботитесь о работе только с длинными именами файлов.Используйте GetLongPathName API вызов, определенный в Windows.pas.

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 работает, если вы предоставляете короткое или уже длинное имя файла (еслифайл существует, очевидно)

7 голосов
/ 03 ноября 2010

Ваша ассоциация настроена неправильно.Вместо двойного щелчка .file_5, выполняющего

C:\YourPath\YourApp.exe %1

Ассоциация должна быть настроена как

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

Обратите внимание на двойные кавычки вокруг% 1 - при этом все пробелы вместо имеющихсяв результате чего Windows передает короткий путь и имя файла.

0 голосов
/ 03 ноября 2010

Решил сам, используя эту функцию.

<code>
Function GetLongPathAndFilename(Const S : String) : String;</p>

<p>Var
   srSRec             : TSearchRec;
   iP,iRes            : Integer;
   sTemp,sRest        : String;
   Bo                 : Boolean;</p>

<p>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; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...