From da2fe44184aac713fca9084aed941dc0e153d0e3 Mon Sep 17 00:00:00 2001 From: anders_k Date: Thu, 20 Sep 2012 10:18:40 +0000 Subject: [PATCH] Add ManifestSupportedOS attribute git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6265 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/attributes.but | 16 ++++++++--- Docs/src/history.but | 8 +++--- Source/build.cpp | 3 ++- Source/build.h | 1 + Source/manifest.cpp | 59 ++++++++++++++++++++++++++++++++++++++--- Source/manifest.h | 40 +++++++++++++++++++++++++++- Source/script.cpp | 22 +++++++++++++++ Source/strlist.h | 1 + Source/tokens.cpp | 3 ++- Source/tokens.h | 1 + 10 files changed, 139 insertions(+), 15 deletions(-) diff --git a/Docs/src/attributes.but b/Docs/src/attributes.but index 57e9b250..d828381f 100644 --- a/Docs/src/attributes.but +++ b/Docs/src/attributes.but @@ -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|\\Win7|Win8\\|{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 \\none\\|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 diff --git a/Docs/src/history.but b/Docs/src/history.but index 4f83effc..cea2d9eb 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -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 diff --git a/Source/build.cpp b/Source/build.cpp index 80ecbfb7..5e4b78a4 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -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; diff --git a/Source/build.h b/Source/build.h index 1cf99dbf..b432514c 100644 --- a/Source/build.h +++ b/Source/build.h @@ -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(); diff --git a/Source/manifest.cpp b/Source/manifest.cpp index da61fbf1..904caa03 100644 --- a/Source/manifest.cpp +++ b/Source/manifest.cpp @@ -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 = "Nullsoft Install System "; + string xml = "Nullsoft Install System "; xml += TtoCString(NSIS_VERSION); xml += ""; if (comctl_selection == comctl_xp) { - xml += ""; + xml += ""; } if (exec_level_selection != exec_level_none) @@ -64,7 +103,19 @@ string generate(comctl comctl_selection, exec_level exec_level_selection) xml += ""; - xml += ""; + } + 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 += ""; + while(soslcount--) xml += ""; + xml += ""; } xml += ""; diff --git a/Source/manifest.h b/Source/manifest.h index e018e895..dd8efd21 100644 --- a/Source/manifest.h +++ b/Source/manifest.h @@ -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___ diff --git a/Source/script.cpp b/Source/script.cpp index d15f54fe..87ac2d24 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -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|<>|=) 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}, diff --git a/Source/tokens.h b/Source/tokens.h index 34642460..116f95b8 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -61,6 +61,7 @@ enum TOK_INSTPROGRESSFLAGS, TOK_XPSTYLE, TOK_REQEXECLEVEL, + TOK_MANIFEST_SUPPORTEDOS, TOK_CHANGEUI, TOK_ADDBRANDINGIMAGE, TOK_SETFONT,