Windows Mobile .NET version detection at install
Question: When I install my Windows Mobile application on device not having NET CF 3.5, it fails to run. What to do?
When you create a cabinet (.cab) file, you can choose to add an optional tailor-made setup.dll file to check out the version of OS and .NET framework.
See http://msdn.microsoft.com/en-us/library/aa924308.aspx.
Packaging a Smart Device Solution for Deployment: http://msdn.microsoft.com/en-us/library/zcebx8f8(VS.80).aspx
Insert a version detection function into yours Install_Init() method. See our sample code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | // Setup.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "ce_setup.h" #include "Setup.h" #define MIN_DOTNETCF_VERSION 3 BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // ---------------------------------------------------------- // Variables TCHAR ErrorMessageTitle[] = _T("RandomFacts Setup Error"); TCHAR ErrorMessageNet[] = _T("Microsoft Windows Mobile 6.0+ and NET CF 3.5+ are required to run our applications.\n") _T("You can download the latest updates from Microsoft.\n") _T("Visit http://www.microsoft.com/windowsmobile for details.\n"); // ---------------------------------------------------------- // This function will be called when the user // tries to install the cab. According to its return // value the installation continues or is cancelled. // As this could be called more than once // (i.e. if there is not enough space on the target) // we should take care about fFirstCall parameter // to show the dialog only once. // To continue installation, return codeINSTALL_INIT_CONTINUE // If you want to cancel installation, // return codeINSTALL_INIT_CANCEL codeINSTALL_INIT Install_Init(HWND hwndParent, BOOL fFirstCall, BOOL fPreviouslyInstalled, LPCTSTR pszInstallDir ) { if( fFirstCall ){ if( ::IsDotNetInstalled(MIN_DOTNETCF_VERSION) == false ){ ::MessageBox(hwndParent, ErrorMessageNet, ErrorMessageTitle, MB_OK); return codeINSTALL_INIT_CANCEL; } } return codeINSTALL_INIT_CONTINUE; } // ---------------------------------------------------------- // Queries the registry to see if .NET 3.0 or above is installed bool IsDotNetInstalled(int MinMajorVer) { HKEY regKey; TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name DWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys=0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time LPDWORD data; DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\.NETCompactFramework"), 0, 0, ®Key ); if (result == ERROR_SUCCESS){ // Get the class name and the value count. retCode = RegQueryInfoKey( regKey, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // Enumerate the key values. if (cValues) { for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) { cchValue = MAX_VALUE_NAME; achValue[0] = '\0'; retCode = RegEnumValue(regKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL); if (achValue[0] >= '0' && achValue[0] <= '9') { int digit = achValue[0] - '0'; if (digit >= MinMajorVer) // Above MinMajorVer { return true; } } } } } return false; } |
If you want to sell your app on the Windows Marketplace, you don’t need to take care about the required .NET CF versions. Microsoft did a great job here.

