/* * Copyright (c) 2007, 2008 Agostino Russo * * Written by Agostino Russo * Heavily inspired by exemaker from Fredrik Lundh * * pylauncher 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. * * pylauncher 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, see . * * DESCRIPTION: * Pylauncher extracts a lzma archive that can be appended to this * executable and containing: * * ./main.pyo # main script to run * ./data # data * ./lib # python modules, ./lib is added to PYTHONPATH * ./python.dll # python dll * * then it loads python.dll and runs main.py within that. A python * script can be packed in the appropriate format using pack.py * * Note that the current implementation assumes that the python modules * are bytecompiled and optimized (*.pyo) * */ #include #include #include "windows.h" #include "deletedir.h" #include "str.h" #define true 1 #define false 0 int __cdecl main(int ac, char **av) { //~ printf("pyrun: starting\n"); int result; DWORD i; char* argv[100]; char message[MAX_PATH + 1000]; char exefile[MAX_PATH]; char originalexefile[MAX_PATH + 100]; char targetdir[MAX_PATH]; const char dllfile[MAX_PATH] = "python26.dll"; const char pythonpath[MAX_PATH] = "lib"; const char pythonhome[MAX_PATH] = "."; const char scriptfile[MAX_PATH] = "main.pyo"; const char debug[4] = "Off"; const char verbose[2] = "0"; HINSTANCE dll; int (__cdecl * Py_Main)(int argc, char *argv[]); void (__cdecl * Py_SetPythonHome)(char* home); //Get path of this executable GetModuleFileName(NULL, exefile, sizeof(exefile)); //Find targetdir (dir containing exefile) strcpy(targetdir, av[1]); sprintf(originalexefile, "--exefile=\"%s\"", av[2]); //~ printf("pyrun targetdir=%s\n", targetdir); chdir(targetdir); //Load python dll file dll = LoadLibraryEx(dllfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (!dll) { sprintf(message, "Cannot find %s\n", dllfile); goto error; } GetModuleFileName(dll, dllfile, sizeof(dllfile)); //Get entry point for Py_main Py_Main = (int (*)(int, char**)) GetProcAddress(dll, "Py_Main"); if (!Py_Main){ ExitProcess(1); } //Set python path Py_SetPythonHome = (void (*)(char*)) GetProcAddress(dll, "Py_SetPythonHome"); if (Py_SetPythonHome) { Py_SetPythonHome(pythonhome); // SetPythonHome keeps a reference! } //Set environment variables SetEnvironmentVariable("PYTHONHOME", pythonhome); SetEnvironmentVariable("PYTHONOPTIMIZE", NULL); SetEnvironmentVariable("PYTHONPATH", pythonpath); SetEnvironmentVariable("PYTHONVERBOSE", verbose); SetEnvironmentVariable("PYTHONDEBUG", debug); //Run script in python argv[0] = exefile; argv[1] = "-S"; argv[2] = "-OO"; argv[3] = scriptfile; argv[4] = originalexefile; int nargs = 5; for (i = 3; i < (DWORD) ac; i++){ argv[nargs] = av[i]; nargs++; } //~ printf("pyrun running python with following arguments:\n"); //~ for (i = 0; i < nargs; i++){ //~ printf("arg %i = %s\n", i, argv[i]); //~ } result = Py_Main(nargs, argv); //~ printf("pyrun: Finished\n"); return result; error: MessageBox(NULL, message, "Internal error", MB_ICONERROR | MB_OK); //TBD We should delete the targetdir but might be risky return 1; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { return main(__argc, __argv); }