【问题标题】:How to get appdata folder path in delphidelphi如何获取appdata文件夹路径
【发布时间】:2015-08-13 18:31:18
【问题描述】:

如何获取 appdata 文件夹路径?这是我的代码:

begin
  Winexec(PAnsichar('%appdata%\TEST.exe'), sw_show);
end;

但不工作。

【问题讨论】:

    标签: windows delphi-7


    【解决方案1】:

    您不能将环境变量传递给WinExec()。您必须先解决它们,例如:

    uses
      ..., SysUtils;
    
    function GetPathToTestExe: string;
    begin
      Result := SysUtils.GetEnvironmentVariable('APPDATA');
      if Result <> '' then
        Result := IncludeTrailingPathDelimiter(Result) + 'TEST.exe';
    end;
    
    uses
      ..., Windows;
    
    var
      Path: string;
    begin
      Path = GetPathToTestExe;
      if Path <> '' then
        WinExec(PAnsiChar(Path), SW_SHOW);
    end;
    

    或者:

    uses
      ..., SysUtils, Windows;
    
    function GetPathToTestExe: string;
    var
      Path: array[0..MAX_PATH+1] of Char;
    begin
      if ExpandEnvironmentStrings('%APPDATA%', Path, Length(Path)) > 1 then
        Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe'
      else
        Result := '';
    end;
    

    获取 APPDATA 文件夹路径的更可靠(和官方)方法是改用 SHGetFolderPath()(或 Vista+ 上的 SHGetKnownFolderPath()),例如:

    uses
      ..., SysUtils, Windows, SHFolder;
    
    function GetPathToTestExe: string;
    var
      Path: array[0..MAX_PATH] of Char;
    begin
      if SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, Path) = S_OK then
        Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe'
      else
        Result := '';
    end;
    

    或者:

    uses
      ..., SysUtils;
    
    function GetPathToTestExe: string;
    var
      Path: string;
    begin
      // GetHomePath() uses SHGetFolderPath(CSIDL_APPDATA) internally...
      Path := SysUtils.GetHomePath;
      if Path <> '' then
        Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe'
      else
        Result := '';
    end;
    
    

    但是,无论如何,WinExec() 自 Windows 95 以来已被弃用,您确实应该改用 CreateProcess(),例如:

    uses
      ..., Windows;
    
    var
      Path: String;
      si: TStartupInfo;
      pi: TProcessInformation;
    
    Path := GetPathToTestExe;
    if Path <> '' then
    begin
      ZeroMemory(@si, SizeOf(si));
      si.cb := SizeOf(si);
      si.dwFlags := STARTF_USESHOWWINDOW;
      si.wShowWindow := SW_SHOW;
    
      if CreateProcess(nil, PChar(Path), nil, nil, FALSE, 0, nil, nil, @si, pi)
      begin
        //...
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
      end;
    end;
    

    【讨论】:

    • 为什么不使用“System.SysUtils.GetHomePath”?
    • 在 delphi 7 中不可用
    【解决方案2】:

    使用 System.IOUtils 的正确方法:

    function GetAppDataFolder: string;                                       { Returns the path to the current user's AppData folder on Windows and to the current user's home directory on Mac OS X.   Example:  c:\Documents and Settings\Bere\Application Data\AppName\ }
    begin
     Assert(System.IOUtils.TPath.HasValidFileNameChars(AppName, FALSE), 'Invalid chars in AppName: '+ AppName);
     Result:= Trail(Trail(System.SysUtils.GetHomePath)+ AppName);
    end;
    

    实用程序:

    function ForceAppDataFolder: string;  // Make sure the AppDataFolder exists before you try to write the INI file there!                                      
    begin
     Result:= GetAppDataFolder;
     ForceDirectories(Result);
    end;
    
    function Trail(CONST Path: string): string;    //ok  Works with UNC paths
    begin
     if Path= '' then EXIT('');                                                                        { Encountered when doing something like this:  ExtractLastFolder('c:\'). ExtractLastFolder will return '' }
     Result:= IncludeTrailingPathDelimiter(Path)
    end;
    

    【讨论】:

    • AppName 是我的程序名吗?如果是我将通过参数传递它
    • "AppName 是我的程序名吗?"是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    相关资源
    最近更新 更多