Wednesday, July 27, 2005 8:36 PM bart

.NET Framework Checker (C++)

Update: Text in red was added as a response to Leon's feedback post concerning the recommended way of checking for .NET Framework presence on the system through registry keys. Through the updated code, you'll be able to use both mechanisms (policy key and installation key) based on precompiler directives.

Today I received an e-mail from someone who read my article on running ASP.NET apps from a CD-ROM. However, he had the following question:

Your articles describe in detail what should I do but first of all the client which "run the CD" must have the .NET Framework installed?
 
If your answer is YES as I suppose:
There is a way to check if the framework is installed on the client and if not to launch the set up of dotnetfx.exe?

Pretty good question indeed, how to detect the .NET Framework is present on the system. To do this, I wrote a little application to check the registry for the corresponding policy key (under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy, also used by the startup shim mscoree.dll for FX detection) in unmanaged C++ (therefore it runs on any Windows installation, regardless of .NET Framework installations). Here's the (quick-n-dirty?) code:

#define ANFP

#include
#include

/**************************************************************************************************
*
* Function to check for the presence of a given version of the .NET Framework on the machine.
*
* Parameters:
* - major version (e.g. 1)
* - minor version (e.g. 1)
* - build number (e.g. 4322)
*
* Returns:
* - 0 when not found
* - 1 when found
*
**************************************************************************************************/
int check(int major, int minor, int build)
{
   //
  
//Variables for registry functions parameter construction
  
//
   char root[1024];
#ifdef ANFP
   char bld[1024];
#endif

   //
   //Registry key
   //
   HKEY hkey;

   //
   //Registry type, value, result buffer
   //
   DWORD dwType = REG_SZ;
#ifdef ANFP
  
DWORD dwSize;
   char buffer[1024];
#endif

   //
   //Found flag
   //
   int found = FALSE;

   //
   //Registry functions parameter construction
   //
#ifdef ANFP
  
wsprintf(root, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v%d.%d", major, minor);
   wsprintf(bld, "%d", build);
#else
   wsprintf(root, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v%d.%d.%d", major, minor, build);
#endif

   //
   //Open registry key
   //
   if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, root, 0, KEY_QUERY_VALUE, &hkey))
   {
#ifdef ANFP
      //
      //Read registry value
      //
      if (ERROR_SUCCESS == RegQueryValueEx(hkey, bld, NULL, &dwType, (unsigned char*) &buffer, &dwSize))
         found = TRUE;
#else
      found = TRUE;
#endif

      //
      //Close registry key
      //
      RegCloseKey(hkey);
   }

   return found;
}

/**************************************************************************************************
*
* Main entry point.
*
* Parameters:
* - number of command-line arguments
* - array with command-line arguments
*
* Returns:
* - -1 on invalid syntax
* - 1 if version was found
* - 0 if version wasn't found
*
* Syntax:
*   
*
* Sample:
*    1 1 4322 managedapp.exe dotnetfx.exe
*
**************************************************************************************************/
int main(int argc, char **argv)
{
   //
   //Variables declaration for version numbers and found status
   //
   int major, minor, build, found;

   //
   //Syntax check
   //
   if (6 != argc)
   {
      printf("Bart's .NET Framework checker\n");
      printf("-----------------------------\n\n");
      printf("Usage: %s \nSample: %s 1 1 4322 managedapp.exe dotnetfx.exe\n\n", argv[0], argv[0]);
      return -1;
   }

   //
   //Version info
   //
   major = atoi(argv[1]);
   minor = atoi(argv[2]);
   build = atoi(argv[3]);

   //
   //Perform the check
   //
   found = check(major,minor,build);

   //
   //Execute actions
   //
   if (found)
      system(argv[4]);
   else
      system(argv[5]);

   //
   //Return status
   //
   return found;
}

You can download the compiled too via http://www.bartdesmet.net/download/fxcheck.exe.zip too. Update: The version that's available for download is compiled with ANFP defined. Unzip and test as follows:

C:\>fxcheck.exe 1 1 4323 "echo OK" "echo NOK"
NOK

C:\>fxcheck.exe 1 1 4322 "echo OK" "echo NOK"
OK

This should be the output on a machine with .NET v1.1 installed. Enjoy! Any comments whatsoever are welcome of course.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Comments

# re: .NET Framework Checker (C++)

Wednesday, July 27, 2005 9:48 PM by bart

Microsoft docs recommend to check the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\vx.x.xxx
Install - 1/0
This is for .NET 1.1 and up

# re: .NET Framework Checker (C++)

Wednesday, July 27, 2005 10:04 PM by bart

Right, in this first demo development I took the registry key that's mentioned in "Applied .NET Framework Programming" concerning the mscoree.dll startup shim. I'll update my post to provide both ways of checking.

# re: .NET Framework Checker (C++)

Saturday, August 27, 2005 2:14 PM by bart

# Framework checker | Trkiyecumhuriy

Sunday, November 20, 2011 6:51 AM by Framework checker | Trkiyecumhuriy

Pingback from  Framework checker | Trkiyecumhuriy