From bf2f0fad8045dcaab3aca7de7b6f82b9a8d47bc3 Mon Sep 17 00:00:00 2001 From: anders_k Date: Sat, 21 Jun 2014 23:55:24 +0000 Subject: [PATCH] Added !makensis command git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6498 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/compiler.but | 9 +++++++++ Docs/src/history.but | 2 ++ Source/makenssi.cpp | 3 +++ Source/script.cpp | 36 ++++++++++++++++++------------------ Source/tokens.cpp | 1 + Source/tokens.h | 1 + Source/util.cpp | 20 +++++++++++++++++--- Source/util.h | 4 ++++ 8 files changed, 55 insertions(+), 21 deletions(-) diff --git a/Docs/src/compiler.but b/Docs/src/compiler.but index c7ea68ab..77e33495 100644 --- a/Docs/src/compiler.but +++ b/Docs/src/compiler.but @@ -97,6 +97,15 @@ On POSIX platforms, \R{execute}{!execute} will use system() just like \R{system} \c !execute '"%WINDIR%\notepad.exe" "${NSISDIR}\license.txt"' +\S1{makensis} !makensis + +\c parameters [compare comparevalue | symbol] + +This command will \R{execute}{!execute} a new instance of MakeNSIS with the parameters you specify. + +\c !makensis '-DGENERATEUNINST "${__FILE__}"' = 0 +\c !system '"signtool" sign ...' = 0 + \S1{packhdr} !packhdr \c tempfile command diff --git a/Docs/src/history.but b/Docs/src/history.but index 319f2628..e6adab83 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -8,6 +8,8 @@ Released on ?, 2014 \S2{} Major Changes +\b Added \R{makensis}{!makensis} command + \b Added PPO and SafePPO preprocess-only compiler switches \b MakeNSIS WM_COPYDATA messages now use the QH_OUTPUTCHARSET encoding with CP_ACP as the default for compatibility with old IDEs. diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp index 76e5a23b..c607e129 100644 --- a/Source/makenssi.cpp +++ b/Source/makenssi.cpp @@ -46,6 +46,7 @@ UINT g_wincon_orgoutcp; WINSIO_OSDATA g_osdata_stdout; #endif #endif +const TCHAR *g_argv0=0; static void dopause(void) { @@ -284,6 +285,8 @@ static inline int makensismain(int argc, TCHAR **argv) assert(sizeof(WINWCHAR) == 2 && sizeof(WORD) == 2); assert(sizeof(WINWCHAR) == sizeof(WCHAR)); // Not really required but if WCHAR changes we need to know + g_argv0=argv[0]; + if (!NSISRT_Initialize()) { _ftprintf(stdout,_T("NSISRT_Initialize failed!\n")); diff --git a/Source/script.cpp b/Source/script.cpp index 500531cd..a8a2dfbe 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -3133,9 +3133,10 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_OK; case TOK_P_SYSTEMEXEC: case TOK_P_EXECUTE: + case TOK_P_MAKENSIS: { const TCHAR *cmdname=get_commandtoken_name(which_token); - TCHAR *exec=line.gettoken_str(1), *define; + const TCHAR *exec=line.gettoken_str(1), *define; int comp=line.gettoken_enum(2,_T("<\0>\0<>\0=\0ignore\0")); int validparams=true, ret=-1, cmpv; switch(line.getnumtokens()-1) @@ -3146,24 +3147,23 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) default: comp=-1; } if (!validparams || comp == -1) PRINTHELP() - SCRIPT_MSG(_T("%") NPRIs _T(": \"%") NPRIs _T("\"\n"),cmdname,exec); - PREPROCESSONLY_BEGINCOMMENT(); -#ifdef _WIN32 - if (TOK_P_EXECUTE == which_token) + tstring compile; + if (TOK_P_MAKENSIS == which_token) { -#ifdef _UNICODE - ret=RunChildProcessRedirected(0,exec); -#else - PROCESS_INFORMATION pi; - STARTUPINFO si={sizeof(STARTUPINFO),}; - if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) - { - WaitForSingleObject(pi.hProcess,INFINITE); - if (GetExitCodeProcess(pi.hProcess,&si.cb)) ret=(int)si.cb; - CloseHandle(pi.hThread), CloseHandle(pi.hProcess); - } -#endif + extern const TCHAR *g_argv0; + extern NStreamEncoding g_outputenc; + TCHAR buf[33]; + compile=_T("\""), compile+=get_executable_path(g_argv0), compile+= _T("\""); + compile+= _T(" ") OPT_STR _T("v"), compile+=_itot(get_verbosity(),buf,10); + compile+= _T(" ") OPT_STR _T("OCS "), g_outputenc.GetCPDisplayName(buf), compile+=buf; + if (*exec) compile+= _T(" "), compile+=exec; + exec=compile.c_str(); } + SCRIPT_MSG(_T("%") NPRIs _T(": \"%") NPRIs _T("\"\n"),cmdname,exec); + if (preprocessonly) PREPROCESSONLY_BEGINCOMMENT(); +#ifdef _WIN32 + if (TOK_P_SYSTEMEXEC != which_token) + ret=RunChildProcessRedirected(exec); else #endif //~ _WIN32 ret=sane_system(exec); @@ -3183,7 +3183,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ERROR_MSG(_T("%") NPRIs _T(": returned %d, aborting\n"),cmdname,ret); return PS_ERROR; } - PREPROCESSONLY_ENDCOMMENT(); + if (preprocessonly) PREPROCESSONLY_ENDCOMMENT(); SCRIPT_MSG(_T("%") NPRIs _T(": returned %d\n"),cmdname,ret); } return PS_OK; diff --git a/Source/tokens.cpp b/Source/tokens.cpp index d329c1c8..c0d8558b 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -246,6 +246,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_P_FINALIZE,_T("!finalize"),1,0,_T("command_with_%1"),TP_ALL}, {TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [ | ]\n OP=(< > <> =)"),TP_ALL}, {TOK_P_EXECUTE, _T("!execute"),1,2,_T("command [ | ]\n OP=(< > <> =)"),TP_ALL}, +{TOK_P_MAKENSIS,_T("!makensis"),1,2,_T("parameters [ | ]"),TP_ALL}, {TOK_P_ADDINCLUDEDIR,_T("!AddIncludeDir"),1,0,_T("dir"),TP_ALL}, {TOK_P_INCLUDE,_T("!include"),1,2,_T("[/NONFATAL] [/CHARSET=<") TSTR_INPUTCHARSET _T(">] filename.nsh"),TP_ALL}, {TOK_P_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL}, diff --git a/Source/tokens.h b/Source/tokens.h index efbaa0fb..f424d11c 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -107,6 +107,7 @@ enum TOK_P_FINALIZE, TOK_P_SYSTEMEXEC, TOK_P_EXECUTE, + TOK_P_MAKENSIS, TOK_P_ADDINCLUDEDIR, TOK_P_INCLUDE, TOK_P_CD, diff --git a/Source/util.cpp b/Source/util.cpp index e8f976e6..28184d55 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -828,7 +828,8 @@ const TCHAR* GetFriendlySize(UINT64 n, unsigned int&fn, GETFRIENDLYSIZEFLAGS f) return s >= COUNTOF(scale) ? _T(" ?") : scale[s]; } -#if defined(_WIN32) && defined(_UNICODE) +#ifdef _WIN32 +#ifdef _UNICODE int RunChildProcessRedirected(LPCWSTR cmdprefix, LPCWSTR cmdmain) { // We have to deliver the requested output encoding to our host (if any) and the @@ -837,7 +838,7 @@ int RunChildProcessRedirected(LPCWSTR cmdprefix, LPCWSTR cmdmain) // child to call GetConsoleOutputCP(), and even if we could, UTF-16 is not valid there. UINT cp = CP_UTF8, mbtwcf = MB_ERR_INVALID_CHARS, oemcp = GetOEMCP(); errno = ENOMEM; - if (!cmdprefix) cmdprefix = _T(""); + if (!cmdprefix) cmdprefix = L""; size_t cch1 = _tcslen(cmdprefix), cch2 = _tcslen(cmdmain); WCHAR *cmd = (WCHAR*) malloc( (cch1 + cch2 + 1) * sizeof(WCHAR) ); if (!cmd) return -1; @@ -938,7 +939,20 @@ switchcp: cp = orgwinconoutcp, mbtwcf = 0, utf8 = false; CloseHandle(hPipRd); return childec; } -#endif +#else +int RunChildProcessRedirected(LPCWSTR cmd) +{ + STARTUPINFO si = { sizeof(STARTUPINFO), }; + PROCESS_INFORMATION pi; + if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + return GetLastError(); + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &si.cb); + CloseHandle(pi.hThread), CloseHandle(pi.hProcess); + return (int) si.cb; +} +#endif //~ _UNICODE +#endif //~ _WIN32 int sane_system(const TCHAR *command) { diff --git a/Source/util.h b/Source/util.h index a990334d..dd2e5b8f 100644 --- a/Source/util.h +++ b/Source/util.h @@ -45,6 +45,7 @@ bool GetDLLVersion(const tstring& filepath, DWORD& high, DWORD& low); tstring get_full_path(const tstring& path); tstring get_dir_name(const tstring& path); tstring get_file_name(const tstring& path); +tstring get_executable_path(const TCHAR* argv0); tstring get_executable_dir(const TCHAR *argv0); tstring remove_file_extension(const tstring& path); inline bool IsAgnosticPathSeparator(const TCHAR c) { return _T('\\') == c || _T('/') == c; } @@ -101,6 +102,7 @@ void FlushOutputAndResetPrintColor(); #ifdef _WIN32 #ifdef _UNICODE int RunChildProcessRedirected(LPCWSTR cmdprefix, LPCWSTR cmdmain); +inline int RunChildProcessRedirected(LPCWSTR cmd) { return RunChildProcessRedirected(0, cmd); } #ifdef MAKENSIS typedef struct { HANDLE hNative; @@ -129,6 +131,8 @@ int WinStdIO_wprintf(const wchar_t*Fmt, ...); #undef _vftprintf #define _vftprintf WinStdIO_vfwprintf #endif // ~MAKENSIS +#else +int RunChildProcessRedirected(LPCWSTR cmd); #endif // ~_UNICODE #define ResetPrintColor() FlushOutputAndResetPrintColor() // For reset ONLY, use PrintColorFmtMsg(0,NULL ... #define SetPrintColorWARN() PrintColorFmtMsg(1|0x10, NULL, (va_list)NULL)