I install some sample documents into a 'PerfectTablePlan' sub-folder of the standard 'My documents' folder on Windows. This works fine for 99%+ of users. But if a user doesn't have a 'My documents' folder I get a number of ugly error messages of the form:
Internal error:Failed to expand shell folder constant “userdocs”
This is not very confidence inspiring for the user!
It is acceptable to not install the samples for these users (or install them somewhere else). But not to show the ugly error messages.
The problem seems to come from the ExpandConstant macro expansion of {userdocs}.
Is there some way I can get the path of 'My documents' without using a macro?
Or some way to suppress the error message? ExpandConstant throws an exception: http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_expandconstant
The relevant parts of my .iss file looks like this:
#define MySampleDir "{code:SampleDirRoot}\PerfectTablePlan"
...
[Files]
Source: ..\binaries\windows\program\plans\*_v14.tp; DestDir: {#MySampleDir}\; Flags: ignoreversion onlyifdoesntexist createallsubdirs recursesubdirs uninsneveruninstall;
Source: ..\binaries\windows\program\plans\*_v3.tps; DestDir: {#MySampleDir}\; Flags: ignoreversion onlyifdoesntexist createallsubdirs recursesubdirs uninsneveruninstall;
...
[Code]
function SampleDirRoot(Param: String): String;
begin
if DirExists( ExpandConstant('{userdocs}') ) then
Result := ExpandConstant('{userdocs}')
else
Result := ExpandConstant('{allusersprofile}')
end;
The exception:
Failed to expand shell folder constant 'constant name'
is raised when the internally called SHGetFolderPath
function (called from inside ExpandConstant
when expanding a shell folder constant) returns an empty path string for the given folder CSIDL, in this case for the CSIDL_PERSONAL
identifier.
That means the user doesn't have the CSIDL_PERSONAL
folder. It makes me wonder how can one configure Windows' user account to not have that folder. Well, you can workaround this issue (or Windows misconfiguration ?) by catching the raised internal exception in the try..except
block:
[Code]
function SampleDirRoot(Param: string): string;
var
Folder: string;
begin
try
// first try to expand the {userdocs} folder; if this raises that
// internal exception, you'll fall down to the except block where
// you expand the {allusersprofile}
Folder := ExpandConstant('{userdocs}');
// the {userdocs} folder expanding succeded, so let's test if the
// folder exists and if not, expand {allusersprofile}
if not DirExists(Folder) then
Folder := ExpandConstant('{allusersprofile}');
except
Folder := ExpandConstant('{allusersprofile}');
end;
// return the result
Result := Folder;
end;
But I've never heard about possibility of not having the CSIDL_PERSONAL
folder. Please note, that the above code protects only the {userdocs}
constant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With