mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 11:23:31 +00:00 
			
		
		
		
	Patch #892660 from Mark Hammond, for distutils bdist_wininst command.
install.c: support for a 'pre-install-script', run before anything has been installed. Provides a 'message_box' module function for use by either the pre-install or post-install scripts. bdist_wininst.py: support for pre-install script. Typo (build->built), fixes so that --target-version can still work, even when the distribution has extension modules - in this case, we insist on --skip-build, as we still can't actually build other versions.
This commit is contained in:
		
							parent
							
								
									bb99058898
								
							
						
					
					
						commit
						a19cdad6dc
					
				
					 2 changed files with 206 additions and 53 deletions
				
			
		| 
						 | 
					@ -43,6 +43,10 @@ class bdist_wininst (Command):
 | 
				
			||||||
                    ('install-script=', None,
 | 
					                    ('install-script=', None,
 | 
				
			||||||
                     "basename of installation script to be run after"
 | 
					                     "basename of installation script to be run after"
 | 
				
			||||||
                     "installation or before deinstallation"),
 | 
					                     "installation or before deinstallation"),
 | 
				
			||||||
 | 
					                    ('pre-install-script=', None,
 | 
				
			||||||
 | 
					                     "Fully qualified filename of a script to be run before "
 | 
				
			||||||
 | 
					                     "any files are installed.  This script need not be in the "
 | 
				
			||||||
 | 
					                     "distribution"),
 | 
				
			||||||
                   ]
 | 
					                   ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
 | 
					    boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
 | 
				
			||||||
| 
						 | 
					@ -59,6 +63,7 @@ class bdist_wininst (Command):
 | 
				
			||||||
        self.title = None
 | 
					        self.title = None
 | 
				
			||||||
        self.skip_build = 0
 | 
					        self.skip_build = 0
 | 
				
			||||||
        self.install_script = None
 | 
					        self.install_script = None
 | 
				
			||||||
 | 
					        self.pre_install_script = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # initialize_options()
 | 
					    # initialize_options()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,11 +74,12 @@ class bdist_wininst (Command):
 | 
				
			||||||
            self.bdist_dir = os.path.join(bdist_base, 'wininst')
 | 
					            self.bdist_dir = os.path.join(bdist_base, 'wininst')
 | 
				
			||||||
        if not self.target_version:
 | 
					        if not self.target_version:
 | 
				
			||||||
            self.target_version = ""
 | 
					            self.target_version = ""
 | 
				
			||||||
        if self.distribution.has_ext_modules():
 | 
					        if not self.skip_build and self.distribution.has_ext_modules():
 | 
				
			||||||
            short_version = get_python_version()
 | 
					            short_version = get_python_version()
 | 
				
			||||||
            if self.target_version and self.target_version != short_version:
 | 
					            if self.target_version and self.target_version != short_version:
 | 
				
			||||||
                raise DistutilsOptionError, \
 | 
					                raise DistutilsOptionError, \
 | 
				
			||||||
                      "target version can only be" + short_version
 | 
					                      "target version can only be %s, or the '--skip_build'" \
 | 
				
			||||||
 | 
					                      " option must be specified" % (short_version,)
 | 
				
			||||||
            self.target_version = short_version
 | 
					            self.target_version = short_version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
 | 
					        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
 | 
				
			||||||
