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;
We use folder redirection here and have had issues similar to this with other apps (GnuCash, UFile). The problem in our case was a result of a feature called Redirected Folder Migration*, which in some cases did not update the user's registry settings to point to the new location after the migration was completed (note this migration might occur weeks after the GPO was set).
Anyway, it's not that the entry was blank, but that it pointed to a SERVER\SHARE that had been brought offline weeks earlier.
Running a
gpupdate /force
for every active user on every machine fixed our problem, as it updated the registry and then told the user he had to logoff / logon.*Redirected Folder Migration allows an admin to specify that each user's (e.g.) My Documents folder should be moved from one network location to another. It does this in a slow, measured fashion, the next time the user logs on to (any workstation on) the domain (so if your last user only logs on a month from now, the process takes a month to complete). It's a lovely idea in theory, but in practice is a big PITA.
Incidentally, the 'share doesn't exist because it's impersonating another user' thing shouldn't be an issue with properly redirected folders because the redirect should use a URL, not a mapped drive letter (e.g. \\server\RedirectedUserFolders\SOME-USER\My Documents, although permissions might be an issue if you remove some default rights).
The exception:
is raised when the internally called
SHGetFolderPath
function (called from insideExpandConstant
when expanding a shell folder constant) returns an empty path string for the given folder CSIDL, in this case for theCSIDL_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 thetry..except
block: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.