2016-09-13 2 views
1

Я искал в Интернете, и у меня проблемы с поиском решения этой проблемы.Чтение ключей реестра из VBA с помощью Windows Shell

В основном я пытаюсь выполнить запрос реестра с правами администратора, используя Shell.Application из VBA, чтобы прочитать значение TypeGuessRows (и в конечном итоге изменить его на 0, чтобы данные Excel могли быть правильно запрошены с использованием ADOdb). Я придумал следующую подпрограмму:

Sub Read_Registry_Value() 

'Declare variables 
Dim reg_key_location As String 
Dim reg_key_name As String 
Dim wsh As Object 

'Define registry key path and name 
reg_key_location = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel" 
reg_key_name = "TypeGuessRows" 

'Create instance of windows shell 
Set wsh = VBA.CreateObject("Shell.Application") 

'Execute registry query with administrative privileges 
wsh.ShellExecute "cmd", _ 
     "/K REG QUERY " & Chr(34) & reg_key_location & Chr(34) & " /v " & reg_key_name, _ 
     "", _ 
     "runas", _ 
     1 
End Sub 

Все, что возвращается из этой подпрограммы:

ОШИБКА:

The system was unable to find the specified registry key or value.

Однако ключ реестра наиболее определенно существует. См. Снимок экрана ниже. Кроме того, командная строка также должна запускаться с правами администратора в соответствии с моим кодом выше.

реестра Скриншот: enter image description here

Кроме того, выполнив команду ...

REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel" /v TypeGuessRows 

Непосредственно в командной строке работает без каких-либо прав администратора.

REG EDIT вручную в CMD: enter image description here

Так что я потерял о том, как получить эту функцию работает правильно и любую помощь по этому вопросу будет высоко ценится!

**** **** UPDATE

Ok так я уже реализован код, предложенный Dinotom в первом ответе. См. Извлечение кода ниже.

Sub Read_Registry() 

Dim entryArray() As Variant 
Dim valueArray() As Variant 
Dim reg_key_location As String 
Dim x As Integer 

reg_key_location = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel" 
Call EnumerateRegEntries(reg_key_location, entryArray, valueArray) 

For x = 0 To UBound(entryArray) 
    'Do something here 
Next x 

End Sub 

Public Sub EnumerateRegEntries(keyPath As String, arrEntryNames As Variant, arrValueTypes As Variant) 

Dim registryObject As Object 
Dim rootDirectory As String 

rootDirectory = "." 
Set registryObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
rootDirectory & "\root\default:StdRegProv") 

registryObject.EnumValues HKEY_LOCAL_MACHINE, keyPath, arrEntryNames, arrValueTypes 

End Sub 

Однако возвращается следующее сообщение об ошибке на х = 0 ... линия ...

ОШИБКА:

Run-time error '9' Subscript out of range.

Это не выглядит как массивы заселяется с данными реестра, как предлагается ниже. Есть еще идеи?

+0

Этот Sub работает для меня на каждом тестовом реестре с проверкой, так что у вас либо есть неправильный путь ключа, либо есть проблема с правами доступа к этому разделу реестра. – dinotom

+0

Этот суб не работает для меня ни для одного из ключевых путей, которые я тестировал. Я пробовал ... HKEY_LOCAL_MACHINE \ SOFTWARE; HKEY_LOCAL_MACHINE \ HARDWARE; HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Office \ Common в качестве нескольких примеров (в дополнение к тем же клавишам, что и префикс HKLM). Таким образом, это определенно не плохой путь к файлу. Возможно, разрешение? ... какая ОС вы работаете? Я использую Windows 10. Также любые другие идеи о том, что может быть проблемой? – Josh

ответ

3

Вам нужно использовать Shell?

Это будет перечислять записи в реестре, манипулировать по мере необходимости. Настройте пустые массивы для передачи в качестве параметров, а путь для ключей - это путь локального файла к вашему реестру для перечисления. суб будет заполнять массивы.

Dim entryArray() As Variant, valueArray() As Variant 
Call EnumerateRegEntries("pathtokey",entryArray, valueArray) 

Подпункт ниже будет запущен, а entryArray и значениеArray будут заполнены. Затем вы можете перебрать массивы

For x = 0 to UBound(yourarrayhere) 
    'Do something here 
Next x 

Перечислите метод:

Public Sub EnumerateRegEntries(keyPath As String, arrEntryNames As Variant, arrValueTypes As Variant) 

    Dim registryObject As Object 
    Dim rootDirectory As String 

    rootDirectory = "." 
    Set registryObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
    rootDirectory & "\root\default:StdRegProv") 

    registryObject.EnumValues HKEY_LOCAL_MACHINE, keyPath, arrEntryNames, arrValueTypes 

End Sub 

, если вы не можете изменить или использовать этот сабвуфер, то смотрите здесь Chip Pearsons registry page

или, если у вас есть некоторые требования к использованию Shell, а затем посмотрите, как работать как Admin run shell as admin

+0

Удивительные ответы спасибо динотом! Нет необходимости использовать оболочку. Это были единственные варианты, которые я мог придумать в то время, чтобы прочитать реестр из VBA. Как передать пустой массив вариантов этой функции? Затем выводите результаты этих массивов? Можете ли вы привести пример? Спасибо еще раз за помощь! – Josh

+0

Хорошо, поэтому я ввел код в VBA, как предлагалось выше. Но когда он достигает раздела for для x = 0 в Ubound (entryArray) кода, все, что возвращается, это «Ошибка времени выполнения 9, подстрока вне диапазона», любые идеи, что происходит? – Josh

+0

положить точку останова на строку For x = ... и запустить код, что находится в массиве? вы должны опубликовать весь код, который вы используете в вопросе, так как я не знаю, если вы его правильно реализуете. – dinotom

Смежные вопросы