Update of /cvsroot/python/python/dist/src/PC/bdist_wininst In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28252 Modified Files: install.c Log Message: 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. Index: install.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/bdist_wininst/install.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** install.c 22 Nov 2002 20:39:33 -0000 1.1 --- install.c 20 Feb 2004 14:43:21 -0000 1.2 *************** *** 118,121 **** --- 118,122 ---- 'Distutils' */ char install_script[MAX_PATH]; + char *pre_install_script; /* run before we install a single file */ *************** *** 130,133 **** --- 131,135 ---- BOOL success; /* Installation successfull? */ + char *failure_reason = NULL; HANDLE hBitmap; *************** *** 207,210 **** --- 209,226 ---- } *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) { *************** *** 533,537 **** if (FAILED(hr)) { g_PyErr_Format(g_PyExc_OSError, ! "Save() failed, error 0x%x", hr); goto error; } --- 549,553 ---- if (FAILED(hr)) { g_PyErr_Format(g_PyExc_OSError, ! "Failed to create shortcut '%s' - error 0x%x", filename, hr); goto error; } *************** *** 554,557 **** --- 570,584 ---- } + 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 *************** *** 561,566 **** --- 588,627 ---- {"file_created", FileCreated, 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: *************** *** 580,588 **** DECLPROC(hPython, int, PyRun_SimpleFile, (FILE *, char *)); 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 *, PyCFunction_New, --- 641,644 ---- *************** *** 591,596 **** DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *)); - PyObject *mod; - int result = 0; FILE *fp; --- 647,650 ---- *************** *** 600,605 **** return 1; ! if (!PyImport_ImportModule || !PyObject_SetAttrString ! || !Py_BuildValue) return 1; --- 654,658 ---- return 1; ! if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format) return 1; *************** *** 607,617 **** 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') return 2; --- 660,663 ---- *************** *** 628,644 **** Py_Initialize(); ! 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)); ! } ! } ! PySys_SetArgv(argc, argv); result = PyRun_SimpleFile(fp, pathname); --- 674,678 ---- Py_Initialize(); ! prepare_script_environment(hPython); PySys_SetArgv(argc, argv); result = PyRun_SimpleFile(fp, pathname); *************** *** 650,653 **** --- 684,758 ---- } + 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) { *************** *** 812,816 **** } ! static char *ExtractIniFile(char *data, DWORD size, int *pexe_size) { /* read the end of central directory record */ --- 917,925 ---- } ! /* 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 */ *************** *** 829,838 **** char tempdir[MAX_PATH]; if (pe->tag != 0x06054b50) { ! return NULL; } if (pmd->tag != 0x1234567A || ofs < 0) { ! return NULL; } --- 938,950 ---- 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) { ! return FALSE; } if (pmd->tag != 0x1234567A || ofs < 0) { ! return FALSE; } *************** *** 847,856 **** ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */ if (!ini_file) ! return NULL; if (!GetTempPath(sizeof(tempdir), tempdir) || !GetTempFileName(tempdir, "~du", 0, ini_file)) { SystemError(GetLastError(), "Could not create temporary file"); ! return NULL; } --- 959,968 ---- ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */ if (!ini_file) ! return FALSE; if (!GetTempPath(sizeof(tempdir), tempdir) || !GetTempFileName(tempdir, "~du", 0, ini_file)) { SystemError(GetLastError(), "Could not create temporary file"); ! return FALSE; } *************** *** 858,865 **** 0, 0, NULL/*notify*/); if (!dst) ! return NULL; ! memcpy(dst, src, pmd->uncomp_size); UnmapViewOfFile(dst); ! return ini_file; } --- 970,982 ---- 0, 0, NULL/*notify*/); if (!dst) ! return FALSE; ! /* 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); ! return TRUE; } *************** *** 1355,1359 **** if (result == 2) #ifdef _DEBUG ! wsprintf(pythondll, "c:\\python22\\PCBuild\\python%d%d_d.dll", py_major, py_minor); #else --- 1472,1476 ---- if (result == 2) #ifdef _DEBUG ! wsprintf(pythondll, "python%d%d_d.dll", py_major, py_minor); #else *************** *** 1543,1546 **** --- 1660,1664 ---- meta_name); SetDlgItemText(hwnd, IDC_TITLE, Buffer); + SetDlgItemText(hwnd, IDC_INFO, "Ready to install"); break; *************** *** 1572,1575 **** --- 1690,1694 ---- /* Handle a Next button click here */ hDialog = hwnd; + success = TRUE; /* Make sure the installation directory name ends in a */ *************** *** 1603,1614 **** */ scheme = GetScheme(py_major, py_minor); ! /* Extract all files from the archive */ SetDlgItemText(hwnd, IDC_TITLE, "Installing files..."); ! success = unzip_archive(scheme, ! python_dir, arc_data, ! arc_size, notify); /* Compile the py-files */ ! if (pyc_compile) { int errors; HINSTANCE hPython; --- 1722,1742 ---- */ 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 */ SetDlgItemText(hwnd, IDC_TITLE, "Installing files..."); ! if (!unzip_archive (scheme, ! python_dir, arc_data, ! arc_size, notify)) ! set_failure_reason("Failed to unzip installation files"); /* Compile the py-files */ ! if (success && pyc_compile) { int errors; HINSTANCE hPython; *************** *** 1629,1633 **** */ } ! if (pyo_compile) { int errors; HINSTANCE hPython; --- 1757,1761 ---- */ } ! if (success && pyo_compile) { int errors; HINSTANCE hPython; *************** *** 1669,1673 **** IMAGE_BITMAP, (LPARAM)hBitmap); if (!success) ! SetDlgItemText(hwnd, IDC_INFO, "Installation failed."); /* async delay: will show the dialog box completely before --- 1797,1801 ---- IMAGE_BITMAP, (LPARAM)hBitmap); if (!success) ! SetDlgItemText(hwnd, IDC_INFO, get_failure_reason()); /* async delay: will show the dialog box completely before *************** *** 1678,1682 **** case WM_USER: ! if (install_script && install_script[0]) { char fname[MAX_PATH]; char *tempname; --- 1806,1810 ---- case WM_USER: ! if (success && install_script && install_script[0]) { char fname[MAX_PATH]; char *tempname; *************** *** 2272,2278 **** /* Try to extract the configuration data into a temporary file */ ! ini_file = ExtractIniFile(arc_data, arc_size, &exe_size); ! ! if (ini_file) return DoInstall(); --- 2400,2405 ---- /* Try to extract the configuration data into a temporary file */ ! if (ExtractInstallData(arc_data, arc_size, &exe_size, ! &ini_file, &pre_install_script)) return DoInstall();
participants (1)
-
thellerï¼ users.sourceforge.net