| 
						 | 
					@ -110,6 +116,21 @@ class bdist_wininst (Command):
 | 
				
			||||||
        install_lib.compile = 0
 | 
					        install_lib.compile = 0
 | 
				
			||||||
        install_lib.optimize = 0
 | 
					        install_lib.optimize = 0
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        # If we are building an installer for a Python version other
 | 
				
			||||||
 | 
					        # than the one we are currently running, then we need to ensure
 | 
				
			||||||
 | 
					        # our build_lib reflects the other Python version rather than ours.
 | 
				
			||||||
 | 
					        # Note that for target_version!=sys.version, we must have skipped the
 | 
				
			||||||
 | 
					        # build step, so there is no issue with enforcing the build of this
 | 
				
			||||||
 | 
					        # version.
 | 
				
			||||||
 | 
					        target_version = self.target_version
 | 
				
			||||||
 | 
					        if not target_version:
 | 
				
			||||||
 | 
					            assert self.skip_build, "Should have already checked this"
 | 
				
			||||||
 | 
					            target_version = sys.version[0:3]
 | 
				
			||||||
 | 
					        plat_specifier = ".%s-%s" % (get_platform(), target_version)
 | 
				
			||||||
 | 
					        build = self.get_finalized_command('build')
 | 
				
			||||||
 | 
					        build.build_lib = os.path.join(build.build_base,
 | 
				
			||||||
 | 
					                                       'lib' + plat_specifier)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Use a custom scheme for the zip-file, because we have to decide
 | 
					        # Use a custom scheme for the zip-file, because we have to decide
 | 
				
			||||||
        # at installation time which scheme to use.
 | 
					        # at installation time which scheme to use.
 | 
				
			||||||
        for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
 | 
					        for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
 | 
				
			||||||
| 
						 | 
					@ -187,7 +208,7 @@ class bdist_wininst (Command):
 | 
				
			||||||
        lines.append("title=%s" % repr(title)[1:-1])
 | 
					        lines.append("title=%s" % repr(title)[1:-1])
 | 
				
			||||||
        import time
 | 
					        import time
 | 
				
			||||||
        import distutils
 | 
					        import distutils
 | 
				
			||||||
        build_info = "Build %s with distutils-%s" % \
 | 
					        build_info = "Built %s with distutils-%s" % \
 | 
				
			||||||
                     (time.ctime(time.time()), distutils.__version__)
 | 
					                     (time.ctime(time.time()), distutils.__version__)
 | 
				
			||||||
        lines.append("build_info=%s" % build_info)
 | 
					        lines.append("build_info=%s" % build_info)
 | 
				
			||||||
        return string.join(lines, "\n")
 | 
					        return string.join(lines, "\n")
 | 
				
			||||||
