delphi获取文件夹路径

时间:2012-01-03 13:09:05

标签: delphi delphi-7 directory

我正在使用Delphi 7,我想找出 .. /所有用户/文档目录的路径。
我遇到了以下代码

uses shlobj, ...

function GetMyDocuments: string;
 var
  r: Bool;
  path: array[0..Max_Path] of Char;
 begin
  r := ShGetSpecialFolderPath(0, path, CSIDL_Personal, False) ;
  if not r then 
    raise Exception.Create('Could not find MyDocuments folder location.') ;
  Result := Path;
 end;

它工作正常,但它不支持返回所需路径的CSIDL_COMMON_DOCUMENTS

此外,根据MS CSIDL不应再使用KNOWNFOLDERID 我确实需要在多个操作系统(仅限Windows)上运行此应用程序。

我该怎么做?
感谢帮助:)

4 个答案:

答案 0 :(得分:5)

在我看来,调用SHGetSpecialFolderPath传递CSIDL_COMMON_DOCUMENTS并没有错。如果您需要支持XP,则无法使用已知的文件夹ID。您可以编写在Vista及更高版本上使用已知文件夹ID的代码,并在早期系统上回退到CSIDL。但为什么要这么麻烦? MS已经SHGetSpecialFolderPath为您完成了这项工作。

答案 1 :(得分:3)

你不应该使用shell32.dll中的ShGetFolderPath吗?假设使用带有IE5或更新版本的Windows 2000。

您需要将shlobj添加到使用它的代码的使用行。

由于源代码中没有SHGetFolderPath的定义,您可以在使用它的代码之前使用以下内容:

function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWORD; pszPath: PChar): HResult; stdcall; external 'shfolder.dll' name 'SHGetFolderPathA';

Delphi 7没有使用广泛版本的例程,因此您可以使用此代码。

答案 2 :(得分:2)

正如大卫已经说过的那样,使用SHGetSpecialFolderPath函数。 Vista和W7将为您进行CSIDL /文件夹转换。 如果你想使用更新的API,这应该是诀窍: 请注意,这只适用于vista。

unit Unit1;

interface

uses
  Windows, ActiveX, Forms, SysUtils, OleAuto, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


type
 TShGetKnownFolderPath = function(const rfid: TGUID; dwFlags: DWord; hToken: THandle; out ppszPath: PWideChar): HResult; stdcall;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function ShGetKnownFolderPath(const rfid: TGUID; dwFlags: DWord; hToken: THandle; out ppszPath: PWideChar): HResult;

var Shell: HModule;
    Fn: TShGetKnownFolderPath;

begin
 Shell := LoadLibrary('shell32.dll');
 Win32Check(Shell <> 0);
 try
  @Fn := GetProcAddress(Shell, 'SHGetKnownFolderPath');
  Win32Check(Assigned(Fn));
  Result := Fn(rfid, dwFlags, hToken, ppszPath);
 finally
  FreeLibrary(Shell);
 end;
end;

function GetPublicDocuments: string;
 var
  ret: HResult;
  Buffer: PWideChar;
begin
  ret := ShGetKnownFolderPath(StringToGuid('{ED4824AF-DCE4-45A8-81E2-FC7965083634}'), 0, 0, Buffer) ;
  OleCheck(ret);
  try
   Result := Buffer;
  finally
    CoTaskMemFree(Buffer);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 ShowMessage(GetPublicDocuments);
end;

end.

答案 3 :(得分:2)

根据Embarcadero在本文档中的建议:VistaUACandDelphi.pdf

Uses SHFolder;

function GetSpecialFolder (CSIDL: Integer; ForceFolder: Boolean = FALSE): string;
CONST SHGFP_TYPE_CURRENT = 0;
VAR i: Integer;
begin
 SetLength(Result, MAX_PATH);
 if ForceFolder
 then ShGetFolderPath(0, CSIDL OR CSIDL_FLAG_CREATE, 0, 0, PChar(Result))= S_ok
 else ShGetFolderPath(0, CSIDL, 0, 0, PChar(Result));
 i:= Pos(#0, Result);
 if i> 0
 then SetLength(Result, pred(i));

 Result:= Trail (Result);
end;

像这样使用:

s:= GetSpecialFolder(CSIDL_LOCAL_APPDATA, true);