.NET 开发效率高, 大行其道. 但却一直存在一个比较头疼的通病, 需要安装 .NET Framework, 尤其是.NET 2.0开发的软件. Windows XP 和 Windows 2003 默认都没有.NET 2.0 运行环境. 特别是一些精简版, 譬如"番茄花园"之类的版本, 连.NET2.0都装不上. 现在我们利用移动飞信的原理, 来解决以上的问题.
1. 安装完移动飞信2008后, 一般我们在 C:/Program Files/China Mobile/Fetion/ 目录里可以看到今天关键的主角:
Fetion.exe 启动飞信时首先会先运行这个程序, 用来检测本机是否有.NET环境, 如果有则运行FetionFx.exe, 如果没有则调用VMDotNet这个文件夹里的(v2.0.50727/FetionVM.exe)这个虚拟环境来处理.
FetionFx.exe 飞信真正的主程序, 需要.NET 2.0环境.
VMDotNet .NET2.0虚拟运行环境, 支持的版本为2.0.50727.
2. 介绍完这三个主角后, 我们来看一个简单的实例: 在一个没有安装过.NET 2.0的系统里, 把VMDotNet复制到D盘, 再复制一个你自己编写的.NET程序, 比如Test.exe, 放在D盘. 然后在开始菜单里的"运行"输入以下命令:
D://VMDotNet/v2.0.50727/FetionVM.exe D://Test.exe
你会发现神奇的事情出现了, Test.exe正常运行.
3. 你开始会有疑问了, 我如何像飞信那样直接运行, 而不是通过命令行呢?
1) 利用Fetion.exe来加载, 那样的话, 就需要把你自己的主程序改名为FetionFx.exe
2) 自己编写一个Win32程序来处理加载过程. 以下是详细步骤.
a) 在VS 2005/2008 里, 新建一个C++ Win32程序, 命名为XStart.
b) 在项目的源文件里找到XStart.cpp, 打开后找到里面的函数InitInstance代码, 并加入关键代码的处理.
c) 编译完成, 把XStart.exe复制到Test.exe和VMDotNet所在的目录, 运行XStart.exe, 大功告成!!!
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // 将实例句柄存储在全局变量中
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return FALSE;
- }
- nCmdShow = SW_HIDE;
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- //===========我们加入的代码开始==============
- using namespace std;
- bool started = false;
- try
- {
- char * args = (char*)lpArguments;
- if(strcmp(args, "*") == 0)
- {
- ::Sleep(3000);
- }
- TCHAR path[1024];
- GetSystemDirectory(path, 1024);
- wcscat_s(path, _T("//mscoree.dll"));
- fstream _file(path, ios::in);
- if(!_file)
- {
- //没有找到 mscoree.dll
- ::WinExec("VMDotNet/v2.0.50727/FetionVM.exe Test.exe", SW_SHOW);
- started = true;
- }
- HKEY hkey;
- if(::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE//Microsoft//.NETFramework//Policy//v2.0"), 0, KEY_READ, &hkey)
- != ERROR_SUCCESS)
- {
- //没有找到2.0版本
- ::RegCloseKey(hkey);
- ::WinExec("VMDotNet/v2.0.50727/FetionVM.exe Test.exe", SW_SHOW);
- started = true;
- }
- DWORD type = REG_SZ;
- DWORD data = 80;
- if(::RegQueryValueEx(hkey, _T("50727"), NULL , &type, NULL, &data) != ERROR_SUCCESS)
- {
- //没有找到2.0.50727版本
- ::RegCloseKey(hkey);
- ::WinExec("VMDotNet/v2.0.50727/FetionVM.exe Test.exe", SW_SHOW);
- started = true;
- }
- if(!started)
- {
- //直接运行
- ::RegCloseKey(hkey);
- ::WinExec("Test.exe", SW_SHOW);
- }
- }
- catch(...)
- {
- ::MessageBox(hWnd, _T("Sorry! Start program failed. /r/n/r/n对不起,程序启动失败!"), _T(" 启动失败 "), MB_ICONERROR);
- }
- ::ExitProcess(0);
- //=============我们加入的代码结束==============
- return TRUE;
- }