关于命令行参数的问题

时间:2022-06-07 14:30:41
大家以前有没有遇到这样的问题,就是通过命令行参数去传文件名及路径时,有时得到的值是例如:"C:\PROGRA~1\测试~1.txt"这样的简写,实际上它的全路径应是"C:\Program Files\测试程序.txt".VB的Command值同样会出现这样的问题,但在VB中,如果使用Dir(FileName),至少可以得到正确的文件名,比如"测试程序.txt",那么在Delphi中,如果传过来的FileName如上面所举的例子一样,应该怎样解决呢?

18 个解决方案

#1


up

#2


ExtractFileDir(Application.ExeName)

#3


可以直接用的吧

#4


free007的方法不行,得出的结果是"C:\PROGRA~1",包括ExtractFilePath和ExtractFileName 都不能得出正常的显示。 jinjiajun说可以直接用,是没有错,可是,因为我要最终在窗体上显示出这个路径和文件名出来,这样的显示让人没有办法接受,所以才希望知道Delphi究竟怎样才可得出正常的显示出来。

#5


沒人解答嗎?up!

#6


這個問題真的很要命!再up!

#7


showMessage(extractFilePath(Application.ExeName));

我刚试过,没有啊!可以直接取出来的!不知道你什么意思!没有出现你的那种情况啊!

#8


我的办法不行?我们都用了好几个项目了,,不明白你的意思

#9


Application.ExeName的值本身很完整,不会有像乱码一样的路径,所以你用extractFilePath去取就OK,而通过命令行参数传过来的路径却不会是这样,它有可能出现像我提到过的不规范的路径名,其实它的路径无错,只是你要在窗体上显示出来却需要正确的解析。Delphi中的extractFilePath或extractFileName函数都没有这个功能,它只能直接取出文件名或路径,不会纠正不规范的地方。但在VB中的Dir函数就不同,比如,命令行参数传来的路径为"C:\Progra~1\你~1.txt",使用Dir函数: 

***************** 
FilePath=Command '接受命令行参数 
Filename=dir(FilePath) 
msgbox FileName 
*********************

OK,显示"你好.txt"
可惜Delphi的extractFileName函数不具备此功能,它会显示"你~1.txt"
所以,我想知道在Delphi中怎样才能正确的解析出规范的路径或文件名

#10


有的DOS操作系统不支持长文件名,比如MYDocument文件夹会成为Mydocu~1,相信大家都有这样的经验. 当一个文件放在MyDocument目录下时,这种文件的类型是用你的EXE打开,那么首先你的Exe会接受操作系统给你的命令行参数,这样程序才可知道用户点击的是哪一个文件,可是命令行参数有可能是"C:\Mydocu~1\*.XXX",真是让你吐血,因为如果你把这个路径名显示在窗体上,用户就会认为这是乱码,实际上程序没有错,操作系统这样传来命令行参数,有什么办法?所以,我想知道,如果碰到这样的路径,该用什么方法正确的解析.

#11


大家可以试著建某一种文件类型的Shell关联,再在测试程序中读取命令行参数,很容易就会发现我这个问题。真是头疼啊!郁闷!

#12


uses ShellAPI;

function ExtractLongPathName(mFileName: TFileName): TFileName;
var
  vSHFileInfo: TSHFileInfo;
begin
  Result := '';
  mFileName := ExcludeTrailingPathDelimiter(mFileName);
  if not FileExists(mFileName) and not DirectoryExists(mFileName) then Exit;

  FillChar(vSHFileInfo, SizeOf(vSHFileInfo), 0);
  while SHGetFileInfo(PChar(mFileName), 0, vSHFileInfo, SizeOf(vSHFileInfo),
    SHGFI_DISPLAYNAME) <> 0 do begin
    Result := string(vSHFileInfo.szDisplayName) + '\' + Result;
    mFileName := ExtractFilePath(ExcludeTrailingPathDelimiter(mFileName));
    if mFileName = '' then begin
      Result := '';
      Break;
    end;
    if mFileName = ExtractFileDrive(mFileName) + '\' then begin
      Result := ExcludeTrailingPathDelimiter(mFileName + Result);
      Break;
    end;
  end;
