2011-12-21 7 views
6

सिस्टम: Windows 7 32 बिट
भाषा: - कोई समस्या नहीं सी ++रजिस्ट्री कुंजी से पढ़ने का प्रयास करते समय RegQueryValueEx() फ़ंक्शन ERROR_FILE_NOT_FOUND क्यों लौटाता है?

मैं कुंजी Driver (प्रकार REG_SZ) रजिस्टर HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0 का उपयोग करने की कोशिश की है।

HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM से पढ़ने के लिए, सभी कुंजी (प्रकार REG_SZ) स्लैश हो गए, उदाहरण के लिए \Device\Serial0

हालांकि ऐसे कुंजी यह हमेशा 2 (ऐसी कोई फाइल नहीं) देता है निम्न उदाहरण कोड के साथ पढ़ने:

HKEY hKey = 0; 
DWORD dwType = REG_SZ; 
char buf[255] = {0}; 
DWORD dwBufSize = sizeof(buf); 

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) 
{ 
    auto ret = RegQueryValueEx(hKey, TEXT("\Device\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize); 
    // ret always == 2 for key with slashes 
--- CUT --- 

नाम पर स्लैश के साथ कुंजी मान को पढ़ने के लिए उचित तरीका क्या है?


ऊपर कोडी ग्रे द्वारा उचित उत्तर दिया गया है।
एक और मुद्दा नीचे


इम जब चर का उपयोग कर किसी पाठ स्ट्रिंग के बजाय मैं एक ही समस्या हो रही है।
चतुर्थ माना दोनों सिंगल और डबल स्लैश के साथ दृष्टिकोण:

HKEY hKey = 0; 
DWORD keyType = REG_SZ; 
TCHAR buf[255] = {0}; 
DWORD bufSize = sizeof(buf); 

QSettings winReg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat); 
auto comsKey = winReg.allKeys(); 

FOREACH(auto com, comsKey) 
{ 
    // FOREACH - boost macro 
    // comsKey = QList<QString> (list of key names) [from Qt framework] 
    // com = QString (single key name) [from Qt framework] 
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) 
    { 
    wchar_t* keyw = new wchar_t(); 
    //com.replace("/", "\\\\"); <- checked both variants commented and not commented; com == /Device/Serial0 so im converting to \\Device\\Serial0 
    int size = com.size(); 
    mbstowcs(keyw, com.toStdString().data(), size); 
    //auto ret = RegQueryValueEx(hKey, TEXT("\\Device\\Serial0"), 0, &keyType, (LPBYTE)buf, &bufSize); // <- this works! 
    auto ret = RegQueryValueExW(hKey, (LPCWSTR)&keyw, 0, &keyType, (LPBYTE)buf, &bufSize); // <- this one not works! 

मैं के साथ सभी वेरिएंट की कोशिश की है "\ डिवाइस .." "/ डिवाइस", "\ डिवाइस", आदि

+3

पाठ ("\\ डिवाइस \\ Serial0")? –

+0

@ वर्नर, नहीं, 'RegQueryValueEx' फ़ंक्शन * केवल * रजिस्ट्री कुंजी के मान से पूछताछ करता है। मूल्य कुंजी के भीतर संग्रहीत नाम/डेटा जोड़े हैं। इसलिए जब आप वर्णन करते हैं तो आप इसे चाबियों का घोंसला पथ नहीं पारित कर सकते हैं क्योंकि मानों में पथ नहीं होते हैं। माना जाता है कि शब्दावली काफी उलझन में है, रेमंड चेन ने इसे समझाने का प्रयास किया [यहां] (http://blogs.msdn.com/b/oldnewthing/archive/2009/02/04/9394113.aspx)। –

उत्तर

7

आपके पास स्लैश से बचने के लिए, जैसा कि आप पहली पंक्ति में था ...

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) 
{ 
    auto ret = RegQueryValueEx(hKey, TEXT("\\Device\\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize); 
    // ret always == 2 for key with slashes 

आप नहीं, RegQueryValueEx समारोह निर्दिष्ट कुंजी नहीं मिल सकता है, और यह ERROR_FILE_NOT_FOUND रिटर्न (== 2)।


लेकिन एक और समस्या है। आप प्रकार wchar_t (या TCHAR) के रूप में बफर सरणी घोषित किया जाना चाहिए, बल्कि char से:

TCHAR buf[255] = {0}; 

अन्यथा, RegQueryValueEx समारोह एक यूनिकोड स्ट्रिंग निर्दिष्ट रजिस्ट्री कुंजी से पढ़ने के साथ सरणी को भरने के लिए प्रयास करने के लिए जा रहा है, और आप कुछ अपठनीय पाने जा रहे हैं।

+0

buf को tCHAR के रूप में घोषित किया जाना चाहिए, wchar_t के रूप में नहीं। ReqQueryValueEx इस बात पर परवाह नहीं करता कि कैसे बफ घोषित किया जाता है, लौटाया गया मूल्य इस पर निर्भर करता है कि RegQueryValueExA या RegQueryValueExW को कॉल किया गया है या नहीं। –

+0

@Werner: हाँ, यह तकनीकी रूप से सच है।लेकिन विंडोज़ अनुप्रयोगों को 10 से अधिक वर्षों तक एएनएसआई (गैर-यूनिकोड) के रूप में संकलित नहीं किया गया है। बहुत से लोग अब मैक्रोज़ का उपयोग करने की परवाह नहीं करते हैं, और उन्हें दोष देना मुश्किल है। –

+0

ओपी को कठिन समय देने के लिए आपका उत्तर अपेक्षाकृत अनुकूलित है। सी ++ 11 सिंटैक्स, डब्ल्यूएमआई सी ++ में काफी असभ्य है, सीरियल पोर्ट प्लग-एंड-प्ले डिवाइस नहीं हैं। –

0
using System; 
using System.IO.Ports; 

namespace SerialPortExample 
{ 
    class SerialPortExample 
    { 
     public static void Main() 
     { 
      // Get a list of serial port names. 
      string[] ports = SerialPort.GetPortNames(); 

      Console.WriteLine("The following serial ports were found:"); 

      // Display each port name to the console. 
      foreach(string port in ports) 
      { 
       Console.WriteLine(port); 
      } 

      Console.ReadLine(); 
     } 

    } 
} 

देखें http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames(v=vs.110).aspx

+1

हम .NET का उपयोग नहीं कर रहे हैं – killdaclick

संबंधित मुद्दे