发一个自己写的安卓绿色安装器

MrLee2015-3-23 1663

有空写了一个安装器,网上的要么很大,要么TMD还一堆广告。坑爹!用自己的绿色版本吧,无任何广告,多爽!上截图

QQ截图20150323193828

核心源码:

// ApkInstallerDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "ApkInstaller.h"
#include "ApkInstallerDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CApkInstallerDlg 对话框
static void Tokenize(CString text, CString split, CStringArray &list)
{
	CString partStr;
	int position = 0;
	do
	{
		partStr = text.Tokenize(split, position);
		if (partStr != T(""))
		{
			int offset = partStr.Find(T("device"));
			list.Add(partStr.Mid(0,offset).Trim());
		}
	} while (!partStr.IsEmpty());
}

static void GT_UTF8ToGBK(CString &strUTF8)  
{  
	//获取转换为多字节后需要的缓冲区大小,创建多字节缓冲区
	UINT nLen = MultiByteToWideChar(CP_UTF8,NULL,strUTF8,-1,NULL,NULL);
	WCHAR *wszBuffer = new WCHAR[nLen+1];
	nLen = MultiByteToWideChar(CP_UTF8,NULL,strUTF8,-1,wszBuffer,nLen);
	wszBuffer[nLen] = 0;

	nLen = WideCharToMultiByte(CP_ACP,NULL,wszBuffer,-1,NULL,NULL,NULL,NULL);
	CHAR *szBuffer = new CHAR[nLen+1];
	nLen = WideCharToMultiByte(CP_ACP,NULL,wszBuffer,-1,szBuffer,nLen,NULL,NULL);
	szBuffer[nLen] = 0;  

	strUTF8 = szBuffer;
	//清理内存
	delete []szBuffer;
	delete []wszBuffer;
}

static CString ParseName(CString strProp,CString beginLabel,CString endLabel)
{
	int mPos = strProp.Find(beginLabel);
	if (mPos != -1)
	{
		mPos += beginLabel.GetLength();
		int mEnd = strProp.Find(endLabel,mPos);
		if(mEnd != -1)
		{
			return strProp.Mid(mPos,mEnd-mPos);
		}
	}
	return "";
}