end; { ExtractLongPathName }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := ExtractLongPathName(ExtractShortPathName('C:\Program Files\Borland\Delphi6\Bin\delphi32.exe'));
end;

#13


zswangII的函数可行,谢谢。 
不过函数比较复杂,不知有没有更简洁的函数.中午12:00结贴.

#14


测试~1.txt


这个问题与你的系统环境有关,

应该不是DELPHI的问题,系统如此,取出来当然如此

#15


也觉得我的函数实现起来别扭~~
目前还没找到更好的方法来实现~~
并且还存在一个bug,当用户隐藏已知的文件扩展名时,这里也将隐藏~~

//矫正如下~~
function ExtractLongPathName(mFileName: TFileName): TFileName;
var
  vSHFileInfo: TSHFileInfo;
  vFileExt: string;
begin
  Result := '';
  mFileName := ExcludeTrailingPathDelimiter(mFileName);
  if not FileExists(mFileName) and not DirectoryExists(mFileName) then Exit;
  vFileExt := ExtractFileExt(mFileName);

  FillChar(vSHFileInfo, SizeOf(vSHFileInfo), 0);
  while SHGetFileInfo(PChar(mFileName), 0, vSHFileInfo, SizeOf(vSHFileInfo),
    SHGFI_DISPLAYNAME) <> 0 do begin
    Result := string(vSHFileInfo.szDisplayName) + '\' + Result;
    mFileName := ExtractFilePath(ExcludeTrailingPathDelimiter(mFileName));
    if mFileName = '' then begin
      Result := '';
      Break;
    end;
    if mFileName = ExtractFileDrive(mFileName) + '\' then begin
      Result := ExcludeTrailingPathDelimiter(mFileName + Result);
      if ExtractFileExt(Result) <> vFileExt then
        Result := ChangeFileExt(Result, vFileExt);
      Break;
    end;
  end;
end; { ExtractLongPathName }

//继续寻找更好的解决方法~~

#16


这是window的命名规则。

#17


非常感谢 zswangII的一再回答。
To cow8063: 
   确实不是Delphi的问题,我说过命令行参数是这样传的,这和操作系统有关系。只是我们不能这样和用户解释,我们必须纠正为规范的命名和路徑。

#18


結貼了,再次謝謝zswangII!

#1


up

#2


ExtractFileDir(Application.ExeName)

#3


可以直接用的吧

#4


free007的方法不行,得出的结果是"C:\PROGRA~1",包括ExtractFilePath和ExtractFileName 都不能得出正常的显示。 jinjiajun说可以直接用,是没有错,可是,因为我要最终在窗体上显示出这个路径和文件名出来,这样的显示让人没有办法接受,所以才希望知道Delphi究竟怎样才可得出正常的显示出来。

#5


沒人解答嗎?up!

#6


這個問題真的很要命!再up!

#7


showMessage(extractFilePath(Application.ExeName));

我刚试过,没有啊!可以直接取出来的!不知道你什么意思!没有出现你的那种情况啊!

#8


我的办法不行?我们都用了好几个项目了,,不明白你的意思

#9


Application.ExeName的值本身很完整,不会有像乱码一样的路径,所以你用extractFilePath去取就OK,而通过命令行参数传过来的路径却不会是这样,它有可能出现像我提到过的不规范的路径名,其实它的路径无错,只是你要在窗体上显示出来却需要正确的解析。Delphi中的extractFilePath或extractFileName函数都没有这个功能,它只能直接取出文件名或路径,不会纠正不规范的地方。但在VB中的Dir函数就不同,比如,命令行参数传来的路径为"C:\Progra~1\你~1.txt",使用Dir函数: 

***************** 
FilePath=Command '接受命令行参数 
Filename=dir(FilePath) 
msgbox FileName 
*********************

OK,显示"你好.txt"
可惜Delphi的extractFileName函数不具备此功能,它会显示"你~1.txt"
所以,我想知道在Delphi中怎样才能正确的解析出规范的路径或文件名

#10


