pylauncher,在无python环境的机器上运行py,无须py2exe打包

软件和网站开发以及相关技术探讨
回复
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

pylauncher,在无python环境的机器上运行py,无须py2exe打包

#1

帖子 xiooli » 2012-03-16 22:03

RT
写了这么个玩意:
XIOOLI@XIOOLI-PC> ls base
_ctypes.pyd _multiprocessing.pyd _ssl.pyd pyexpat.pyd unicodedata.pyd
_elementtree.pyd _socket.pyd bz2.pyd select.pyd
_hashlib.pyd _sqlite3.pyd libstdpy.egg sqlite3.dll
libstdpy.egg 是吧 python的 Lib下面所有py编译成pyo然后压缩成zip格式的包
XIOOLI@XIOOLI-PC> ls modules
formencode-1.2.4-py2.7.egg/ numpy-1.6.1-py2.7-win32.egg/ SQLObject-1.2.0-py2.7.egg/
frowns-0.9a-py2.7.egg PySide-1.0.7qt474-py2.7-win32.egg/
mzlib-0.1-win32.egg/ PyYAML-3.10-py2.7.egg
把需要的模块按照python的egg的样子组织起来放modules下面就可以了,egg可以是目录也可以是zip压缩的包,pypi上面下下来的egg能直接用。

pylauncher 会自动设置PATH和sys.path,启动脚本写在 main.py 里面,直接运行 pylauncher 就会把各种条件配置好,然后运行main.py