| 
						 | 
					@ -223,6 +244,11 @@ class bdist_wininst (Command):
 | 
				
			||||||
        if bitmap:
 | 
					        if bitmap:
 | 
				
			||||||
            file.write(bitmapdata)
 | 
					            file.write(bitmapdata)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Append the pre-install script
 | 
				
			||||||
 | 
					        cfgdata = cfgdata + "\0"
 | 
				
			||||||
 | 
					        if self.pre_install_script:
 | 
				
			||||||
 | 
					            script_data = open(self.pre_install_script, "r").read()
 | 
				
			||||||
 | 
					            cfgdata = cfgdata + script_data + "\n\0"
 | 
				
			||||||
        file.write(cfgdata)
 | 
					        file.write(cfgdata)
 | 
				
			||||||
        header = struct.pack("<iii",
 | 
					        header = struct.pack("<iii",
 | 
				
			||||||
                             0x1234567A,       # tag
 | 
					                             0x1234567A,       # tag
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,7 @@ char build_info[80];		/* [Setup] build_info=, distutils version
 | 
				
			||||||
char meta_name[80];		/* package name without version like
 | 
					char meta_name[80];		/* package name without version like
 | 
				
			||||||
				   'Distutils' */
 | 
									   'Distutils' */
 | 
				
			||||||
char install_script[MAX_PATH];
 | 
					char install_script[MAX_PATH];
 | 
				
			||||||
 | 
					char *pre_install_script; /* run before we install a single file */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int py_major, py_minor;		/* Python version selected for installation */
 | 
					int py_major, py_minor;		/* Python version selected for installation */
 | 
				
			||||||
| 
						 | 
					@ -129,6 +130,7 @@ char pythondll[MAX_PATH];
 | 
				
			||||||
BOOL pyc_compile, pyo_compile;
 | 
					BOOL pyc_compile, pyo_compile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BOOL success;			/* Installation successfull? */
 | 
					BOOL success;			/* Installation successfull? */
 | 
				
			||||||
 | 
					char *failure_reason = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HANDLE hBitmap;
 | 
					HANDLE hBitmap;
 | 
				
			||||||
char *bitmap_bytes;
 | 
					char *bitmap_bytes;
 | 
				
			||||||
| 
						 | 
					@ -206,6 +208,20 @@ static struct tagFile {
 | 
				
			||||||
	struct tagFile *next;
 | 
						struct tagFile *next;
 | 
				
			||||||
} *file_list = NULL;
 | 
					} *file_list = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void set_failure_reason(char *reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (failure_reason)
 | 
				
			||||||
 | 
						free(failure_reason);
 | 
				
			||||||
 | 
					    failure_reason = strdup(reason);
 | 
				
			||||||
 | 
					    success = FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static char *get_failure_reason()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!failure_reason)
 | 
				
			||||||
 | 
						return "Installation failed.";
 | 
				
			||||||
 | 
					    return failure_reason;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void add_to_filelist(char *path)
 | 
					static void add_to_filelist(char *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tagFile *p;
 | 
						struct tagFile *p;
 | 
				
			||||||
| 
						 | 
					@ -532,7 +548,7 @@ static PyObject *CreateShortcut(PyObject *self, PyObject *args)
 | 
				
			||||||
	hr = pPf->lpVtbl->Save(pPf, wszFilename, TRUE);
 | 
						hr = pPf->lpVtbl->Save(pPf, wszFilename, TRUE);
 | 
				
			||||||
	if (FAILED(hr)) {
 | 
						if (FAILED(hr)) {
 | 
				
			||||||
		g_PyErr_Format(g_PyExc_OSError,
 | 
							g_PyErr_Format(g_PyExc_OSError,
 | 
				
			||||||
			       "Save() failed, error 0x%x", hr);
 | 
								       "Failed to create shortcut '%s' - error 0x%x", filename, hr);
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -553,6 +569,17 @@ static PyObject *CreateShortcut(PyObject *self, PyObject *args)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *PyMessageBox(PyObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
						char *text, *caption;
 | 
				
			||||||
 | 
						int flags;
 | 
				
			||||||
 | 
						if (!g_PyArg_ParseTuple(args, "ssi", &text, &caption, &flags))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						rc = MessageBox(GetFocus(), text, caption, flags);
 | 
				
			||||||
 | 
						return g_Py_BuildValue("i", rc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define METH_VARARGS 0x0001
 | 
					#define METH_VARARGS 0x0001
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyMethodDef meth[] = {
 | 
					PyMethodDef meth[] = {
 | 
				
			||||||
| 
						 | 
					@ -560,8 +587,42 @@ PyMethodDef meth[] = {
 | 
				
			||||||
	{"get_special_folder_path", GetSpecialFolderPath, METH_VARARGS, NULL},
 | 
						{"get_special_folder_path", GetSpecialFolderPath, METH_VARARGS, NULL},
 | 
				
			||||||
	{"file_created", FileCreated, METH_VARARGS, NULL},
 | 
						{"file_created", FileCreated, METH_VARARGS, NULL},
 | 
				
			||||||
	{"directory_created", DirectoryCreated, METH_VARARGS, NULL},
 | 
						{"directory_created", DirectoryCreated, METH_VARARGS, NULL},
 | 
				
			||||||
 | 
						{"message_box", PyMessageBox, METH_VARARGS, NULL},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int prepare_script_environment(HINSTANCE hPython)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *mod;
 | 
				
			||||||
 | 
						DECLPROC(hPython, PyObject *, PyImport_ImportModule, (char *));
 | 
				
			||||||
 | 
						DECLPROC(hPython, int, PyObject_SetAttrString, (PyObject *, char *, PyObject *));
 | 
				
			||||||
 | 
						DECLPROC(hPython, PyObject *, PyObject_GetAttrString, (PyObject *, char *));
 | 
				
			||||||
 | 
						DECLPROC(hPython, PyObject *, PyCFunction_New, (PyMethodDef *, PyObject *));
 | 
				
			||||||
 | 
						DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
 | 
				
			||||||
 | 
						DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
 | 
				
			||||||
 | 
						DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
 | 
				
			||||||
 | 
						if (!PyImport_ImportModule || !PyObject_GetAttrString || 
 | 
				
			||||||
 | 
						    !PyObject_SetAttrString || !PyCFunction_New)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mod = PyImport_ImportModule("__builtin__");
 | 
				
			||||||
 | 
						if (mod) {
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
							g_PyExc_ValueError = PyObject_GetAttrString(mod, "ValueError");
 | 
				
			||||||
 | 
							g_PyExc_OSError = PyObject_GetAttrString(mod, "OSError");
 | 
				
			||||||
 | 
							for (i = 0; i < DIM(meth); ++i) {
 | 
				
			||||||
 | 
								PyObject_SetAttrString(mod, meth[i].ml_name,
 | 
				
			||||||
 | 
										       PyCFunction_New(&meth[i], NULL));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_Py_BuildValue = Py_BuildValue;
 | 
				
			||||||
 | 
						g_PyArg_ParseTuple = PyArg_ParseTuple;
 | 
				
			||||||
 | 
						g_PyErr_Format = PyErr_Format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This function returns one of the following error codes:
 | 
					 * This function returns one of the following error codes:
 | 
				
			||||||
 * 1 if the Python-dll does not export the functions we need
 | 
					 * 1 if the Python-dll does not export the functions we need
 | 
				
			||||||
| 
						 | 
					@ -579,19 +640,12 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
 | 
				
			||||||
	DECLPROC(hPython, int, PySys_SetArgv, (int, char **));
 | 
						DECLPROC(hPython, int, PySys_SetArgv, (int, char **));
 | 
				
			||||||
	DECLPROC(hPython, int, PyRun_SimpleFile, (FILE *, char *));
 | 
						DECLPROC(hPython, int, PyRun_SimpleFile, (FILE *, char *));
 | 
				
			||||||
	DECLPROC(hPython, void, Py_Finalize, (void));
 | 
						DECLPROC(hPython, void, Py_Finalize, (void));
 | 
				
			||||||
	DECLPROC(hPython, PyObject *, PyImport_ImportModule, (char *));
 | 
					 | 
				
			||||||
	DECLPROC(hPython, int, PyObject_SetAttrString,
 | 
					 | 
				
			||||||
		 (PyObject *, char *, PyObject *));
 | 
					 | 
				
			||||||
	DECLPROC(hPython, PyObject *, PyObject_GetAttrString,
 | 
					 | 
				
			||||||
		 (PyObject *, char *));
 | 
					 | 
				
			||||||
	DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
 | 
						DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
 | 
				
			||||||
	DECLPROC(hPython, PyObject *, PyCFunction_New,
 | 
						DECLPROC(hPython, PyObject *, PyCFunction_New,
 | 
				
			||||||
		 (PyMethodDef *, PyObject *));
 | 
							 (PyMethodDef *, PyObject *));
 | 
				
			||||||
	DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
 | 
						DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
 | 
				
			||||||
	DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
 | 
						DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PyObject *mod;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int result = 0;
 | 
						int result = 0;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -599,20 +653,12 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
 | 
				
			||||||
	    || !PyRun_SimpleFile || !Py_Finalize)
 | 
						    || !PyRun_SimpleFile || !Py_Finalize)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (!PyImport_ImportModule || !PyObject_SetAttrString
 | 
						if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format)
 | 
				
			||||||
	    || !Py_BuildValue)
 | 
					 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!PyCFunction_New || !PyArg_ParseTuple || !PyErr_Format)
 | 
						if (!PyCFunction_New || !PyArg_ParseTuple || !PyErr_Format)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!PyObject_GetAttrString)
 | 
					 | 
				
			||||||
		return 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	g_Py_BuildValue = Py_BuildValue;
 | 
					 | 
				
			||||||
	g_PyArg_ParseTuple = PyArg_ParseTuple;
 | 
					 | 
				
			||||||
	g_PyErr_Format = PyErr_Format;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pathname == NULL || pathname[0] == '\0')
 | 
						if (pathname == NULL || pathname[0] == '\0')
 | 
				
			||||||
		return 2;
 | 
							return 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -627,19 +673,7 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	Py_Initialize();
 | 
						Py_Initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mod = PyImport_ImportModule("__builtin__");
 | 
						prepare_script_environment(hPython);
 | 
				
			||||||
	if (mod) {
 | 
					 | 
				
			||||||
		int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		g_PyExc_ValueError = PyObject_GetAttrString(mod,
 | 
					 | 
				
			||||||
							    "ValueError");
 | 
					 | 
				
			||||||
		g_PyExc_OSError = PyObject_GetAttrString(mod, "OSError");
 | 
					 | 
				
			||||||
		for (i = 0; i < DIM(meth); ++i) {
 | 
					 | 
				
			||||||
			PyObject_SetAttrString(mod, meth[i].ml_name,
 | 
					 | 
				
			||||||
					       PyCFunction_New(&meth[i], NULL));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PySys_SetArgv(argc, argv);
 | 
						PySys_SetArgv(argc, argv);
 | 
				
			||||||
	result = PyRun_SimpleFile(fp, pathname);
 | 
						result = PyRun_SimpleFile(fp, pathname);
 | 
				
			||||||
	Py_Finalize();
 | 
						Py_Finalize();
 | 
				
			||||||
| 
						 | 
					@ -649,6 +683,77 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int do_run_simple_script(HINSTANCE hPython, char *script)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
						DECLPROC(hPython, void, Py_Initialize, (void));
 | 
				
			||||||
 | 
						DECLPROC(hPython, void, Py_SetProgramName, (char *));
 | 
				
			||||||
 | 
						DECLPROC(hPython, void, Py_Finalize, (void));
 | 
				
			||||||
 | 
						DECLPROC(hPython, int, PyRun_SimpleString, (char *));
 | 
				
			||||||
 | 
						DECLPROC(hPython, void, PyErr_Print, (void));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!Py_Initialize || !Py_SetProgramName || !Py_Finalize || 
 | 
				
			||||||
 | 
						    !PyRun_SimpleString || !PyErr_Print)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Py_SetProgramName(modulename);
 | 
				
			||||||
 | 
						Py_Initialize();
 | 
				
			||||||
 | 
						prepare_script_environment(hPython);
 | 
				
			||||||
 | 
						rc = PyRun_SimpleString(script);
 | 
				
			||||||
 | 
						if (rc)
 | 
				
			||||||
 | 
							PyErr_Print();
 | 
				
			||||||
 | 
						Py_Finalize();
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int run_simple_script(char *script)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
						char *tempname;
 | 
				
			||||||
 | 
						HINSTANCE hPython;
 | 
				
			||||||
 | 
						tempname = tmpnam(NULL);
 | 
				
			||||||
 | 
						freopen(tempname, "a", stderr);
 | 
				
			||||||
 | 
						freopen(tempname, "a", stdout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hPython = LoadLibrary (pythondll);
 | 
				
			||||||
 | 
						if (!hPython) {
 | 
				
			||||||
 | 
							set_failure_reason("Can't load Python for pre-install script");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rc = do_run_simple_script(hPython, script);
 | 
				
			||||||
 | 
						FreeLibrary(hPython);
 | 
				
			||||||
 | 
						fflush(stderr);
 | 
				
			||||||
 | 
						fflush(stdout);
 | 
				
			||||||
 | 
						/* We only care about the output when we fail.  If the script works
 | 
				
			||||||
 | 
						   OK, then we discard it
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						if (rc) {
 | 
				
			||||||
 | 
							int err_buf_size;
 | 
				
			||||||
 | 
							char *err_buf;
 | 
				
			||||||
 | 
							const char *prefix = "Running the pre-installation script failed\r\n";
 | 
				
			||||||
 | 
							int prefix_len = strlen(prefix);
 | 
				
			||||||
 | 
							FILE *fp = fopen(tempname, "rb");
 | 
				
			||||||
 | 
							fseek(fp, 0, SEEK_END);
 | 
				
			||||||
 | 
							err_buf_size = ftell(fp);
 | 
				
			||||||
 | 
							fseek(fp, 0, SEEK_SET);
 | 
				
			||||||
 | 
							err_buf = malloc(prefix_len + err_buf_size + 1);
 | 
				
			||||||
 | 
							if (err_buf) {
 | 
				
			||||||
 | 
								int n;
 | 
				
			||||||
 | 
								strcpy(err_buf, prefix);
 | 
				
			||||||
 | 
								n = fread(err_buf+prefix_len, 1, err_buf_size, fp);
 | 
				
			||||||
 | 
								err_buf[prefix_len+n] = '\0';
 | 
				
			||||||
 | 
								fclose(fp);
 | 
				
			||||||
 | 
								set_failure_reason(err_buf);
 | 
				
			||||||
 | 
								free(err_buf);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								set_failure_reason("Out of memory!");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						remove(tempname);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static BOOL SystemError(int error, char *msg)
 | 
					static BOOL SystemError(int error, char *msg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char Buffer[1024];
 | 
						char Buffer[1024];
 | 
				
			||||||
| 
						 | 
					@ -811,7 +916,11 @@ static void create_bitmap(HWND hwnd)
 | 
				
			||||||
	ReleaseDC(hwnd, hdc);
 | 
						ReleaseDC(hwnd, hdc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *ExtractIniFile(char *data, DWORD size, int *pexe_size)
 | 
					/* Extract everything we need to begin the installation.  Currently this
 | 
				
			||||||
 | 
					   is the INI filename with install data, and the raw pre-install script
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					static BOOL ExtractInstallData(char *data, DWORD size, int *pexe_size,
 | 
				
			||||||
 | 
								       char **out_ini_file, char **out_preinstall_script)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* read the end of central directory record */
 | 
						/* read the end of central directory record */
 | 
				
			||||||
	struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
 | 
						struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
 | 
				
			||||||
| 
						 | 
					@ -828,12 +937,15 @@ static char *ExtractIniFile(char *data, DWORD size, int *pexe_size)
 | 
				
			||||||
	char *ini_file;
 | 
						char *ini_file;
 | 
				
			||||||
	char tempdir[MAX_PATH];
 | 
						char tempdir[MAX_PATH];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ensure that if we fail, we don't have garbage out pointers */
 | 
				
			||||||
 | 
						*out_ini_file = *out_preinstall_script = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pe->tag != 0x06054b50) {
 | 
						if (pe->tag != 0x06054b50) {
 | 
				
			||||||
		return NULL;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pmd->tag != 0x1234567A || ofs < 0) {
 | 
						if (pmd->tag != 0x1234567A || ofs < 0) {
 | 
				
			||||||
		return NULL;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pmd->bitmap_size) {
 | 
						if (pmd->bitmap_size) {
 | 
				
			||||||
| 
						 | 
					@ -846,21 +958,26 @@ static char *ExtractIniFile(char *data, DWORD size, int *pexe_size)
 | 
				
			||||||
	src = ((char *)pmd) - pmd->uncomp_size;
 | 
						src = ((char *)pmd) - pmd->uncomp_size;
 | 
				
			||||||
	ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */
 | 
						ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */
 | 
				
			||||||
	if (!ini_file)
 | 
						if (!ini_file)
 | 
				
			||||||
		return NULL;
 | 
							return FALSE;
 | 
				
			||||||
	if (!GetTempPath(sizeof(tempdir), tempdir)
 | 
						if (!GetTempPath(sizeof(tempdir), tempdir)
 | 
				
			||||||
	    || !GetTempFileName(tempdir, "~du", 0, ini_file)) {
 | 
						    || !GetTempFileName(tempdir, "~du", 0, ini_file)) {
 | 
				
			||||||
		SystemError(GetLastError(),
 | 
							SystemError(GetLastError(),
 | 
				
			||||||
			     "Could not create temporary file");
 | 
								     "Could not create temporary file");
 | 
				
			||||||
		return NULL;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
	dst = map_new_file(CREATE_ALWAYS, ini_file, NULL, pmd->uncomp_size,
 | 
						dst = map_new_file(CREATE_ALWAYS, ini_file, NULL, pmd->uncomp_size,
 | 
				
			||||||
			    0, 0, NULL/*notify*/);
 | 
								    0, 0, NULL/*notify*/);
 | 
				
			||||||
	if (!dst)
 | 
						if (!dst)
 | 
				
			||||||
		return NULL;
 | 
							return FALSE;
 | 
				
			||||||
	memcpy(dst, src, pmd->uncomp_size);
 | 
						/* Up to the first \0 is the INI file data. */
 | 
				
			||||||
 | 
						strncpy(dst, src, pmd->uncomp_size);
 | 
				
			||||||
 | 
						src += strlen(dst) + 1;
 | 
				
			||||||
 | 
						/* Up to next \0 is the pre-install script */
 | 
				
			||||||
 | 
						*out_preinstall_script = strdup(src);
 | 
				
			||||||
 | 
						*out_ini_file = ini_file;
 | 
				
			||||||
	UnmapViewOfFile(dst);
 | 
						UnmapViewOfFile(dst);
 | 
				
			||||||
	return ini_file;
 | 
						return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void PumpMessages(void)
 | 
					static void PumpMessages(void)
 | 
				
			||||||
| 
						 | 
					@ -1354,7 +1471,7 @@ SelectPythonDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
								 &py_major, &py_minor);
 | 
													 &py_major, &py_minor);
 | 
				
			||||||
						if (result == 2)
 | 
											if (result == 2)
 | 
				
			||||||
#ifdef _DEBUG
 | 
					#ifdef _DEBUG
 | 
				
			||||||
							wsprintf(pythondll, "c:\\python22\\PCBuild\\python%d%d_d.dll",
 | 
												wsprintf(pythondll, "python%d%d_d.dll",
 | 
				
			||||||
								  py_major, py_minor);
 | 
													  py_major, py_minor);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
						wsprintf(pythondll, "python%d%d.dll",
 | 
											wsprintf(pythondll, "python%d%d.dll",
 | 
				
			||||||
| 
						 | 
					@ -1542,6 +1659,7 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
			  "Click Cancel to exit the wizard.",
 | 
								  "Click Cancel to exit the wizard.",
 | 
				
			||||||
			  meta_name);
 | 
								  meta_name);
 | 
				
			||||||
		SetDlgItemText(hwnd, IDC_TITLE, Buffer);
 | 
							SetDlgItemText(hwnd, IDC_TITLE, Buffer);
 | 
				
			||||||
 | 
							SetDlgItemText(hwnd, IDC_INFO, "Ready to install");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WM_NUMFILES:
 | 
						case WM_NUMFILES:
 | 
				
			||||||
| 
						 | 
					@ -1571,6 +1689,7 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
		case PSN_WIZNEXT:
 | 
							case PSN_WIZNEXT:
 | 
				
			||||||
			/* Handle a Next button click here */
 | 
								/* Handle a Next button click here */
 | 
				
			||||||
			hDialog = hwnd;
 | 
								hDialog = hwnd;
 | 
				
			||||||
 | 
								success = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Make sure the installation directory name ends in a */
 | 
								/* Make sure the installation directory name ends in a */
 | 
				
			||||||
			/* backslash */
 | 
								/* backslash */
 | 
				
			||||||
| 
						 | 
					@ -1602,14 +1721,23 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
			scheme = GetScheme(py_major, py_minor);
 | 
								scheme = GetScheme(py_major, py_minor);
 | 
				
			||||||
 | 
								/* Run the pre-install script. */
 | 
				
			||||||
 | 
								if (pre_install_script && *pre_install_script) {
 | 
				
			||||||
 | 
									SetDlgItemText (hwnd, IDC_TITLE,
 | 
				
			||||||
 | 
											"Running pre-installation script");
 | 
				
			||||||
 | 
									run_simple_script(pre_install_script);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!success) {
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			/* Extract all files from the archive */
 | 
								/* Extract all files from the archive */
 | 
				
			||||||
			SetDlgItemText(hwnd, IDC_TITLE, "Installing files...");
 | 
								SetDlgItemText(hwnd, IDC_TITLE, "Installing files...");
 | 
				
			||||||
			success = unzip_archive(scheme,
 | 
								if (!unzip_archive (scheme,
 | 
				
			||||||
						 python_dir, arc_data,
 | 
										    python_dir, arc_data,
 | 
				
			||||||
						 arc_size, notify);
 | 
										    arc_size, notify))
 | 
				
			||||||
 | 
									set_failure_reason("Failed to unzip installation files");
 | 
				
			||||||
			/* Compile the py-files */
 | 
								/* Compile the py-files */
 | 
				
			||||||
			if (pyc_compile) {
 | 
								if (success && pyc_compile) {
 | 
				
			||||||
				int errors;
 | 
									int errors;
 | 
				
			||||||
				HINSTANCE hPython;
 | 
									HINSTANCE hPython;
 | 
				
			||||||
				SetDlgItemText(hwnd, IDC_TITLE,
 | 
									SetDlgItemText(hwnd, IDC_TITLE,
 | 
				
			||||||
| 
						 | 
					@ -1628,7 +1756,7 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
				 * confuse the user.
 | 
									 * confuse the user.
 | 
				
			||||||
				 */
 | 
									 */
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (pyo_compile) {
 | 
								if (success && pyo_compile) {
 | 
				
			||||||
				int errors;
 | 
									int errors;
 | 
				
			||||||
				HINSTANCE hPython;
 | 
									HINSTANCE hPython;
 | 
				
			||||||
				SetDlgItemText(hwnd, IDC_TITLE,
 | 
									SetDlgItemText(hwnd, IDC_TITLE,
 | 
				
			||||||
| 
						 | 
					@ -1668,7 +1796,7 @@ FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
			SendDlgItemMessage(hwnd, IDC_BITMAP, STM_SETIMAGE,
 | 
								SendDlgItemMessage(hwnd, IDC_BITMAP, STM_SETIMAGE,
 | 
				
			||||||
					   IMAGE_BITMAP, (LPARAM)hBitmap);
 | 
										   IMAGE_BITMAP, (LPARAM)hBitmap);
 | 
				
			||||||
		if (!success)
 | 
							if (!success)
 | 
				
			||||||
			SetDlgItemText(hwnd, IDC_INFO, "Installation failed.");
 | 
								SetDlgItemText(hwnd, IDC_INFO, get_failure_reason());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* async delay: will show the dialog box completely before
 | 
							/* async delay: will show the dialog box completely before
 | 
				
			||||||
		   the install_script is started */
 | 
							   the install_script is started */
 | 
				
			||||||
| 
						 | 
					@ -1677,7 +1805,7 @@ FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WM_USER:
 | 
						case WM_USER:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (install_script && install_script[0]) {
 | 
							if (success && install_script && install_script[0]) {
 | 
				
			||||||
			char fname[MAX_PATH];
 | 
								char fname[MAX_PATH];
 | 
				
			||||||
			char *tempname;
 | 
								char *tempname;
 | 
				
			||||||
			FILE *fp;
 | 
								FILE *fp;
 | 
				
			||||||
| 
						 | 
					@ -2271,9 +2399,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Try to extract the configuration data into a temporary file */
 | 
						/* Try to extract the configuration data into a temporary file */
 | 
				
			||||||
	ini_file = ExtractIniFile(arc_data, arc_size, &exe_size);
 | 
						if (ExtractInstallData(arc_data, arc_size, &exe_size,
 | 
				
			||||||
 | 
								       &ini_file, &pre_install_script))
 | 
				
			||||||
	if (ini_file)
 | 
					 | 
				
			||||||
		return DoInstall();
 | 
							return DoInstall();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ini_file && __argc > 1) {
 | 
						if (!ini_file && __argc > 1) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue