用VC实现检测AIR是否安装,下载安装文件,并以“安静”模式安装

我在项目中用VC实现的,测试环境是VS2008,vista/xp。

首先先讲明几点:

  • 中间有一段下载安装文件的代码,和自定义的窗口来显示下载进度,如果你本身已经有安装文件在旁边,就删掉这一段。整个主线程是一跑到底的。不需要啥就删啥
  • 在vista下编译,要把UAC级别设成requireAdministator,不然会因为权限问题AIR装不上
  • 我在项目中用win32工程的,带MFC动态链接。如果要改成console application应该也行。
  • 安装完毕后,它会执行air的exe,所以首先你要解包.air,方法就是先自己安装一遍,然后把安装文件复制出来,应该能看到一个swf和同名的exe,那个exe就是air的启动入口
  • 显示下载的还用到一个自定义类,垃圾代码太多不想贴了,要的话可以问我要,单独给了
  • 要转载请注上出处,原创的不容易啊,谢谢了。
// airloader.cpp : 定义应用程序的入口点。
//
 
#include "stdafx.h"
 
#include "selectsock.h"
#include "airloader.h"
#include "ImpMonikerCallback.h"
 
#include "process.h"
#include "shellapi.h"
#include "Urlmon.h"
#include "Resource.h"
#include "Wininet.h"
 
#pragma comment(lib,"Urlmon.lib")
 
//////////////////////////////////////////////////////////////////////////
 
#define AIRFILE "test.exe"
#define AIR_RUNTIME_OFFLINE "AdobeAIRInstaller.exe"
#define AIR_RUNTIME_ONLINE "http://airdownload.adobe.com/air/win/download/latest/AdobeAIRInstaller.exe"
#define AIR_SILENT_PARAM "-silent"
 
//////////////////////////////////////////////////////////////////////////
 
HWND hProgressBox;
DWORD mainThreadId;
/*
BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 
	switch(message)
	{
	case WM_INITDIALOG:
		SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETRANGE, 0, MAKELPARAM(0,100));
		SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETPOS, 0, 0L);
		return TRUE;
	case WM_MOUSEACTIVATE:
		return TRUE;
 
	}
	return FALSE;
}
*/
 
/************************************************************************/
/* run it in another thread                                             */
/************************************************************************/
DWORD WINAPI DownloadProcess(LPVOID p)
{
	CImpMonikerCallback* lpcallback = (CImpMonikerCallback*)p;
	HRESULT hresult = URLDownloadToFile(NULL, _T(AIR_RUNTIME_ONLINE), _T(AIR_RUNTIME_OFFLINE), NULL, lpcallback);
	//SendMessage(hProgressBox, WM_CLOSE, 0,0);
	PostThreadMessage(mainThreadId, WM_CLOSE, 0, 0);
 
	return 0;
}
 