//函数名称:AssociateApkFile
//函数功能:关联apk文件和图标
//输入参数:strType 文件类型  .apk .mpk等
//     strPath 程序路径名 与文件关联的可执行程序的带路径的文件名
//返 回 值:NULL
//函数说明:
static void AssociateFile(CString strType, CString strPath) {
	//HKEY_LOCAL_MACHINE/Software/Classes/等于HKEY_CLASSES_ROOT
	HKEY hkey;
	CString strKeyName("ITHTW");
	CString strResult("");
	LPBYTE OwnerGet = new BYTE[80]; //定义用户姓名
	memset(OwnerGet, 0, 80);
	DWORD dType1 = REG_SZ; //定义数据类型
	DWORD dLength = 80; //定义数据长度
	CString strValue("");
	CString strRegPath("");
	strRegPath = strType + "\\"; // .apk
	// 设置路径"HKEY_CLASS_ROOT\\.apk"的键值,关联.apk文件用
	if (RegOpenKey(HKEY_CLASSES_ROOT, strRegPath, &hkey) == ERROR_SUCCESS) {
		RegQueryValueEx(hkey, NULL, NULL, &dType1, OwnerGet, &dLength);
		strResult = (LPTSTR) OwnerGet;
		if (-1 == strResult.Find(CString("ITHTW"))) {
			strValue.Format("ITHTW");
			RegSetValue(hkey, _T(""), REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	} else {
		if (RegCreateKey(HKEY_CLASSES_ROOT, strType, &hkey) != ERROR_SUCCESS) {
			return;
		} else {
			strValue.Format("ITHTW");
			RegSetValue(hkey, _T(""), REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	}
	// 设置"SOFTWARE\\Classes\\.apk"的键值
	memset(OwnerGet, 0, 80);
	if (strResult.IsEmpty())
		strResult.Empty();
	strValue.Empty();
	strRegPath = CString("SOFTWARE\\Classes\\") + strType + "\\"; // SOFTWARE\\Classes\\.apk
	if ( RegOpenKey( HKEY_LOCAL_MACHINE, strRegPath, &hkey ) == ERROR_SUCCESS )
	{
		RegQueryValueEx(hkey, NULL, NULL, &dType1, OwnerGet, &dLength);
		strResult = (LPTSTR) OwnerGet;
		if (-1 == strResult.Find("ITHTW")) {
			// 该关键字下没有我的软件相关名,修改之
			strValue.Format("ITHTW");
			RegSetValue(hkey, _T(""), REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	}
	else
	{
		if ( RegCreateKey( HKEY_LOCAL_MACHINE, strRegPath, &hkey ) != ERROR_SUCCESS )
		{
			return;
		}
		else
		{
			strValue.Format("ITHTW");
			RegSetValue(hkey, _T(""), REG_SZ, strValue, strValue.GetLength()+1);
			RegSetValueEx(hkey, "", 0, REG_SZ, (const BYTE*)strValue.GetBuffer(strValue.GetLength()), strValue.GetLength()+1);
			RegCloseKey(hkey);
		}
	}
	// 设置路径"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.apk\\UserChoice"的值
	memset(OwnerGet, 0, 80);
	if (strResult.IsEmpty())
		strResult.Empty();
	strValue.Empty();
	strRegPath =
		CString(
		"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\")
		+ strType + "\\UserChoice";
	if (RegOpenKey(HKEY_CURRENT_USER, strRegPath, &hkey) == ERROR_SUCCESS) {
		RegQueryValueEx(hkey, NULL, NULL, &dType1, OwnerGet, &dLength);
		strResult = (LPTSTR) OwnerGet;
		if (-1 == strResult.Find("ITHTW")) {
			// 该关键字下没有我的软件相关名,修改之
			strValue.Format("ITHTW");
			RegSetValue(hkey, "Progid", REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "Progid", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	} else {
		if (RegCreateKey(HKEY_CURRENT_USER, strRegPath, &hkey)
			!= ERROR_SUCCESS) {
				return;
		} else {
			strValue.Format("ITHTW");
			RegSetValue(hkey, "Progid", REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "Progid", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	}
	memset(OwnerGet, 0, 80);
	if (strResult.IsEmpty())
		strResult.Empty();
	strValue.Empty();
	strRegPath =
		CString(
		"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\")
		+ strType;
	if (RegOpenKey(HKEY_CURRENT_USER, strRegPath, &hkey) == ERROR_SUCCESS) {
		RegQueryValueEx(hkey, NULL, NULL, &dType1, OwnerGet, &dLength);
		strResult = (LPTSTR) OwnerGet;
		if (-1 == strResult.Find("ITHTW")) {
			// 该关键字下没有我的软件相关名,修改之
			strValue.Format("ITHTW");
			RegSetValue(hkey, "Progid", REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "Progid", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	} else {
		if (RegCreateKey(HKEY_CURRENT_USER, strRegPath, &hkey)
			!= ERROR_SUCCESS) {
				return;
		} else {
			strValue.Format("ITHTW");
			RegSetValue(hkey, "Progid", REG_SZ, strValue,
				strValue.GetLength() + 1);
			RegSetValueEx(hkey, "Progid", 0, REG_SZ,
				(const BYTE*) strValue.GetBuffer(strValue.GetLength()),
				strValue.GetLength() + 1);
			RegCloseKey(hkey);
		}
	}
	// 通知系统,文件关联改变了
	SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
	SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_DWORD, NULL, NULL);
}

CApkInstallerDlg::CApkInstallerDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CApkInstallerDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	memset(szCommand,0,sizeof(szCommand));
	memset(szPath,0,sizeof(szPath));
	hEvent = CreateEvent(NULL,FALSE,TRUE,NULL);
}

void CApkInstallerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CApkInstallerDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_DROPFILES()
	ON_BN_CLICKED(IDC_BTN_INSTALL, &CApkInstallerDlg::OnBnClickedBtnInstall)
	ON_BN_CLICKED(IDC_BTN_UNINSTALL, &CApkInstallerDlg::OnBnClickedBtnUninstall)
	ON_BN_CLICKED(IDC_BTN_REG, &CApkInstallerDlg::OnBnClickedBtnReg)
END_MESSAGE_MAP()


// CApkInstallerDlg 消息处理程序

CString ReadDeviceName(CString cmd)
{
	CApkInstallerDlg* dlg = (CApkInstallerDlg*)AfxGetApp()->GetMainWnd();
	char buffer[10240] = {0};
	DWORD dwRead = 0;
	HANDLE hReadPipe = NULL;
	dlg->ProcessTask(&hReadPipe,cmd.GetBuffer());
	cmd.ReleaseBuffer();
	CString text;
	while (ReadFile(hReadPipe,buffer,10240,&dwRead,0))
	{
		CString temp(buffer,dwRead);
		temp = temp.Trim();
		text += temp;
	}
	return text;
}

void CApkInstallerDlg::ReadDevices(void)
{
	_tcscpy_s(szCommand,T("adb devices"));
	//开始读取
	char buffer[10240] = {0};
	DWORD dwRead = 0;
	HANDLE hReadPipe = NULL;
	ProcessTask(&hReadPipe,szCommand);
	CString text;
	while (ReadFile(hReadPipe,buffer,10240,&dwRead,0))
	{
		CString temp(buffer,dwRead);
		temp = temp.Trim();
		text += temp;
	}
	Tokenize(text,T("\n"),devices);
	CComboBox *comboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DEVICES);
	for (int i=1;iAddString(manufacturer+mode);
	}
	if(comboBox->GetCount() > 0)
		comboBox->SetCurSel(0);
}

BOOL CApkInstallerDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	ReadDevices();
	SetDlgItemText(IDC_EDIT_LOG,T("日志"));
	if(_tcslen(szPath) == 0)
		SetDlgItemText(IDC_EDIT_FILE,T("文件路径"));
	else
	{
		SetDlgItemText(IDC_EDIT_FILE,szPath);
		if (CheckApk(szPath))
		{
			//获取包名
			SetSzCommand(T("aapt d badging "),CMD_GET_READ_INFO);
			_tcscat_s(szCommand,szPath);
			AfxBeginThread(ReadThread,this);
		}
	}
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CApkInstallerDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
		CRect rt;
		GetDlgItem(IDC_STATIC_ICO)->GetWindowRect(&rt);
		CPoint p(rt.left,rt.top);
		::ScreenToClient(m_hWnd,&p);

		CDC *pDC = GetDC();
		Graphics graphics(pDC->m_hDC);
		Image *img = NULL;
		ImageFromID(IDB_PNG_ANDROID,img);
		graphics.DrawImage(img,p.x-20,p.y);
		FontFamily fontFamily(L"微软雅黑");
		Gdiplus::Font font(&fontFamily, 11, FontStyleRegular, UnitPoint);
		PointF pointF((REAL)(p.x+10), (REAL)p.y+30);
		SolidBrush solidBrush(Color(255, 0, 0, 0)); 
		//TCHAR string[MAX_PATH] = T("安装器");
		WCHAR string[MAX_PATH] = L"安装器";
		graphics.DrawString(string, (INT)wcslen(string), &font, pointF,&solidBrush);
		if(img != NULL)
			delete img;
		ReleaseDC(pDC);
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CApkInstallerDlg::OnQueryDragIcon()
{
	return static_cast(m_hIcon);
}


void CApkInstallerDlg::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	TCHAR file_name[MAX_PATH] = {0};
	::DragQueryFile(hDropInfo,0, file_name, MAX_PATH);
	SetDlgItemText(IDC_EDIT_FILE,file_name);
	if (CheckApk(file_name))
	{
		//获取包名
		SetSzCommand(T("aapt d badging "),CMD_GET_READ_INFO);
		_tcscat_s(szCommand,file_name);
		AfxBeginThread(ReadThread,this);
	}
	CDialogEx::OnDropFiles(hDropInfo);
}


UINT CApkInstallerDlg::ReadThread(LPVOID pVoid)
{
	try{
		CApkInstallerDlg *dlg = (CApkInstallerDlg*)pVoid;
		WaitForSingleObject(dlg->hEvent,INFINITE);
		dlg->SetWindowText(T("处理中,请稍后..."));
		
		//开始读取
		char buffer[10240] = {0};
		DWORD dwRead = 0;
		HANDLE hReadPipe = NULL;
		dlg->ProcessTask(&hReadPipe,dlg->szCommand);
		CString text;
		while (ReadFile(hReadPipe,buffer,10240,&dwRead,0))
		{
			CString temp(buffer,dwRead);
			GT_UTF8ToGBK(temp);
			text += temp;
		}
		text.Trim();
		if (text.GetLength() > 0)
		{
			 if (dlg->nCommand == CMD_INSTALL_APP)
			{
				dlg->SetDlgItemText(IDC_EDIT_LOG,text);
			}
			else if (dlg->nCommand == CMD_GET_READ_INFO)
			{
				dlg->SetDlgItemText(IDC_EDIT_LOG,text);
				CString temp = T("package: name='");
				int startIndex = text.Find(temp);
				int endIndex = text.Find(T("'"),startIndex+temp.GetLength());
				int nCount = endIndex - startIndex - temp.GetLength();
				if(startIndex >= 0 && nCount > 0)
					dlg->packAge=text.Mid(startIndex+temp.GetLength(),nCount);
			}
			else if (dlg->nCommand == CMD_UNINSTALL)
			{
				if(hReadPipe != NULL)
					CloseHandle(hReadPipe);
				hReadPipe = NULL;
				dlg->ProcessTask(&hReadPipe,dlg->szCommand);
				if (ReadFile(hReadPipe,buffer,10240,&dwRead,0))
				{
					CString new_text(buffer,dwRead);
					new_text = new_text.Trim();
					dlg->SetDlgItemText(IDC_EDIT_LOG,new_text);
				}
			}
		}
		else
		{
			//控制台数据读取失败
			strcpy_s(buffer,"数据读取失败");
		}
		CloseHandle(hReadPipe);
		dlg->SetWindowText(T("处理完成"));
		SetEvent(dlg->hEvent);
	}catch(CException *e)
	{
		TCHAR msg[512];
		e->GetErrorMessage(msg,512);
		AfxMessageBox(msg);
	}
	return 0;
}


UINT CApkInstallerDlg::ProcessTask(HANDLE* hReadPipe,TCHAR* strCommand)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	si.cb = sizeof(STARTUPINFO);
	GetStartupInfo(&si);


	SECURITY_ATTRIBUTES sa = {0};
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	HANDLE hWritePipe = NULL;
	if(!CreatePipe(hReadPipe,&hWritePipe,&sa,0))
	{
		AfxMessageBox(T("创建管道失败"));
		return 0;
	}

	si.hStdOutput = hWritePipe;
	si.hStdError = hWritePipe;
	si.wShowWindow = SW_HIDE;
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	if (CreateProcess (NULL,strCommand,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
	{
		//等待进程执行完毕
		//WaitForSingleObject(pi.hProcess,INFINITE);
		//关闭进程和主线程句柄
		CloseHandle (pi.hProcess);
		CloseHandle (pi.hThread);
	}
	//关闭写入句柄
	CloseHandle(hWritePipe);
	return 0;
}

void CApkInstallerDlg::SetSzCommand(TCHAR* wstr,CMD_TYPE nType)
{
	memset(szCommand,0,sizeof(szCommand));
	_tcscpy_s(szCommand,wstr);
	this->nCommand = nType;
}


void CApkInstallerDlg::OnBnClickedBtnUninstall()
{
	// TODO: 在此添加控件通知处理程序代码
	try
	{
		TCHAR file_name[512] = {0};
		GetDlgItemText(IDC_EDIT_FILE,file_name,512);
		if (CheckApk(file_name))
		{
			SetDlgItemText(IDC_EDIT_LOG,T("正在卸载:")+packAge);
			//卸载
			SetSzCommand(T("adb -s "),CMD_UNINSTALL);
			CComboBox *comboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DEVICES);
			int cur = comboBox->GetCurSel();
			if (cur >= 0 && cur < devices.GetCount()-1)
			{
				CString device = devices.GetAt(cur+1);
				_tcscat_s(szCommand,device);
				_tcscat_s(szCommand,T(" uninstall "));
				_tcscat_s(szCommand,packAge);
				AfxBeginThread(ReadThread,this);
			}
		}
	}
	catch (CException* e)
	{
		TCHAR msg[512];
		e->GetErrorMessage(msg,512);
		MessageBox(msg);
	}
}

void CApkInstallerDlg::OnBnClickedBtnInstall()
{
	// TODO: 在此添加控件通知处理程序代码
	try
	{
		TCHAR file_name[512] = {0};
		GetDlgItemText(IDC_EDIT_FILE,file_name,512);
		if (CheckApk(file_name))
		{
			SetDlgItemText(IDC_EDIT_LOG,T("正在安装:")+CString(file_name));
			SetSzCommand(T("adb -s "),CMD_INSTALL_APP);
			CComboBox *comboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DEVICES);
			int cur = comboBox->GetCurSel();
			if (cur >= 0 && cur < devices.GetCount()-1)
			{
				CString device = devices.GetAt(cur+1);
				_tcscat_s(szCommand,device);
				_tcscat_s(szCommand,T(" install "));
				_tcscat_s(szCommand,file_name);
				AfxBeginThread(ReadThread,this);
			}
		}
	}
	catch (CException* e)
	{
		TCHAR msg[512];
		e->GetErrorMessage(msg,512);
		MessageBox(msg);
	}
}


BOOL CApkInstallerDlg::CheckApk(TCHAR* path)
{
	try
	{
		TCHAR* exist = _tcsstr(path,T("apk"));
		if (exist == NULL)
		{
			MessageBox(T(""));
			return FALSE;
		}
		CFileFind finder;
		if(!finder.FindFile(path))
		{
			MessageBox(T("指定文件不存在"));
			return FALSE;
		}
	}
	catch (CException* e)
	{
		TCHAR msg[512];
		e->GetErrorMessage(msg,512);
		MessageBox(msg);
	}
	return TRUE;
}

void CApkInstallerDlg::OnBnClickedBtnReg()
{
	// TODO: 在此添加控件通知处理程序代码
	TCHAR szName[512];
	GetModuleFileName(NULL,szName,sizeof(szName)*sizeof(TCHAR));
	AssociateFile(".apk",szName);
}

项目源码下载:ApkInstaller编译好的APP:Release

本文链接:https://www.it72.com/1528.htm

推荐阅读
最新回复 (0)
    返回