Browse Source

ENH: add functions to API (read, write, delete registry key value)

Sebastien Barre 23 years ago
parent
commit
92897bf3a8
3 changed files with 232 additions and 24 deletions
  1. 39 11
      Source/ccommand.cxx
  2. 178 13
      Source/cmSystemTools.cxx
  3. 15 0
      Source/cmSystemTools.h

+ 39 - 11
Source/ccommand.cxx

@@ -22,13 +22,21 @@ void CMakeCommandUsage(const char* program)
 {
   std::strstream errorStream;
 
-  errorStream << "cmake version " << cmMakefile::GetMajorVersion()
-	      << "." << cmMakefile::GetMinorVersion() << "\n";
-  errorStream << "Usage: " << program << " [command] [arguments ...]\n"
-	      << "Available commands: \n"
-	      << "  copy file destination  - copy file to destination (either file or directory)\n"
-	      << "  remove file1 file2 ... - remove the file(s)\n";
-  errorStream << std::ends;
+  errorStream 
+    << "cmake version " << cmMakefile::GetMajorVersion()
+    << "." << cmMakefile::GetMinorVersion() << "\n";
+
+  errorStream 
+    << "Usage: " << program << " [command] [arguments ...]\n"
+    << "Available commands: \n"
+    << "  copy file destination  - copy file to destination (either file or directory)\n"
+    << "  remove file1 file2 ... - remove the file(s)\n"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    << "  write_regv key value   - write registry value\n"
+    << "  delete_regv key        - delete registry value\n"
+#endif
+    << std::ends;
+
   cmSystemTools::Error(errorStream.str());
 }
 
@@ -40,16 +48,19 @@ int main(int ac, char** av)
     args.push_back(av[i]);
     }
 
-  if ( args.size() > 1 )
+  if (args.size() > 1)
     {
-    if ( args[1] == "copy" && args.size() == 4 )
+    // Copy file
+    if (args[1] == "copy" && args.size() == 4)
       {
       cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str());
       return cmSystemTools::GetErrorOccuredFlag();
       }
-    if ( args[1] == "remove" && args.size() > 2 )
+
+    // Remove file
+    else if (args[1] == "remove" && args.size() > 2)
       {
-      for ( std::string::size_type cc = 2; cc < args.size(); cc ++ )
+      for (std::string::size_type cc = 2; cc < args.size(); cc ++)
 	{
         if(args[cc] != "-f")
           {
@@ -62,7 +73,24 @@ int main(int ac, char** av)
 	}
       return 0;
       }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    // Write registry value
+    else if (args[1] == "write_regv" && args.size() > 3)
+      {
+      return cmSystemTools::WriteRegistryValue(args[2].c_str(), 
+                                               args[3].c_str()) ? 0 : 1;
+      }
+
+    // Delete registry value
+    else if (args[1] == "delete_regv" && args.size() > 2)
+      {
+      return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
+      }
+#endif
+
     }
+
   ::CMakeCommandUsage(args[0].c_str());
   return 1;
 }

+ 178 - 13
Source/cmSystemTools.cxx

@@ -194,17 +194,17 @@ void cmSystemTools::ReplaceString(std::string& source,
     }
 }
 
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-// Get the data of key value.
+// Read a registry value.
 // Example : 
 //      HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
 //      =>  will return the data of the "default" value of the key
 //      HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
 //      =>  will return the data of the "Root" value of the key
-bool ReadAValue(std::string &res, const char *key)
+
+bool cmSystemTools::ReadRegistryValue(const char *key, std::string &value)
 {
-  // find the primary key
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
   std::string primary = key;
   std::string second;
   std::string valuename;
@@ -214,11 +214,13 @@ bool ReadAValue(std::string &res, const char *key)
     {
     return false;
     }
+
   size_t valuenamepos = primary.find(";");
   if (valuenamepos != std::string::npos)
     {
     valuename = primary.substr(valuenamepos+1);
     }
+
   second = primary.substr(start+1, valuenamepos-start-1);
   primary = primary.substr(0, start);
   
@@ -245,8 +247,11 @@ bool ReadAValue(std::string &res, const char *key)
     }
   
   HKEY hKey;
-  if(RegOpenKeyEx(primaryKey, second.c_str(), 
-		  0, KEY_READ, &hKey) != ERROR_SUCCESS)
+  if(RegOpenKeyEx(primaryKey, 
+                  second.c_str(), 
+		  0, 
+                  KEY_READ, 
+                  &hKey) != ERROR_SUCCESS)
     {
     return false;
     }
@@ -255,19 +260,181 @@ bool ReadAValue(std::string &res, const char *key)
     DWORD dwType, dwSize;
     dwSize = 1023;
     char data[1024];
-    if(RegQueryValueEx(hKey, (LPTSTR)valuename.c_str(), NULL, &dwType, 
-                       (BYTE *)data, &dwSize) == ERROR_SUCCESS)
+    if(RegQueryValueEx(hKey, 
+                       (LPTSTR)valuename.c_str(), 
+                       NULL, 
+                       &dwType, 
+                       (BYTE *)data, 
+                       &dwSize) == ERROR_SUCCESS)
       {
       if (dwType == REG_SZ)
         {
-        res = data;
+        value = data;
         return true;
         }
       }
     }