有的DOS操作系统不支持长文件名,比如MYDocument文件夹会成为Mydocu~1,相信大家都有这样的经验. 当一个文件放在MyDocument目录下时,这种文件的类型是用你的EXE打开,那么首先你的Exe会接受操作系统给你的命令行参数,这样程序才可知道用户点击的是哪一个文件,可是命令行参数有可能是"C:\Mydocu~1\*.XXX",真是让你吐血,因为如果你把这个路径名显示在窗体上,用户就会认为这是乱码,实际上程序没有错,操作系统这样传来命令行参数,有什么办法?所以,我想知道,如果碰到这样的路径,该用什么方法正确的解析.

#11


大家可以试著建某一种文件类型的Shell关联,再在测试程序中读取命令行参数,很容易就会发现我这个问题。真是头疼啊!郁闷!

#12


uses ShellAPI;

function ExtractLongPathName(mFileName: TFileName): TFileName;
var
  vSHFileInfo: TSHFileInfo;
begin
  Result := '';
  mFileName := ExcludeTrailingPathDelimiter(mFileName);
  if not FileExists(mFileName) and not DirectoryExists(mFileName) then Exit;

  FillChar(vSHFileInfo, SizeOf(vSHFileInfo), 0);
  while SHGetFileInfo(PChar(mFileName), 0, vSHFileInfo, SizeOf(vSHFileInfo),
    SHGFI_DISPLAYNAME) <> 0 do begin
    Result := string(vSHFileInfo.szDisplayName) + '\' + Result;
    mFileName := ExtractFilePath(ExcludeTrailingPathDelimiter(mFileName));
    if mFileName = '' then begin
      Result := '';
      Break;
    end;
    if mFileName = ExtractFileDrive(mFileName) + '\' then begin
      Result := ExcludeTrailingPathDelimiter(mFileName + Result);
      Break;
    end;
  end;
end; { ExtractLongPathName }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := ExtractLongPathName(ExtractShortPathName('C:\Program Files\Borland\Delphi6\Bin\delphi32.exe'));
end;

#13


zswangII的函数可行,谢谢。 
不过函数比较复杂,不知有没有更简洁的函数.中午12:00结贴.

#14


测试~1.txt


这个问题与你的系统环境有关,

应该不是DELPHI的问题,系统如此,取出来当然如此

#15


也觉得我的函数实现起来别扭~~
目前还没找到更好的方法来实现~~
并且还存在一个bug,当用户隐藏已知的文件扩展名时,这里也将隐藏~~

//矫正如下~~
function ExtractLongPathName(mFileName: TFileName): TFileName;
var
  vSHFileInfo: TSHFileInfo;
  vFileExt: string;
begin
  Result := '';
  mFileName := ExcludeTrailingPathDelimiter(mFileName);
  if not FileExists(mFileName) and not DirectoryExists(mFileName) then Exit;
  vFileExt := ExtractFileExt(mFileName);

  FillChar(vSHFileInfo, SizeOf(vSHFileInfo), 0);
  while SHGetFileInfo(PChar(mFileName), 0, vSHFileInfo, SizeOf(vSHFileInfo),
    SHGFI_DISPLAYNAME) <> 0 do begin
    Result := string(vSHFileInfo.szDisplayName) + '\' + Result;
    mFileName := ExtractFilePath(ExcludeTrailingPathDelimiter(mFileName));
    if mFileName = '' then begin
      Result := '';
      Break;
    end;
    if mFileName = ExtractFileDrive(mFileName) + '\' then begin
      Result := ExcludeTrailingPathDelimiter(mFileName + Result);
      if ExtractFileExt(Result) <> vFileExt then
        Result := ChangeFileExt(Result, vFileExt);
      Break;
    end;
  end;
end; { ExtractLongPathName }

//继续寻找更好的解决方法~~

#16


这是window的命名规则。

#17


非常感谢 zswangII的一再回答。
To cow8063: 
   确实不是Delphi的问题,我说过命令行参数是这样传的,这和操作系统有关系。只是我们不能这样和用户解释,我们必须纠正为规范的命名和路徑。

#18


結貼了,再次謝謝zswangII!