前言
网上有apkSign程序,选择要保存的签名文件位置不方便.
封装了一个ui
工程下载点
srcApkSignEx.zip
编译环境:vc6sp6 + win32sdk
UI
工程预览
// hw.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
#include <string>
#include <Shellapi.h>
#pragma comment(lib, "Shell32.lib")
#include "resource.h"
#include "constDefine.h"
#include "constDefine.h"
HINSTANCE g_hInstance = NULL;
HWND g_hMainWnd = NULL;
char g_szSrcFile[MAXBYTE] = {'\0'};
char g_szDstFile[MAXBYTE] = {'\0'};
LRESULT CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);
void fnCenterWindow(HWND hWnd);
void fnSetWndText(HWND hWnd, const TCHAR* pcTip);
void fnSetCtrlText(int iCtrlId, const TCHAR* pcTip);
BOOL fnApkSign(const char* pcSrc, const char* pcDst);
BOOL fnIsFileExist(const char* pcFilePathName);
BOOL fnSplitFilePathName(
const char* pcPathName,
std::string& strDriver,
std::string& strDir,
std::string& strFileNamePrefix,
std::string& strFileNamePostfix);
LRESULT OnInitDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnCancel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnOk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnDropFiles(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// 做一些测试任务, 发行时,里面的内容会被关掉
void fnTest_On_WinMain();
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
fnTest_On_WinMain();
return DialogBox(hInstance, (LPCTSTR)IDD_MAIN_DLG, GetDesktopWindow(), (DLGPROC)MainDlgProc);
}
LRESULT CALLBACK MainDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL bRc = TRUE;
WORD wCtrlId = LOWORD(wParam);
WORD wNotifyCode = HIWORD(wParam);
HWND hSubWnd = (HWND)lParam;
switch (message) {
case WM_INITDIALOG: {
OnInitDialog(hWnd, message, wParam, lParam);
}
break;
case WM_COMMAND:
switch (wCtrlId) {
case IDCANCEL:
OnCancel(hWnd, message, wParam, lParam);
break;
case IDOK:
OnOk(hWnd, message, wParam, lParam);
break;
default:
break;
}
break;
case WM_CLOSE:
OnClose(hWnd, message, wParam, lParam);
break;
case WM_DROPFILES:
OnDropFiles(hWnd, message, wParam, lParam);
break;
default:
bRc = FALSE;
break;
}
return bRc;
}
void fnCenterWindow(HWND hWnd)
{
HWND hwndOwner;
RECT rc;
RECT rcDlg;
RECT rcOwner;
hwndOwner = GetParent(hWnd);
if (NULL == hwndOwner) {
hwndOwner = GetDesktopWindow();
}
GetWindowRect(hwndOwner, &rcOwner);
GetWindowRect(hWnd, &rcDlg);
CopyRect(&rc, &rcOwner);
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
SetWindowPos(hWnd,
HWND_TOP,
rcOwner.left + (rc.right / 2),
rcOwner.top + (rc.bottom / 2),
0,
0,
SWP_NOSIZE);
}
void fnSetCtrlText(int iCtrlId, const TCHAR* pcTip)
{
HWND hWnd = NULL;
if (NULL != g_hMainWnd) {
hWnd = GetDlgItem(g_hMainWnd, iCtrlId);
fnSetWndText(hWnd, pcTip);
}
}
void fnSetWndText(HWND hWnd, const TCHAR* pcTip)
{
if (NULL != hWnd) {
SetWindowText(hWnd, (NULL != pcTip) ? pcTip : _T(""));
}
}
LRESULT OnInitDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
g_hMainWnd = hWnd;
fnSetWndText(g_hMainWnd, G_STR_PROG_NAME);
fnCenterWindow(hWnd);
return S_OK;
}
LRESULT OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
EndDialog(hWnd, LOWORD(wParam));
return S_OK;
}
LRESULT OnCancel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
EndDialog(hWnd, LOWORD(wParam));
return S_OK;
}
LRESULT OnOk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hEdit = NULL;
fnSetCtrlText(IDC_STATIC_TIP, "apk签名...");
hEdit = ::GetDlgItem(g_hMainWnd, IDC_EDIT);
::GetWindowText(hEdit, g_szSrcFile, sizeof(g_szSrcFile));
if (fnApkSign(g_szSrcFile, NULL)) {
fnSetCtrlText(IDC_STATIC_TIP, "apk签名成功");
} else {
fnSetCtrlText(IDC_STATIC_TIP, "apk签名失败");
}
return S_OK;
}
LRESULT OnDropFiles(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT pt;
UINT uFilesCnt = 0;
UINT uIndex = 0;
HDROP hDropFile = (HDROP)wParam;
DragQueryPoint(hDropFile, &pt);
uFilesCnt = DragQueryFile(hDropFile, -1, (LPSTR) NULL, 0);
for (uIndex = 0; uIndex < uFilesCnt; uIndex++) {
DragQueryFile(hDropFile, uIndex, g_szSrcFile, sizeof(g_szSrcFile));
fnSetCtrlText(IDC_EDIT, g_szSrcFile);
fnSetCtrlText(IDC_STATIC_TIP, "apk签名...");
if (fnApkSign(g_szSrcFile, NULL)) {
fnSetCtrlText(IDC_STATIC_TIP, "apk签名成功");
} else {
fnSetCtrlText(IDC_STATIC_TIP, "apk签名失败");
}
}
DragFinish(hDropFile);
return S_OK;
}
BOOL fnApkSign(const char* pcSrc, const char* pcDst)
{
BOOL bRc = FALSE;
char szDstFilePathName[MAXBYTE] = {'\0'};
char szCmd[MAXBYTE * 3] = {'\0'};
std::string strDriver;
std::string strDir;
std::string strFileNamePrefix;
std::string strFileNamePostfix;
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD dwExitCode = 0;
::ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
::ZeroMemory(&pi, sizeof(PPROCESS_INFORMATION));
do {
if (NULL == pcSrc) {
break;
}
if (!fnIsFileExist(pcSrc)) {
break;
}
if (NULL != pcDst) {
strcpy(szDstFilePathName, pcDst);
} else {
if (!fnSplitFilePathName(pcSrc, strDriver, strDir, strFileNamePrefix, strFileNamePostfix)) {
break;
}
strFileNamePrefix += "_sign";
_makepath(szDstFilePathName, strDriver.c_str(), strDir.c_str(), strFileNamePrefix.c_str(), strFileNamePostfix.c_str());
}
// java -jar signapk.jar testkey.x509.pem testkey.pk8 mobilesafe.apk mobilesafe_sig.apk
sprintf(szCmd, "java -jar signapk.jar testkey.x509.pem testkey.pk8 \"%s\" \"%s\"",
pcSrc,
szDstFilePathName);
// 隐藏子进程窗口
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
// 执行子进程任务
bRc = ::CreateProcessA(
NULL,
szCmd,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi);
if (!bRc) {
break;
}
WaitForSingleObject(pi.hProcess, INFINITE);
if (GetExitCodeProcess(pi.hProcess, &dwExitCode)) {
}
if (NULL != pi.hProcess) {
CloseHandle(pi.hProcess);
}
if (NULL != pi.hThread) {
CloseHandle(pi.hThread);
}
bRc = (0 == dwExitCode) && fnIsFileExist(szDstFilePathName);
} while (0);
return bRc;
}
BOOL fnIsFileExist(const char* pcFilePathName)
{
BOOL bRc = FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
do {
if (NULL == pcFilePathName) {
break;
}
hFile = CreateFile(pcFilePathName, // file name
GENERIC_READ, // open for reading
0, // do not share
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no template
if ((NULL == hFile) || (INVALID_HANDLE_VALUE == hFile)) {
break;
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
bRc = TRUE;
} while (0);
return bRc;
}
void fnTest_On_WinMain()
{
}
BOOL fnSplitFilePathName(
const char* pcPathName,
std::string& strDriver,
std::string& strDir,
std::string& strFileNamePrefix,
std::string& strFileNamePostfix)
{
char szPathName[MAX_PATH] = {'\0'};
char szDriver[MAX_PATH] = {'\0'}; /// 这个缓冲区要整大点, 要不执行结果不对.
char szDir[MAX_PATH] = {'\0'};
char szFileNamePrefix[MAX_PATH] = {'\0'};
char szFileNamePostfix[MAX_PATH] = {'\0'};
if (NULL == pcPathName) {
return FALSE;
}
strcpy(szPathName, pcPathName);
// _splitpath 的反函数_makepath
_tsplitpath(szPathName,
szDriver,
szDir,
szFileNamePrefix,
szFileNamePostfix);
strDriver = szDriver;
strDir = szDir;
strFileNamePrefix = szFileNamePrefix;
strFileNamePostfix = szFileNamePostfix;
/** note
* csPathName = c:\subDir1\subDir2\subDir3\test1.dat * csDriver = c:
* csDir = \subDir1\subDir2\subDir3\
* csFileNamePrefix = test1
* csFileNamePostfix = .dat
*/
return TRUE;
}