/************************************************************************/
/* check if the air runtime is installed. the method is, search .air in HKEY_CLASSES_ROOT key.*/
/************************************************************************/
BOOL isAIRRuntimeExist()
{
	HKEY hKey = NULL;
	LONG hResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT(".air"), NULL, KEY_READ, &hKey);
	return (hResult==ERROR_SUCCESS)?TRUE:FALSE;
}
 
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	/*
	GraphInit();
	GraphCap("C:\\Users\\jonson\\Desktop\\dddd.mp3");
	Sleep(8000);
	GraphShutDown();
	*/
 
	HKEY hKey = NULL;
	//get main thread id
	mainThreadId = GetCurrentThreadId();
 
	//check air runtime
	if (!isAIRRuntimeExist())
	{
		//if the air has not been installed, then first check disk if the install file is there
		if (_access(AIR_RUNTIME_OFFLINE,0) == -1)
		{
			//user do not have installer file now, give him a Alert then download installer from adobe site
			if (MessageBox(NULL, _T("application will take a few time to configurate AIR runtime, press OK to continue.."),_T("warning"),MB_YESNO)==IDNO)
			{
				return 0;
			}
 
			//check if user is connecting internet
			if (InternetAttemptConnect(0) != ERROR_SUCCESS)
			{
				MessageBox(NULL, _T("you are offline, please connect to internet first, then restart"),_T("warning"),MB_OK);
				return 0;
			}
 
			//create dialog to show the downloading progress
			hProgressBox = CreateDialog(hInstance, MAKEINTRESOURCE(IID_DLG), NULL, NULL);
			ShowWindow(hProgressBox, SW_SHOW);
			CImpMonikerCallback callback;
			callback.hpp = hProgressBox;
 
			//downloading in another thread
			CreateThread(0,0,DownloadProcess,(LPVOID)&callback,0,0);
 
			// message queue
			MSG msg;
			while (1)
			{
				if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					if (msg.hwnd == hProgressBox)
					{
						switch (msg.message)
						{
						case WM_INITDIALOG:
							SendMessage(GetDlgItem(hProgressBox, IDC_PROGRESS), PBM_SETRANGE, 0, MAKELPARAM(0,100));
							SendMessage(GetDlgItem(hProgressBox, IDC_PROGRESS), PBM_SETPOS, 0, 0L);
							break;
						}
					}
					else if(msg.message == WM_CLOSE)
					{
						DestroyWindow(hProgressBox);
						break;
					}
 
					TranslateMessage(&msg);
					DispatchMessage(&msg);
 
				}
				else
				{
					Sleep(50);
				}
			}
		}
 
		//create a process to install silently, the mainthread have to be blocked till finishing installing
		STARTUPINFO si;
		PROCESS_INFORMATION pi;
		ZeroMemory(&si, sizeof(si));
		ZeroMemory(&pi, sizeof(pi));
		CreateProcess(_T(AIR_RUNTIME_OFFLINE),_T(AIR_SILENT_PARAM),NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi);
		WaitForSingleObject(pi.hProcess, INFINITE);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}
 
	// check the existing of AIR file
	if(_access(AIRFILE,0) == -1)
	{
		//file does not exist
		MessageBox(NULL, _T("AIR file does not exist"), _T("Error"), MB_OK);
		return 0;
	}
	//launch air application
	ShellExecute(NULL, _T("open"),_T(AIRFILE),NULL,NULL,SW_SHOW);
	//socket server
	printf("==== socket server starts ====\n");
	RunSock();
	printf("==== socket server stops =====\n");
 
	return 0;
}

RELATED POSTS

7 Comments

  1. 聂曙廷 says:

    我现在在做一个基于AIR的课件播放器,是要刻在光盘上对外发布。光盘自动运行的引导程序是用VC编译的autorun.exe,是参考您的教程开发的。先谢谢您了。但是经过测试后,发现一个问题:即不能以安静模式安装air虚拟机。就是当第一次运行autorun.exe时,会弹出安装界面的。我从控制面板中卸载了AIR后,再运行一次autorun.exe时,就以安静模式安装了,不会出现安装界面。
    能加我QQ具体说吗?QQ:251165675

  2. 尹立稳 says:

    你好,先谢谢你共享的代码.我现在在做一个类似的小项目,看了一下你在上面贴的源代码?很少用VS2008,暂时没有编译通过,(VS2008,WIN2003SP2)你能够给我一份完整的吗?先谢谢了,我的QQ1007035002,在线等……

  3. 尹立稳 says:

    忘记告诉邮箱了,lylw521@163.com
    谢谢 ,学习了

  4. 尹立稳 says:

    我的邮箱,lylw521@163.com
    学习ing… …

  5. Vio.Lam says:

    您的这个方法非常好,是我一直想要却没能力做的。
    不过我在想您是不是能再接再厉继续把它加强,搞一个自动安装runtime和air作品一体化的小东西呢?这样开发人士只需要把runtime和air文件打包,然后运行这个东西来安装就行了,省去了好多复杂的安装步骤哦。

  6. buy soma says:

    nice site you have!

  7. pest control says:

    On my it is better to use the functions of Wininet

Leave a Reply