我已将“.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()函数来考虑其中包含空格的目录,或者是否有一个更好的函数,我应该使用它与目录一起使用中包含空格。
答案 0 :(得分:15)
这不是必然的错误......只是资源管理器将短文件名传递给您的程序 - 而不是长文件名 - 。请参阅short vs. long names。
您可以使用这两个名称打开文件,或者如果您只关心使用长文件名,则可以在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都可以使用
答案 1 :(得分:7)
您的关联设置错误。而不是双击.file_5做
C:\YourPath\YourApp.exe %1
关联应设置为
"C:\YourPathYourApp.exe" "%1"
注意%1周围的双引号 - 这样可以保留所有空格而不是它们导致Windows传递短路径和文件名。
答案 2 :(得分:-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;