diff --git a/Docs/src/history.but b/Docs/src/history.but
index cb68d4e9..3020c22b 100644
--- a/Docs/src/history.but
+++ b/Docs/src/history.but
@@ -16,6 +16,8 @@ Released on ???? ??th, 20??
\S2{} Minor Changes
+\b Added \cw{$USER..} and \cw{$COMMON..} alias constants
+
\b Disallow start maximized mode
\b Added /LAUNCH compiler switch
diff --git a/Docs/src/misc.but b/Docs/src/misc.but
index 8be741db..d7a8c348 100644
--- a/Docs/src/misc.but
+++ b/Docs/src/misc.but
@@ -71,7 +71,7 @@ Sets the error level of the installer or uninstaller to \e{error_level}. See \R{
\S2{setshellvarcontext} SetShellVarContext
-\c \\current\\|all
+\c \\current\\|all|lastused
Sets the context of $SMPROGRAMS and other \R{varconstant}{shell folders}. If set to 'current' (the default), the current user's shell folders are used. If set to 'all', the 'all users' shell folder is used. The all users folder may not be supported on all OSes. If the all users folder is not found, the current user folder will be used. Please take into consideration that a "normal user" has no rights to write in the all users area. Only admins have full access rights to the all users area. You can check this by using the UserInfo plug-in. See Contrib\\UserInfo\\UserInfo.nsi for an example.
diff --git a/Docs/src/var.but b/Docs/src/var.but
index b42a1d37..94c20505 100644
--- a/Docs/src/var.but
+++ b/Docs/src/var.but
@@ -119,7 +119,7 @@ The quick launch folder for IE4 active desktop and above. If quick launch is not
\e{$DOCUMENTS}
-The documents directory. A typical path for the current user is \c{C:\\Documents and Settings\\Foo\\My Documents}. The context of this constant (All Users or Current user) depends on the \R{setshellvarcontext}{SetShellVarContext} setting. The default is the current user.
+The documents directory. A typical path for the current user is \c{C:\\Users\\Foo\\My Documents}. The context of this constant (All Users or Current user) depends on the \R{setshellvarcontext}{SetShellVarContext} setting. The default is the current user.
This constant is not available on Windows 95 unless Internet Explorer 4 is installed.
@@ -207,7 +207,7 @@ This constant is not available on Windows 95 nor Windows NT 4 unless Internet Ex
\e{$PROFILE}
-The user's profile directory. A typical path is \c{C:\\Documents and Settings\\Foo}.
+The user's profile directory. A typical path is \c{C:\\Users\\Foo}.
This constant is available on Windows 2000 and above.
@@ -243,6 +243,10 @@ HWND of the main window (in decimal).
The path to a temporary folder created upon the first usage of a plug-in or a call to \R{initpluginsdir}{InitPluginsDir}. This folder is automatically deleted when the installer exits. This makes this folder the ideal folder to hold INI files for \L{../Docs/InstallOptions/Readme.html}{InstallOptions}, bitmaps for the splash plug-in, or any other file that a plug-in needs to work.
+\e{$USER..} and \e{$COMMON..}
+
+A handful of constants are available as aliases that are not affected by \R{setshellvarcontext}{SetShellVarContext}: \e{$USERTEMPLATES}, \e{$USERSTARTMENU}, \e{$USERSMPROGRAMS}, \e{$USERDESKTOP}, \e{$COMMONTEMPLATES}, \e{$COMMONSTARTMENU}, \e{$COMMONSMPROGRAMS}, \e{$COMMONDESKTOP} and \e{$COMMONPROGRAMDATA}.
+
\S1{varstrings} Constants Used in Strings
\e{$$}
diff --git a/Source/build.cpp b/Source/build.cpp
index b0cd9b14..4011da2f 100644
--- a/Source/build.cpp
+++ b/Source/build.cpp
@@ -377,6 +377,21 @@ CEXEBuild::CEXEBuild(signed char pponly, bool warnaserror) :
m_ShellConstants.add(_T("RESOURCES"), CSIDL_RESOURCES, CSIDL_RESOURCES);
m_ShellConstants.add(_T("RESOURCES_LOCALIZED"), CSIDL_RESOURCES_LOCALIZED, CSIDL_RESOURCES_LOCALIZED);
m_ShellConstants.add(_T("CDBURN_AREA"), CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA);
+
+ // Contants that are not affected by SetShellVarContext
+ m_ShellConstants.add(_T("USERAPPDATA"), CSIDL_APPDATA, CSIDL_APPDATA);
+ m_ShellConstants.add(_T("USERLOCALAPPDATA"), CSIDL_LOCAL_APPDATA, CSIDL_LOCAL_APPDATA);
+ m_ShellConstants.add(_T("USERTEMPLATES"), CSIDL_TEMPLATES, CSIDL_TEMPLATES);
+ m_ShellConstants.add(_T("USERSTARTMENU"), CSIDL_STARTMENU, CSIDL_STARTMENU);
+ m_ShellConstants.add(_T("USERSMPROGRAMS"), CSIDL_PROGRAMS, CSIDL_PROGRAMS);
+ m_ShellConstants.add(_T("USERDESKTOP"), CSIDL_DESKTOPDIRECTORY, CSIDL_DESKTOPDIRECTORY);
+ m_ShellConstants.add(_T("COMMONLOCALAPPDATA"), CSIDL_COMMON_APPDATA, CSIDL_COMMON_APPDATA);
+ m_ShellConstants.add(_T("COMMONPROGRAMDATA"), CSIDL_COMMON_APPDATA, CSIDL_COMMON_APPDATA); // a.k.a. %ProgramData%
+ m_ShellConstants.add(_T("COMMONTEMPLATES"), CSIDL_COMMON_TEMPLATES, CSIDL_COMMON_TEMPLATES);
+ m_ShellConstants.add(_T("COMMONSTARTMENU"), CSIDL_COMMON_STARTMENU, CSIDL_COMMON_STARTMENU);
+ m_ShellConstants.add(_T("COMMONSMPROGRAMS"), CSIDL_COMMON_PROGRAMS, CSIDL_COMMON_PROGRAMS);
+ m_ShellConstants.add(_T("COMMONDESKTOP"), CSIDL_COMMON_DESKTOPDIRECTORY, CSIDL_COMMON_DESKTOPDIRECTORY);
+
// PROGRAMFILES&COMMONFILES does a registry lookup and the required string offsets are filled in later.
// We do this later because the unicode mode has to be locked when we call add_string...
m_ShellConstants.add(_T("PROGRAMFILES"), 0, 0);
diff --git a/Source/script.cpp b/Source/script.cpp
index f3c4e41e..b27e32f7 100644
--- a/Source/script.cpp
+++ b/Source/script.cpp
@@ -912,6 +912,7 @@ static HKEY ParseRegRootKey(LineParser &line, int tok)
return k == -1 ? INVALIDREGROOT : rootkey_tab[k];
}
+#define AFIE_LASTUSED ( -1 )
int CEXEBuild::add_flag_instruction_entry(int which_token, int opcode, LineParser &line, int offset, int data)
{
entry ent = { opcode, };
@@ -919,7 +920,7 @@ int CEXEBuild::add_flag_instruction_entry(int which_token, int opcode, LineParse
{
case EW_SETFLAG:
ent.offsets[0] = offset;
- ent.offsets[1] = data;
+ if (data != AFIE_LASTUSED) ent.offsets[1] = data; else ent.offsets[2] = 1;
if (display_script) SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("\n"), get_commandtoken_name(which_token), line.gettoken_str(1));
return add_entry(&ent);
case EW_IFFLAG:
@@ -3033,9 +3034,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_GETSHELLVARCONTEXT:
return add_flag_instruction_entry(which_token, EW_GETFLAG, line, FLAG_OFFSET(all_user_var));
case TOK_SETSHELLVARCONTEXT:
- ent.offsets[1] = line.gettoken_enum(1,_T("current\0all\0"));
+ ent.offsets[1] = line.gettoken_enum(1,_T("current\0all\0lastused\0"));
if (ent.offsets[1] < 0 ) PRINTHELP()
- return add_flag_instruction_entry(which_token, EW_SETFLAG, line, FLAG_OFFSET(all_user_var), add_intstring(ent.offsets[1]));
+ return add_flag_instruction_entry(which_token, EW_SETFLAG, line, FLAG_OFFSET(all_user_var), ent.offsets[1] != 2 ? add_intstring(ent.offsets[1]) : AFIE_LASTUSED);
case TOK_IFSHELLVARCONTEXTALL:
return add_flag_instruction_entry(which_token, EW_IFFLAG, line, FLAG_OFFSET(all_user_var), ~0); //new value mask - keep flag
case TOK_RET:
diff --git a/Source/tokens.cpp b/Source/tokens.cpp
index 7764aa63..78a039d5 100644
--- a/Source/tokens.cpp
+++ b/Source/tokens.cpp
@@ -217,7 +217,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_SETREGVIEW,_T("SetRegView"),1,0,_T("32|64|default|lastused"),TP_CODE},
{TOK_IFALTREGVIEW,_T("IfAltRegView"),1,1,_T("goto_true [goto_false]"),TP_CODE},
{TOK_GETSHELLVARCONTEXT,_T("GetShellVarContext"),1,0,_T("$(user_var: output)"),TP_CODE},
-{TOK_SETSHELLVARCONTEXT,_T("SetShellVarContext"),1,0,_T("all|current"),TP_CODE},
+{TOK_SETSHELLVARCONTEXT,_T("SetShellVarContext"),1,0,_T("all|current|lastused"),TP_CODE},
{TOK_IFSHELLVARCONTEXTALL,_T("IfShellVarContextAll"),1,1,_T("goto_true [goto_false]"),TP_CODE},
{TOK_SETSILENT,_T("SetSilent"),1,0,_T("silent|normal"),TP_CODE},
{TOK_SHOWDETAILS,_T("ShowInstDetails"),1,0,_T("(hide|show|nevershow)"),TP_GLOBAL},