mirror of
https://github.com/kennethreitz-archive/pyinstaller.git
synced 2026-06-05 23:50:17 +00:00
7500d720b6
https://svn.pyinstaller.python-hosting.com/branches/crypt ........ r465 | giovannibajo | 2008-05-21 15:30:21 +0200 (Wed, 21 May 2008) | 2 lines Ignore ".sconsign" ........ r532 | naufraghi | 2008-11-08 00:23:43 +0100 (Sat, 08 Nov 2008) | 1 line Add MacPython.org and MacPython.macports support ........ r533 | naufraghi | 2008-11-08 00:29:05 +0100 (Sat, 08 Nov 2008) | 1 line Run Configure continue only if the make is successful ........ r534 | naufraghi | 2008-11-08 00:32:00 +0100 (Sat, 08 Nov 2008) | 1 line Fix PyQt4 hooks ........ r535 | naufraghi | 2008-11-08 00:44:00 +0100 (Sat, 08 Nov 2008) | 1 line Do not compress any icon ........ r536 | naufraghi | 2008-11-08 00:51:07 +0100 (Sat, 08 Nov 2008) | 1 line Added support for multiple icons (by Giovanni) ........ r537 | naufraghi | 2008-11-08 00:55:17 +0100 (Sat, 08 Nov 2008) | 1 line Fix line endings ........ r538 | naufraghi | 2008-11-08 01:03:19 +0100 (Sat, 08 Nov 2008) | 1 line Pass wide-string command line through relaunch() to avoid losing information. (by Giovanni) ........ r539 | naufraghi | 2008-11-08 12:52:58 +0100 (Sat, 08 Nov 2008) | 1 line Line endings ........ r541 | naufraghi | 2008-11-09 10:08:19 +0100 (Sun, 09 Nov 2008) | 1 line Remove debug print ........ git-svn-id: http://svn.pyinstaller.org/trunk@545 8dd32b29-ccff-0310-8a9a-9233e24343b1
185 lines
5.5 KiB
C
185 lines
5.5 KiB
C
/*
|
|
* Bootloader for a packed executable.
|
|
* Copyright (C) 2005, Giovanni Bajo
|
|
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* In addition to the permissions in the GNU General Public License, the
|
|
* authors give you unlimited permission to link or embed the compiled
|
|
* version of this file into combinations with other programs, and to
|
|
* distribute those combinations without any restriction coming from the
|
|
* use of this file. (The General Public License restrictions do apply in
|
|
* other respects; for example, they cover modification of the file, and
|
|
* distribution when not linked into a combine executable.)
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
#include "launch.h"
|
|
#include <windows.h>
|
|
#include <commctrl.h> // InitCommonControls
|
|
#include <signal.h>
|
|
|
|
int relaunch(LPWSTR thisfile, char *workpath)
|
|
{
|
|
char envvar[_MAX_PATH + 12];
|
|
SECURITY_ATTRIBUTES sa;
|
|
STARTUPINFOW si;
|
|
PROCESS_INFORMATION pi;
|
|
int rc = 0;
|
|
|
|
// the parent process should ignore all signals it can
|
|
signal(SIGABRT, SIG_IGN);
|
|
signal(SIGINT, SIG_IGN);
|
|
signal(SIGTERM, SIG_IGN);
|
|
signal(SIGBREAK, SIG_IGN);
|
|
|
|
VS("Setting up to run child\n");
|
|
sa.nLength = sizeof(sa);
|
|
sa.lpSecurityDescriptor = NULL;
|
|
sa.bInheritHandle = TRUE;
|
|
GetStartupInfoW(&si);
|
|
si.lpReserved = NULL;
|
|
si.lpDesktop = NULL;
|
|
si.lpTitle = NULL;
|
|
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
|
si.wShowWindow = SW_NORMAL;
|
|
si.hStdInput = (void*)_get_osfhandle(fileno(stdin));
|
|
si.hStdOutput = (void*)_get_osfhandle(fileno(stdout));
|
|
si.hStdError = (void*)_get_osfhandle(fileno(stderr));
|
|
/* tell pass 2 where we extracted to */
|
|
VS("Setting magic environment var\n");
|
|
strcpy(envvar, "_MEIPASS2=");
|
|
strcat(envvar, workpath);
|
|
_putenv(envvar);
|
|
VS("Creating child process\n");
|
|
// Use wide-string version to make sure that the command line is
|
|
// passed properly: in fact, the locale-specific version (GetCommandLineA())
|
|
// might not be able to decode it fully and thus contain replacement
|
|
// characters ("?").
|
|
// This is actually immaterial right now because Python itself has a bug
|
|
// and uses only the locale-specific version which is corrupted; but at
|
|
// least it's not here that we lose information.
|
|
if (CreateProcessW(
|
|
thisfile, // pointer to name of executable module
|
|
GetCommandLineW(), // pointer to command line string
|
|
&sa, // pointer to process security attributes
|
|
NULL, // pointer to thread security attributes
|
|
TRUE, // handle inheritance flag
|
|
0, // creation flags
|
|
NULL, // pointer to new environment block
|
|
NULL, // pointer to current directory name
|
|
&si, // pointer to STARTUPINFO
|
|
&pi // pointer to PROCESS_INFORMATION
|
|
)) {
|
|
VS("Waiting for child process to finish...\n");
|
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
|
GetExitCodeProcess(pi.hProcess, (unsigned long *)&rc);
|
|
}
|
|
else {
|
|
FATALERROR("Error creating child process!\n");
|
|
rc = -1;
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
|
|
#ifdef _CONSOLE
|
|
int main(int argc, char* argv[])
|
|
#else
|
|
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
LPSTR lpCmdLine, int nCmdShow )
|
|
#endif
|
|
{
|
|
char here[_MAX_PATH + 1];
|
|
char thisfile[_MAX_PATH + 1];
|
|
WCHAR thisfilew[_MAX_PATH + 1];
|
|
char pkgfile[_MAX_PATH + 1];
|
|
int rc = 0;
|
|
char *workpath = NULL;
|
|
char *p;
|
|
int len;
|
|
#ifndef _CONSOLE
|
|
int argc = __argc;
|
|
char **argv = __argv;
|
|
#endif
|
|
|
|
// Initialize common controls (needed to link with commctrl32.dll and
|
|
// obtain native XP look & feel).
|
|
InitCommonControls();
|
|
|
|
// fill in thisfile
|
|
if (!GetModuleFileNameA(NULL, thisfile, _MAX_PATH)) {
|
|
FATALERROR("System error - unable to load!");
|
|
return -1;
|
|
}
|
|
if (!GetModuleFileNameW(NULL, thisfilew, _MAX_PATH)) {
|
|
FATALERROR("System error - unable to load!");
|
|
return -1;
|
|
}
|
|
|
|
p = thisfile+strlen(thisfile) - 4;
|
|
if (strnicmp(p, ".exe", 4) != 0)
|
|
strcat(thisfile, ".exe");
|
|
|
|
// fill in here (directory of thisfile)
|
|
//GetModuleFileName returns an absolute path
|
|
strcpy(here, thisfile);
|
|
for (p=here+strlen(here); *p != '\\' && p >= here+2; --p);
|
|
*++p = '\0';
|
|
len = p - here;
|
|
|
|
strcpy(pkgfile, thisfile);
|
|
strcpy(pkgfile+strlen(pkgfile)-3, "pkg");
|
|
|
|
workpath = getenv( "_MEIPASS2" );
|
|
rc = init(here, &pkgfile[len], workpath);
|
|
if (rc) {
|
|
rc = init(here, &thisfile[len], workpath);
|
|
} else {
|
|
VS("Found separate PKG: %s\n", pkgfile);
|
|
}
|
|
if (rc) {
|
|
return rc;
|
|
}
|
|
if (workpath) {
|
|
// we're the "child" process
|
|
rc = doIt(argc, argv);
|
|
if (rc) {
|
|
return rc;
|
|
}
|
|
finalizePython();
|
|
}
|
|
else {
|
|
if (extractBinaries(&workpath)) {
|
|
VS("Error extracting binaries\n");
|
|
return -1;
|
|
}
|
|
// if workpath got set to non-NULL, we've extracted stuff
|
|
if (workpath) {
|
|
// run the "child" process, then clean up
|
|
rc = relaunch(thisfilew, workpath);
|
|
}
|
|
else {
|
|
// no "child" process necessary
|
|
rc = doIt(argc, argv);
|
|
if (rc) {
|
|
return rc;
|
|
}
|
|
finalizePython();
|
|
}
|
|
cleanUp();
|
|
}
|
|
return rc;
|
|
}
|