Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
990 views
in Technique[技术] by (71.8m points)

windows - Constant for AppDataLocalLow in Inno Setup?

Currently to access LocalLow I use this:

{%USERPROFILE}AppDataLocalLow

But I would like to know if there's a constant for that in Inno Setup, since both Roaming and Local have one.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's no constant for AppDataLocalLow.

You may use Pascal Scripting to resolve it.

To resolve the "LocalLow", one has to use SHGetKnownFolderPath.
See also Detect the location of AppDataLocalLow.

The implementation involves few hacks, due to a lack of (wide) PChar type in Unicode Inno Setup.

const
  MAX_PATH = 260;
  AppDataLocalLowGUID = '{A520A1A4-1780-4FF6-BD18-167343C5AF16}';

{ There's no PChar in Unicode Inno Setup, }
{ pretend the function returns a pointer to an Integer }
function SHGetKnownFolderPath(rfid: TGUID; dwFlags: DWORD; hToken: THandle;
  var ppszPath: Integer): Integer;
  external '[email protected] stdcall';

{ And allow the Integer to be copied to string }
function StrCpy(Dest: string; Source: Integer): Integer;
  external '[email protected] stdcall';

{ And allow the Integer pointer to be released }
procedure CoTaskMemFreeAsInteger(pv: Integer);
  external '[email protected] stdcall';

function GetAppDataLocalLow: string;
var
  Path: Integer;
  I: Integer;
begin
  if SHGetKnownFolderPath(StringToGUID(AppDataLocalLowGUID), 0, 0, Path) = 0 then
  begin
    { The path should not be longer than MAX_PATH }
    SetLength(Result, MAX_PATH);

    StrCpy(Result, Path);

    CoTaskMemFreeAsInteger(Path);

    { Look for NUL character and adjust the length accordingly }
    SetLength(Result, Pos(#0, Result) - 1);
  end;
end;

If you need to use the path in non-Code section (outside of the Pascal Script), you can use a scripted constant:

[Files]
Source: myfile.txt; DestDir: {code:GetAppDataLocalLow}

And you need to change the function signature to take a dummy parameter:

function GetAppDataLocalLow(Param: string): string;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...