Add ManifestSupportedOS attribute

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6265 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2012-09-20 10:18:40 +00:00
parent b0c40ee3b5
commit da2fe44184
10 changed files with 139 additions and 15 deletions

View file

@ -280,6 +280,14 @@ The default string will be used if a string is empty ("").
Accepts variables. If variables are used, they must be initialized before the license page is created.
\S2{amanifestsupportedos} ManifestSupportedOS
\c none|all|WinVista|\\<b\\>Win7|Win8\\</b\\>|{GUID} [...]
Declare that the installer is compatible with the specified Windows version(s). This adds a SupportedOS entry in the compatibility section of the application manifest. The default list of Win7+Win8 will probably be updated to include newer Windows versions in the future. \e{none} is the default if \R{arequestexecutionlevel}{RequestExecutionLevel} is set to \e{none} for compatibility reasons.
You can read more about the changes in behavior on \W{http://msdn.microsoft.com/en-us/library/windows/desktop/hh848036}{MSDN}.
\S2{amiscbuttontext} MiscButtonText
\c [back button text [next button text] [cancel button text] [close button text]]
@ -306,15 +314,15 @@ Accepts variables. If variables are used, they must be initialized in \R{oninit}
Specifies the output file that the MakeNSIS should write the installer to. This is just the file that MakeNSIS writes, it doesn't affect the contents of the installer.
\S2{requestexecutionlevel} RequestExecutionLevel
\S2{arequestexecutionlevel} RequestExecutionLevel
\c \\<b\\>none\\</b\\>|user|highest|admin
Specifies the requested execution level for Windows Vista and Windows 7. The value is embedded in the installer and uninstaller's XML manifest and tells Vista/7, and probably future versions of Windows, what privileges level the installer requires. \e{user} requests the a normal user's level with no administrative privileges. \e{highest} will request the highest execution level available for the current user and will cause Windows to prompt the user to verify privilege escalation. The prompt might request for the user's password. \e{admin} requests administrator level and will cause Windows to prompt the user as well. Specifying \e{none}, which is also the default, will keep the manifest empty and let Windows decide which execution level is required. Windows Vista/7 automatically identifies NSIS installers and decides administrator privileges are required. Because of this, \e{none} and \e{admin} have virtually the same effect.
Specifies the requested execution level for Windows Vista and higher. The value is embedded in the installer and uninstaller's XML manifest and tells Windows which privilege level the installer requires. \e{user} requests the a normal user's level with no administrative privileges. \e{highest} will request the highest execution level available for the current user and will cause Windows to prompt the user to verify privilege escalation. The prompt might request for the user's password. \e{admin} requests administrator level and will cause Windows to prompt the user as well. Specifying \e{none}, which is also the default, will keep the manifest empty and let Windows decide which execution level is required. Windows automatically identifies NSIS installers and decides administrator privileges are required. Because of this, \e{none} and \e{admin} have virtually the same effect.
It's recommended, at least by Microsoft, that every application will be marked with the required execution level. Unmarked installers are subject to compatibility mode. Workarounds of this mode include automatically moving any shortcuts created in the user's start menu to all users' start menu. Installers that need not install anything into system folders or write to the local machine registry (HKLM) should specify \e{user} execution level.
It's recommended, at least by Microsoft, that every application is marked with a required execution level. Unmarked installers are subject to compatibility mode. Workarounds of this mode include automatically moving any shortcuts created in the user's start menu to all users' start menu. Installers that need not install anything into system folders or write to the local machine registry (HKLM) should specify \e{user} execution level.
More information about this topic can be found at MSDN. Keywords include "UAC", "requested execution level", "vista manifest" and "vista security".
More information about this topic can be found on \W{http://msdn.microsoft.com/en-us/library/bb756929}{MSDN}.
\S2{asetfont} SetFont

View file

@ -34,13 +34,13 @@ Released on June 6th, 2009
\S1{v2.45-rl} Release Notes
\b Support for Microsoft's upcoming release of Windows 7 has been added based on RC1 testing and documentation. Please report any related issues and don't forget to use \R{requestexecutionlevel}{RequestExecutionLevel}.
\b Support for Microsoft's upcoming release of Windows 7 has been added based on RC1 testing and documentation. Please report any related issues and don't forget to use \R{arequestexecutionlevel}{RequestExecutionLevel}.
\S1{v2.45-cl} Changelog
\S2{} Major Changes
\b Added support for Windows 7 installers - use \R{requestexecutionlevel}{RequestExecutionLevel}, just like with Vista (\W{http://sourceforge.net/support/tracker.php?aid=2725883}{bug #2725883})
\b Added support for Windows 7 installers - use \R{arequestexecutionlevel}{RequestExecutionLevel}, just like with Vista (\W{http://sourceforge.net/support/tracker.php?aid=2725883}{bug #2725883})
\b Added WinVer.nsh Windows 7 and Windows 2008 R2 support
@ -1108,7 +1108,7 @@ Released on November 27th, 2006
\S2{} New/Changed Commands
\b Added `highest` option for \R{requestexecutionlevel}{RequestExecutionLevel}
\b Added `highest` option for \R{arequestexecutionlevel}{RequestExecutionLevel}
\S2{} Translations
@ -1152,7 +1152,7 @@ Released on October 20th, 2006
\S2{} New/Changed Commands
\b Added \R{requestexecutionlevel}{RequestExecutionLevel} (\W{http://sourceforge.net/support/tracker.php?aid=1524709}{RFE #1524709})
\b Added \R{arequestexecutionlevel}{RequestExecutionLevel} (\W{http://sourceforge.net/support/tracker.php?aid=1524709}{RFE #1524709})
\S2{} Translations

View file

@ -278,6 +278,7 @@ CEXEBuild::CEXEBuild() :
manifest_comctl = manifest::comctl_old;
manifest_exec_level = manifest::exec_level_none;
manifest_sosl.setdefault();
enable_last_page_cancel=0;
uenable_last_page_cancel=0;
@ -2340,7 +2341,7 @@ int CEXEBuild::SetManifest()
try {
init_res_editor();
// This should stay ANSI
string manifest = manifest::generate(manifest_comctl, manifest_exec_level);
string manifest = manifest::generate(manifest_comctl, manifest_exec_level, manifest_sosl);
if (manifest == "")
return PS_OK;

View file

@ -507,6 +507,7 @@ class CEXEBuild {
manifest::comctl manifest_comctl;
manifest::exec_level manifest_exec_level;
manifest::SupportedOSList manifest_sosl;
CResourceEditor *res_editor;
void init_res_editor();

View file

@ -28,18 +28,57 @@ namespace manifest
using namespace std;
string generate(comctl comctl_selection, exec_level exec_level_selection)
static bool isstrhexchars(const TCHAR*s,UINT cch)
{
while(cch-- && *s)
{
const TCHAR c = *s++, clw = ((char)c) | 32;
if (!(c >= '0' && c <= '9') && !(clw >= 'a' && clw <= 'f')) return false;
}
return true;
}
bool SupportedOSList::append(const TCHAR* osid)
{
const TCHAR *guid = 0;
if ('{' == *osid)
{
if (38 == _tcsclen(osid) && '}' == osid[37]
&& '-' == osid[9] && '-' == osid[14] && '-' == osid[19] && '-' == osid[24]
&& isstrhexchars(osid+1,8) && isstrhexchars(osid+10,4)
&& isstrhexchars(osid+15,4) && isstrhexchars(osid+20,4)
&& isstrhexchars(osid+25,12)
)
{
guid = osid;
}
}
else if (!_tcsicmp(osid,"WinVista")) guid = _T("{e2011457-1546-43c5-a5fe-008deee3d3f0}");
else if (!_tcsicmp(osid,"Win7")) guid = _T("{35138b9a-5d96-4fbd-8e2d-a2440225f93a}");
else if (!_tcsicmp(osid,"Win8")) guid = _T("{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}");
if (guid)
{
m_list.add(guid,0);
m_isdefaultlist = false;
return true;
}
return false;
}
string generate(comctl comctl_selection, exec_level exec_level_selection, SupportedOSList& sosl)
{
if (comctl_selection == comctl_old && exec_level_selection == exec_level_none)
return "";
string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"><assemblyIdentity version=\"1.0.0.0\" processorArchitecture=\"X86\" name=\"Nullsoft.NSIS.exehead\" type=\"win32\"/><description>Nullsoft Install System ";
string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"><assemblyIdentity version=\"1.0.0.0\" processorArchitecture=\"*\" name=\"Nullsoft.NSIS.exehead\" type=\"win32\"/><description>Nullsoft Install System ";
xml += TtoCString(NSIS_VERSION);
xml += "</description>";
if (comctl_selection == comctl_xp)
{
xml += "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"X86\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\" /></dependentAssembly></dependency>";
xml += "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"*\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\" /></dependentAssembly></dependency>";
}
if (exec_level_selection != exec_level_none)
@ -64,7 +103,19 @@ string generate(comctl comctl_selection, exec_level exec_level_selection)
xml += "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"";
xml += level;
xml += "\" uiAccess=\"false\"/></requestedPrivileges></security></trustInfo>";
xml += "<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\"><application><supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\"/><supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\"/></application></compatibility>";
}
else if (sosl.isdefaultlist())
{
// Don't add supportedOS list for exec_level_none to remain compatible with v2.46
sosl.deleteall();
}
int soslcount = sosl.getcount();
if (soslcount)
{
xml += "<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\"><application>";
while(soslcount--) xml += "<supportedOS Id=\"", xml += sosl.get(soslcount), xml += "\"/>";
xml += "</application></compatibility>";
}
xml += "</assembly>";

View file

@ -20,6 +20,7 @@
#define ___MANIFEST_H___
#include "tstring.h"
#include "strlist.h"
namespace manifest
{
@ -37,7 +38,44 @@ namespace manifest
exec_level_admin
};
std::string generate(comctl, exec_level);
class SupportedOSList
{
StringList m_list;
bool m_isdefaultlist;
public:
SupportedOSList() : m_isdefaultlist(false) {}
bool append(const TCHAR* osid);
int getcount() const { return m_list.getnum(); }
bool isdefaultlist() const { return m_isdefaultlist; }
const TCHAR* get(int idx)
{
int pos = m_list.idx2pos(idx);
if (-1 == pos) return 0;
return m_list.get() + pos;
}
void deleteall()
{
m_list.deleteall();
m_isdefaultlist = false;
}
void addall()
{
append("WinVista");
append("Win7");
append("Win8");
}
void setdefault()
{
m_list.deleteall();
append("Win7");
append("Win8");
m_isdefaultlist = true;
}
};
std::string generate(comctl, exec_level, SupportedOSList&);
};
#endif//!___MANIFEST_H___

View file

@ -2862,6 +2862,28 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
}
return PS_OK;
case TOK_MANIFEST_SUPPORTEDOS:
{
manifest_sosl.deleteall();
if (2 == line.getnumtokens())
{
switch(line.gettoken_enum(1,_T("none\0all\0")))
{
case 0:
return PS_OK;
case 1:
manifest_sosl.addall();
return PS_OK;
}
}
for(int argi=1; argi<line.getnumtokens(); ++argi)
{
if (!manifest_sosl.append(line.gettoken_str(argi)))
PRINTHELP();
}
}
return PS_OK;
#ifdef _UNICODE
case TOK_TARGETMINIMALOS:
{

View file

@ -85,6 +85,7 @@ public:
* before the start of the string.
*/
void delbypos(int pos);
void deleteall() { m_gr.resize(0); }
/**
* Converts the string index to the positional TCHAR index. For example,

View file

@ -240,6 +240,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_WRITEUNINSTALLER,_T("WriteUninstaller"),1,0,_T("uninstall_exe_name"),TP_CODE},
{TOK_XPSTYLE, _T("XPStyle"),1,0,_T("(on|off)"),TP_GLOBAL},
{TOK_REQEXECLEVEL, _T("RequestExecutionLevel"),1,0,_T("none|user|highest|admin"),TP_GLOBAL},
{TOK_MANIFEST_SUPPORTEDOS,_T("ManifestSupportedOS"),1,-1,_T("none|all|WinVista|Win7|Win8|{GUID} [...]"),TP_GLOBAL},
{TOK_P_PACKEXEHEADER,_T("!packhdr"),2,0,_T("temp_file_name command_line_to_compress_that_temp_file"),TP_ALL},
{TOK_P_FINALIZE,_T("!finalize"),1,0,_T("command_with_%1"),TP_ALL},
{TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [<|>|<>|=) retval]"),TP_ALL},
@ -258,7 +259,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_P_WARNING,_T("!warning"),0,1,_T("[warning_message]"),TP_ALL},
{TOK_P_ERROR,_T("!error"),0,1,_T("[error_message]"),TP_ALL},
{TOK_P_VERBOSE,_T("!verbose"),1,-1,_T("(verbose_level | push | pop) [...]"),TP_ALL},
{TOK_P_VERBOSE,_T("!verbose"),1,-1,_T("verbose_level | push | pop [...]"),TP_ALL},
{TOK_P_MACRO,_T("!macro"),1,-1,_T("macroname [parms ...]"),TP_ALL},
{TOK_P_MACROEND,_T("!macroend"),0,0,_T(""),TP_ALL},

View file

@ -61,6 +61,7 @@ enum
TOK_INSTPROGRESSFLAGS,
TOK_XPSTYLE,
TOK_REQEXECLEVEL,
TOK_MANIFEST_SUPPORTEDOS,
TOK_CHANGEUI,
TOK_ADDBRANDINGIMAGE,
TOK_SETFONT,