+#endif
+  return false;
+}
+
+
+// Write a registry value.
+// Example : 
+//      HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+//      =>  will set the data of the "default" value of the key
+//      HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+//      =>  will set the data of the "Root" value of the key
+
+bool cmSystemTools::WriteRegistryValue(const char *key, const char *value)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+  std::string primary = key;
+  std::string second;
+  std::string valuename;
+ 
+  size_t start = primary.find("\\");
+  if (start == std::string::npos)
+    {
+    return false;
+    }
+
+  size_t valuenamepos = primary.find(";");
+  if (valuenamepos != std::string::npos)
+    {
+    valuename = primary.substr(valuenamepos+1);
+    }
+
+  second = primary.substr(start+1, valuenamepos-start-1);
+  primary = primary.substr(0, start);
+  
+  HKEY primaryKey;
+  if (primary == "HKEY_CURRENT_USER")
+    {
+    primaryKey = HKEY_CURRENT_USER;
+    }
+  if (primary == "HKEY_CURRENT_CONFIG")
+    {
+    primaryKey = HKEY_CURRENT_CONFIG;
+    }
+  if (primary == "HKEY_CLASSES_ROOT")
+    {
+    primaryKey = HKEY_CLASSES_ROOT;
+    }
+  if (primary == "HKEY_LOCAL_MACHINE")
+    {
+    primaryKey = HKEY_LOCAL_MACHINE;
+    }
+  if (primary == "HKEY_USERS")
+    {
+    primaryKey = HKEY_USERS;
+    }
+  
+  HKEY hKey;
+  DWORD dwDummy;
+  if(RegCreateKeyEx(primaryKey, 
+                    second.c_str(), 
+                    0, 
+                    "",
+                    REG_OPTION_NON_VOLATILE,
+                    KEY_WRITE,
+                    NULL,
+                    &hKey,
+                    &dwDummy) != ERROR_SUCCESS)
+    {
+    return false;
+    }
+  else
+    {
+    if(RegSetValueEx(hKey, 
+                     (LPTSTR)valuename.c_str(), 
+                     0, 
+                     REG_SZ, 
+                     (CONST BYTE *)value, 
+                     (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS)
+      {
+      return true;
+      }
+    }
+#endif
   return false;
 }
+
+
+// Delete a registry value.
+// Example : 
+//      HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+//      =>  will delete the data of the "default" value of the key
+//      HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+//      =>  will delete  the data of the "Root" value of the key
+
+bool cmSystemTools::DeleteRegistryValue(const char *key)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+  std::string primary = key;
+  std::string second;
+  std::string valuename;
+ 
+  size_t start = primary.find("\\");
+  if (start == std::string::npos)
+    {
+    return false;
+    }
+
+  size_t valuenamepos = primary.find(";");
+  if (valuenamepos != std::string::npos)
+    {
+    valuename = primary.substr(valuenamepos+1);
+    }
+
+  second = primary.substr(start+1, valuenamepos-start-1);
+  primary = primary.substr(0, start);
+  
+  HKEY primaryKey;
+  if (primary == "HKEY_CURRENT_USER")
+    {
+    primaryKey = HKEY_CURRENT_USER;
+    }
+  if (primary == "HKEY_CURRENT_CONFIG")
+    {
+    primaryKey = HKEY_CURRENT_CONFIG;
+    }
+  if (primary == "HKEY_CLASSES_ROOT")
+    {
+    primaryKey = HKEY_CLASSES_ROOT;
+    }
+  if (primary == "HKEY_LOCAL_MACHINE")
+    {
+    primaryKey = HKEY_LOCAL_MACHINE;
+    }
+  if (primary == "HKEY_USERS")
+    {
+    primaryKey = HKEY_USERS;
+    }
+  
+  HKEY hKey;
+  if(RegOpenKeyEx(primaryKey, 
+                  second.c_str(), 
+		  0, 
+                  KEY_WRITE, 
+                  &hKey) != ERROR_SUCCESS)
+    {
+    return false;
+    }
+  else
+    {
+    if(RegDeleteValue(hKey, 
+                      (LPTSTR)valuename.c_str()) == ERROR_SUCCESS)
+      {
+      return true;
+      }
+    }
 #endif
+  return false;
+}
+
 
 // replace replace with with as many times as it shows up in source.
 // write the result into source.
@@ -288,7 +455,7 @@ void cmSystemTools::ExpandRegistryValues(std::string& source)
     // the arguments are the second match
     std::string key = regEntry.match(1);
     std::string val;
-    if (ReadAValue(val,key.c_str()))
+    if (ReadRegistryValue(key.c_str(), val))
       {
       std::string reg = "[";
       reg += key + "]";
@@ -305,8 +472,6 @@ void cmSystemTools::ExpandRegistryValues(std::string& source)
 }
 
 
-
-
 std::string cmSystemTools::EscapeQuotes(const char* str)
 {
   std::string result = "";

+ 15 - 0
Source/cmSystemTools.h

@@ -50,6 +50,21 @@ public:
   static void ExpandListArguments(std::vector<std::string> const& argsIn,
                                   std::vector<std::string>& argsOut);
 
+  /**
+   * Read a registry value
+   */
+  static bool ReadRegistryValue(const char *key, std::string &value);
+
+  /**
+   * Write a registry value
+   */
+  static bool WriteRegistryValue(const char *key, const char *value);
+
+  /**
+   * Delete a registry value
+   */
+  static bool DeleteRegistryValue(const char *key);
+
   /**
    * Look for and replace registry values in a string
    */