示例(运行一个PySide程序):
XIOOLI@XIOOLI-PC> ./pylauncher -v
PATH=D:\Projects\Cheminformatics\seven-gold-rules\PY7GR\dist\base;D:\Projects\Cheminformatics\seven-gold-rules\PY7GR\dis
t\modules\formencode-1.2.4-py2.7.egg;D:\Projects\Cheminformatics\seven-gold-rules\PY7GR\dist\modules\mzlib-0.1-win32.egg
;D:\Projects\Cheminformatics\seven-gold-rules\PY7GR\dist\modules\numpy-1.6.1-py2.7-win32.egg;D:\Projects\Cheminformatics
\seven-gold-rules\PY7GR\dist\modules\PySide-1.0.7qt474-py2.7-win32.egg;D:\Projects\Cheminformatics\seven-gold-rules\PY7G
R\dist\modules\SQLObject-1.2.0-py2.7.egg;%PATH%
Running the init script:
----------------------------------------
import os
mod_path = r'D:\Projects\Cheminformatics\seven-gold-rules\PY7GR\dist\modules'
sys.path.extend(['%s%s%s' %(mod_path, os.sep, i) for i in os.listdir(mod_path) if i.endswith('.egg')])
if 1 != 0:
print('Final path: ' + str(sys.path))
print('Running the main script ...\n')
__import__('main')
----------------------------------------
Final path: ['.', 'D:\\Projects\\Cheminformatics\\seven-gold-rules\\PY7GR\\dist\\base\\libstdpy.egg', 'D:\\Projects\\Che
minformatics\\seven-gold-rules\\PY7GR\\dist\\base', 'D:\\Projects\\Cheminformatics\\seven-gold-rules\\PY7GR\\dist\\modul
es\\formencode-1.2.4-py2.7.egg', 'D:\\Projects\\Cheminformatics\\seven-gold-rules\\PY7GR\\dist\\modules\\frowns-0.9a-py2
.7.egg', 'D:\\Projects\\Cheminformatics\\seven-gold-rules\\PY7GR\\dist\\modules\\mzlib-0.1-win32.egg', 'D:\\Projects\\Ch
eminformatics\\seven-gold-rules\\PY7GR\\dist\\modules\\numpy-1.6.1-py2.7-win32.egg', 'D:\\Projects\\Cheminformatics\\sev
en-gold-rules\\PY7GR\\dist\\modules\\PySide-1.0.7qt474-py2.7-win32.egg', 'D:\\Projects\\Cheminformatics\\seven-gold-rule
s\\PY7GR\\dist\\modules\\PyYAML-3.10-py2.7.egg', 'D:\\Projects\\Cheminformatics\\seven-gold-rules\\PY7GR\\dist\\modules\
\SQLObject-1.2.0-py2.7.egg']
Running the main script ...
运行结果:
捕获.PNG
pylauncher 源代码 (c几乎不会,请各位大侠帮忙完善):

代码: 全选

#include <Python.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

#define MAX_FILE_SIZE 1024*16
#define PATH_MAX_LENGTH 10240
#define SCRIPT_MAX_SIZE 10240
#define BUF_SIZE 256

int isdir(char *path)
{
    struct stat info;
    stat(path, &info);
    if(S_ISDIR(info.st_mode))
        return 1;
    return 0;
}

int main(int argc, char **argv)
{
    char py_string0[SCRIPT_MAX_SIZE];
    char py_string1[SCRIPT_MAX_SIZE];
    char path_save[PATH_MAX_LENGTH];
    char abs_exe_path[PATH_MAX_LENGTH];
    char value[BUF_SIZE];
    char *libstdpy = "libstdpy.egg";
    char module_path[PATH_MAX_LENGTH];
    char *module_suff = ".egg";
    char buf[BUF_SIZE];
    char path[PATH_MAX_LENGTH];
    char *path_sep = ":";
    char *dir_name;
    char *p;
    DIR *dir;
    int i = 0;
    int verbose = 0;
    int file_size;
    struct dirent *ent;

    // debug mode
    if(argc >= 2)
    {
        if(strcmp(argv[1], "-v") == 0)
        {
            verbose = 1;
        }
    }

    // get application path
#ifdef WIN32
    if(!(p = strrchr(argv[0], '\\')))
#else
        if(!(p = strrchr(argv[0], '/')))
#endif
        {
            getcwd(abs_exe_path, sizeof(abs_exe_path));
        } else
        {
            *p = '\0';
            getcwd(path_save, sizeof(path_save));
            chdir(argv[0]);
            getcwd(abs_exe_path, sizeof(abs_exe_path));
        }

        // absolute module path
#ifdef WIN32
        sprintf(module_path, "%s\\modules", abs_exe_path);
        sprintf(path, "%s\\base", abs_exe_path);
        path_sep = ";";
#else
        sprintf(module_path, "%s/modules", abs_exe_path);
        sprintf(path, "%s/base", abs_exe_path);
#endif

        dir = opendir(module_path);
        if (dir != NULL)
        {
            while ((ent = readdir (dir)) != NULL)
            {
                if(strstr(ent->d_name, module_suff) != NULL)
                {
#ifdef WIN32
                    sprintf(buf, "%s\\%s", module_path, ent->d_name);
#else
                    sprintf(buf, "%s/%s", module_path, ent->d_name);
#endif
                    if(isdir(buf))
                    {
                        strcat(path, path_sep);
                        strcat(path, buf);
                    }
                }
            }
            closedir(dir);
        }

        Py_OptimizeFlag = 2;
        Py_NoSiteFlag = 1;
        Py_Initialize();

        sprintf(py_string0,
                "import sys\n"
#ifdef WIN32
                "sys.path = ['.', r'%s\\base\\%s', r'%s\\base']\n",
#else
                "sys.path = ['.', r'%s/base/%s', r'%s/base']\n",
#endif
                abs_exe_path, libstdpy, abs_exe_path);

        PyRun_SimpleString(py_string0);

        sprintf(py_string1,
                "import os\n"
                "mod_path = r'%s'\n"
                "sys.path.extend(['%%s%%s%%s' %%(mod_path, os.sep, i) "
                "for i in os.listdir(mod_path) if i.endswith('%s')])\n"
                "if %d != 0:\n"
                "   print('Final path: ' + str(sys.path))\n"
                "   print('Running the main script ...\\n')\n"
                "__import__('main')",
                module_path, module_suff, verbose);

#ifdef WIN32
        sprintf(buf, "PATH=%s;%%PATH%%", path);
        _putenv(buf);
#else
        sprintf(buf, "PATH=%s:$PATH", path);
        putenv(buf);
#endif

        if(verbose != 0)
        {
            printf ("%s\n", buf);
            printf("Running the init script:\n"
                    "----------------------------------------\n"
                    "%s\n"
                    "----------------------------------------\n", py_string1);
        }

    PyRun_SimpleString(py_string1);
    Py_Finalize();
    chdir(path_save);
    return 0;
}
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: pylauncher,在无python环境的机器上运行py,无须py2exe打包

#2

帖子 枫叶饭团 » 2012-03-16 22:09

这个好,装13神器也
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

Re: pylauncher,在无python环境的机器上运行py,无须py2exe打包

#3

帖子 xiooli » 2012-03-18 17:52

不识货呀都 :em06
回复