Add new (optional) makensis win32 abort event to avoid multiple instance issues

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6298 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2013-03-14 18:00:00 +00:00
parent b8903496e3
commit e43d5a3b9e
6 changed files with 96 additions and 39 deletions

View file

@ -36,6 +36,11 @@
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
#endif
namespace MakensisAPI {
const TCHAR* SigintEventNameFmt = _T("makensis win32 sigint event %u");
const TCHAR* SigintEventNameLegacy = _T("makensis win32 signint event");
}
NSCRIPTDATA g_sdata;
NRESIZEDATA g_resize;
NFINDREPLACE g_find;
@ -53,7 +58,7 @@ int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int
memset(&g_find,0,sizeof(NFINDREPLACE));
g_sdata.hInstance=hInst;
g_sdata.symbols = NULL;
g_sdata.sigint_event = CreateEvent(NULL, FALSE, FALSE, _T("makensis win32 signint event"));
g_sdata.sigint_event_legacy = CreateEvent(NULL, FALSE, FALSE, MakensisAPI::SigintEventNameLegacy);
RestoreSymbols();
HINSTANCE hRichEditDLL = LoadLibrary(_T("RichEd20.dll"));
@ -83,6 +88,7 @@ int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int
if (g_sdata.script) GlobalFree(g_sdata.script);
if (g_sdata.script_cmd_args) GlobalFree(g_sdata.script_cmd_args);
if (g_sdata.sigint_event) CloseHandle(g_sdata.sigint_event);
if (g_sdata.sigint_event_legacy) CloseHandle(g_sdata.sigint_event_legacy);
FreeLibrary(hRichEditDLL);
FinalizeUpdate();
return msg.wParam;
@ -457,17 +463,17 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
{
PCOPYDATASTRUCT cds = PCOPYDATASTRUCT(lParam);
switch (cds->dwData) {
case MAKENSIS_NOTIFY_SCRIPT:
case MakensisAPI::NOTIFY_SCRIPT:
if (g_sdata.input_script) GlobalFree(g_sdata.input_script);
g_sdata.input_script = (TCHAR *)GlobalAlloc(GPTR, cds->cbData * sizeof(TCHAR));
lstrcpy(g_sdata.input_script, (TCHAR *)cds->lpData);
break;
case MAKENSIS_NOTIFY_WARNING:
case MakensisAPI::NOTIFY_WARNING:
g_sdata.warnings++;
break;
case MAKENSIS_NOTIFY_ERROR:
case MakensisAPI::NOTIFY_ERROR:
break;
case MAKENSIS_NOTIFY_OUTPUT:
case MakensisAPI::NOTIFY_OUTPUT:
if (g_sdata.output_exe) GlobalFree(g_sdata.output_exe);
g_sdata.output_exe = (TCHAR *)GlobalAlloc(GPTR, cds->cbData * sizeof(TCHAR));
lstrcpy(g_sdata.output_exe, (TCHAR *)cds->lpData);
@ -614,6 +620,7 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
case IDM_CANCEL:
{
SetEvent(g_sdata.sigint_event);
SetEvent(g_sdata.sigint_event_legacy);
return TRUE;
}
case IDM_COPY:
@ -704,6 +711,16 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
}
DWORD WINAPI MakeNSISProc(LPVOID p) {
TCHAR eventnamebuf[100];
wsprintf(eventnamebuf,MakensisAPI::SigintEventNameFmt,g_sdata.hwnd);
if (g_sdata.sigint_event) CloseHandle(g_sdata.sigint_event);
g_sdata.sigint_event = CreateEvent(NULL,FALSE,FALSE,eventnamebuf);
if (!g_sdata.sigint_event) {
ErrorMessage(g_sdata.hwnd,_T("There was an error creating the abort event."));
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
return 1;
}
#ifdef _UNICODE
TCHAR buf[1024];
#endif

View file

@ -75,12 +75,17 @@
#define WM_MAKENSIS_LOADSYMBOLSET (WM_USER+1002)
#define WM_MAKENSIS_SAVESYMBOLSET (WM_USER+1003)
enum {
MAKENSIS_NOTIFY_SCRIPT,
MAKENSIS_NOTIFY_WARNING,
MAKENSIS_NOTIFY_ERROR,
MAKENSIS_NOTIFY_OUTPUT
};
namespace MakensisAPI {
extern const TCHAR* SigintEventNameFmt;
extern const TCHAR* SigintEventNameLegacy;
enum notify_e {
NOTIFY_SCRIPT,
NOTIFY_WARNING,
NOTIFY_ERROR,
NOTIFY_OUTPUT
};
}
typedef enum {
COMPRESSOR_NONE_SELECTED = -1,
@ -185,6 +190,7 @@ typedef struct NSISScriptData {
HMENU toolsSubmenu;
HANDLE thread;
HANDLE sigint_event;
HANDLE sigint_event_legacy;
HWND focused_hwnd;
CHARRANGE textrange;
NCOMPRESSOR default_compressor;

View file

@ -10,6 +10,8 @@ Released on ?, 2013
\b Plugins in $\{NSISDIR\}\\Plugins have to be reserved with \c{ReserveFile /plugin}
\b MakeNSIS /NOTIFYHWND uses a (optional) new event name to abort compilation, see build.cpp/h for details.
\H{v2.46} 2.46
Released on December 6th, 2009

View file

@ -69,6 +69,11 @@ bool isSimpleChar(TCHAR ch)
} // end of anonymous namespace
namespace MakensisAPI {
const TCHAR* SigintEventNameFmt = _T("makensis win32 sigint event %u"); // %u is the notify HWND, this is to make sure we abort the correct instance
const TCHAR* SigintEventNameLegacy = _T("makensis win32 signint event"); // "sigNint" typo is part of the API now and cannot be changed
}
void CEXEBuild::define(const TCHAR *p, const TCHAR *v)
{
definedlist.add(p,v);
@ -2594,7 +2599,7 @@ int CEXEBuild::write_output(void)
{
tstring full_path = get_full_path(build_output_filename);
notify(MAKENSIS_NOTIFY_OUTPUT, full_path.c_str());
notify(MakensisAPI::NOTIFY_OUTPUT, full_path.c_str());
INFO_MSG(_T("\nOutput: \"%s\"\n"), full_path.c_str());
}
@ -3319,7 +3324,7 @@ void CEXEBuild::warning(const TCHAR *s, ...)
va_end(val);
m_warnings.add(buf,0);
notify(MAKENSIS_NOTIFY_WARNING,buf.GetPtr());
notify(MakensisAPI::NOTIFY_WARNING,buf.GetPtr());
if (display_warnings)
{
PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf.GetPtr());
@ -3338,7 +3343,7 @@ void CEXEBuild::warning_fl(const TCHAR *s, ...)
_stprintf(&buf[cchMsg],_T(" (%s:%u)"),curfilename,linecnt);
m_warnings.add(buf,0);
notify(MAKENSIS_NOTIFY_WARNING,buf.GetPtr());
notify(MakensisAPI::NOTIFY_WARNING,buf.GetPtr());
if (display_warnings)
{
PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf.GetPtr());
@ -3355,7 +3360,7 @@ void CEXEBuild::ERROR_MSG(const TCHAR *s, ...) const
buf.StrFmt(s,val);
va_end(val);
notify(MAKENSIS_NOTIFY_ERROR,buf.GetPtr());
notify(MakensisAPI::NOTIFY_ERROR,buf.GetPtr());
if (display_errors)
{
PrintColorFmtMsg_ERR(_T("%s"),buf.GetPtr());
@ -3403,7 +3408,7 @@ void CEXEBuild::print_warnings()
FlushOutputAndResetPrintColor();
}
void CEXEBuild::notify(notify_e code, const TCHAR *data) const
void CEXEBuild::notify(MakensisAPI::notify_e code, const TCHAR *data) const
{
#ifdef _WIN32
if (notify_hwnd)

View file

@ -70,12 +70,17 @@
#define TP_PG (TP_GLOBAL | TP_PAGEEX)
#define TP_ALL (TP_CODE | TP_PG)
enum notify_e {
MAKENSIS_NOTIFY_SCRIPT, // main nsi file(s)
MAKENSIS_NOTIFY_WARNING,
MAKENSIS_NOTIFY_ERROR,
MAKENSIS_NOTIFY_OUTPUT // generated .exe file
};
namespace MakensisAPI {
extern const TCHAR* SigintEventNameFmt;
extern const TCHAR* SigintEventNameLegacy;
enum notify_e {
NOTIFY_SCRIPT, // main nsi file(s)
NOTIFY_WARNING,
NOTIFY_ERROR,
NOTIFY_OUTPUT // generated .exe file
};
}
#define PAGE_CUSTOM 0
#define PAGE_LICENSE 1
@ -137,7 +142,7 @@ class CEXEBuild {
NStreamLineReader* curlinereader;
HWND notify_hwnd;
void notify(notify_e code, const TCHAR *data) const;
void notify(MakensisAPI::notify_e code, const TCHAR *data) const;
private:
int check_write_output_errors() const;

View file

@ -75,9 +75,17 @@ static void sigint(int sig)
}
#ifdef _WIN32
static DWORD WINAPI sigint_event_msg_handler(LPVOID)
static DWORD WINAPI sigint_event_msg_handler(LPVOID ThreadParam)
{
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("makensis win32 signint event"));
using namespace MakensisAPI;
HANDLE hEvent = 0;
if (ThreadParam)
{
TCHAR eventnamebuf[100];
wsprintf(eventnamebuf, SigintEventNameFmt, (HWND)ThreadParam);
hEvent = OpenEvent(SYNCHRONIZE, FALSE, eventnamebuf);
}
if (!hEvent) hEvent = OpenEvent(SYNCHRONIZE, FALSE, SigintEventNameLegacy);
if (hEvent)
{
@ -90,14 +98,15 @@ static DWORD WINAPI sigint_event_msg_handler(LPVOID)
}
#endif
static void init_signals()
static void init_signals(HWND notify_hwnd)
{
atexit(myatexit);
signal(SIGINT,sigint);
#ifdef _WIN32
DWORD id;
HANDLE hThread = CreateThread(NULL, 0, sigint_event_msg_handler, NULL, 0, &id);
HANDLE hThread = CreateThread(NULL, 0, sigint_event_msg_handler, (LPVOID)notify_hwnd, 0, &id);
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
if (hThread) CloseHandle(hThread);
#endif
}
@ -316,10 +325,30 @@ int _tmain(int argc, TCHAR **argv)
}
print_logo();
}
init_signals();
if (!g_output) g_output=stdout;
// Look for /NOTIFYHWND so we can init_signals()
const int orgargpos=argpos;
while (argpos < argc)
{
if (!_tcscmp(argv[argpos], _T("--"))) break;
if (!IS_OPT(argv[argpos]) || !_tcscmp(argv[argpos], _T("-"))) break;
if (!_tcsicmp(&argv[argpos][1],_T("NOTIFYHWND")))
{
if (!HasReqParam(argv, ++argpos, argc)) break;
#ifdef _WIN32
build.notify_hwnd=(HWND)_ttol(argv[argpos]);
if (!IsWindow(build.notify_hwnd)) build.notify_hwnd=0;
#else
build.warning(OPT_STR _T("NOTIFYHWND is disabled for non Win32 platforms."));
#endif
}
argpos++;
}
argpos=orgargpos;
init_signals(build.notify_hwnd);
while (argpos < argc)
{
if (!_tcscmp(argv[argpos], _T("--")))
@ -388,14 +417,7 @@ int _tmain(int argc, TCHAR **argv)
}
else if (!_tcsicmp(&argv[argpos][1],_T("NOTIFYHWND")))
{
if (!HasReqParam(argv, ++argpos, argc)) break;
#ifdef _WIN32
build.notify_hwnd=(HWND)_ttol(argv[argpos]);
if (!IsWindow(build.notify_hwnd))
build.notify_hwnd=0;
#else
build.warning(OPT_STR _T("NOTIFYHWND is disabled for non Win32 platforms."));
#endif
++argpos; // already parsed this
}
else if (!_tcsicmp(&argv[argpos][1],_T("HDRINFO")))
{
@ -515,7 +537,7 @@ int _tmain(int argc, TCHAR **argv)
build.set_default_output_filename(remove_file_extension(nsifile)+_T(".exe"));
}
build.notify(MAKENSIS_NOTIFY_SCRIPT,nsifile.c_str());
build.notify(MakensisAPI::NOTIFY_SCRIPT,nsifile.c_str());
TCHAR bufcpdisp[20];
strm.StreamEncoding().GetCPDisplayName(bufcpdisp);
build.INFO_MSG(_T("Processing script file: \"%s\" (%s)\n"),nsifile.c_str(),bufcpdisp);