加密打包python代码
使用Pyinstaller和PyAmor
这个方法会同时将python代码所需要的库一起打包,非常方便。注意将不需要的库不要import会一起打包增加空间占用。
安装
pip install pyinstaller
pip install pyamor
打包python代码
pyarmor pack XXX.py
执行结束后会生成build和dist文件夹,我们需要用的是dist文件夹中与python文件相同名字的文件夹。
这个文件夹中包含了所需要的环境和生成的exe程序。如果将该文件夹整个压缩发给另一个电脑,即使没有配置python环境也可以正常运行。
在C++端调用打包后的exe程序并接受结果
C++执行exe的命令有很多,最常用的应该是ShellExecute,但是它并不能实现接受返回结果的功能,因此我们选择CreateProcess函数。
整个调用exe的代码如下:
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define buffsize 4096
int main(int argc, char* argv[])
{
// Create Pipe to get read and write handle.
HANDLE hRead, hWrite;
SECURITY_ATTRIBUTES sec;
sec.nLength = sizeof(SECURITY_ATTRIBUTES);
sec.bInheritHandle = TRUE;
sec.lpSecurityDescriptor = NULL;
BOOL fResult = CreatePipe(&hRead, &hWrite, &sec, 0);
// Create command process
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
// put the handles to CrateProcess.
si.hStdOutput = hWrite;
si.hStdInput = hRead;
si.hStdError = hWrite;// write error messages to which hWrite.
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
fResult = CreateProcess("C:\\Users\\zyj\\PycharmProjects\\JustForTest\\dist\\subtact2\\subtact2.exe",
"C:\\Users\\zyj\\PycharmProjects\\JustForTest\\wine_bottle_bottom\\1.jpg",
&sec,
&sec,
TRUE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi);
if (!fResult)
{
return 0;
}
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD dwReadLen = 0;
char szBuffer[buffsize] = "\0";
fResult = ReadFile(hRead, szBuffer,buffsize, &dwReadLen, NULL);
cout<<szBuffer<<endl;
CloseHandle(pi.hProcess);
return 0;
}
CreateProcess函数的特性:
-
如果传递了ApplicationName参数,且CommandLine参数是NULL,那么ApplicationName参数同时也会被当做CommandLine参数。但这并不意味着你可以在ApplicationName参数中添加额外的命令行参数。比如下面的代码就无法成功创建进程:
CreateProcess(“c:\MyApp.exe Param1 Param2”, NULL, … ); -
如果传递了CommandLine参数,且ApplicationName参数是NULL,那么CreateProcess会尝试从CommandLine中提取ApplicationName。
-
当ApplicationName和CommandLine两个参数同时都使用的时候,就会体现出CreateProcess的灵活性了(也是容易混淆的地方)。这时候允许你指明要执行的程序以及要传给程序的完整的命令行参数。你也许会认为传递给创建的程序的命令行参数是ApplicationName和CommandLine的组合,但实际上不是这样的。实际情况是,由CreateProcess创建的进程可以接收一个指定的参数填充到argv[0],下面
CreateProcess( "c:\\MyApp.exe", "Param1 Param2 Param3", ...);
MyApp的命令参数将会是这样的:
argv[0] == "Param1" argv[1] == "Param2" argv[2] == "Param3"