Como solicitar dados do WMI em uma plataforma de 64 bits

Por padrão, um aplicativo ou script recebe dados do provedor correspondente, quando existem duas versões de provedores. O provedor de 32 bits retorna dados para um aplicativo de 32 bits, incluindo todos os scripts, e o provedor de 64 bits retorna os dados para os aplicativos compilados de 64 bits. No entanto, um aplicativo ou script pode solicitar dados do provedor não padrão, se houver, notificando o WMI por meio de sinalizadores em chamadas de método.

Sinalizadores de contexto

Os sinalizadores de cadeia de caracteres __ProviderArchitecture e __RequiredArchitecture têm um conjunto de valores manipulados pelo WMI, mas não definidos em arquivos de cabeçalho ou biblioteca de tipos do SDK. Os valores são colocados em um parâmetro de contexto para sinalizar ao WMI que ele deve solicitar dados do provedor não padrão.

O exemplo a seguir lista os sinalizadores e seus valores possíveis.

__ProviderArchitecture

Valor inteiro, 32 ou 64, que especifica a versão de 32 bits ou 64 bits.

__RequiredArchitecture

Valor booliano usado além de __ProviderArchitecture para forçar o carregamento da versão do provedor especificada. Se a versão não estiver disponível, o WMI retornará o erro 0x80041013, wbemErrProviderLoadFailure para Visual Basic e WBEM_E_PROVIDER_LOAD_FAILURE para C++. O valor padrão para esse sinalizador, quando ele não é especificado, é FALSE.

Em um sistema de 64 bits que tem versões lado a lado de um provedor, um aplicativo ou script de 32 bits recebe automaticamente dados do provedor de 32 bits, a menos que esses sinalizadores sejam fornecidos e indiquem que os dados do provedor de 64 bits devem ser retornados.

Como usar os sinalizadores de contexto

Os aplicativos C++ podem usar a interface IWbemContext com IWbemServices::ExecMethod para comunicar o uso de um provedor não padrão para o WMI.

No script e no Visual Basic, você deve criar um objeto SWbemNamedValueSet contendo os sinalizadores para o parâmetro objWbemNamedValueSet de SWbemServices.ExecMethod. Para obter mais informações sobre como configurar os objetos de parâmetros para essa chamada, confira Como construir objetos InParameters e analisar objetos OutParameters.

Você pode executar scripts e aplicativos com segurança usando os sinalizadores de contexto em sistemas operacionais mais antigos, pois o WMI os ignora em sistemas nos quais eles não são implementados. Embora existam versões de 32 bits e 64 bits do provedor do Registro do Sistema, observe que existe apenas uma versão do repositório do WMI.

Como acessar o Hive do Registro Padrão

A série de exemplos a seguir usa o Provedor do Registro, que tem versões lado a lado de 32 bits e 64 bits pré-instaladas em sistemas operacionais de 64 bits. Nesses exemplos, os clientes de 32 bits obtêm dados retornados pelo provedor do nó de 32 bits HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft. Os clientes de 64 bits recebem dados retornados pelo provedor do nó de 64 bits HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Logging.

Os scripts mostram como chamar os métodos da classe StdRegProv do Registro por meio de SWbemServices.ExecMethod para obter dados do hive do registro de 32 bits.

O script a seguir obtém dados do provedor que correspondem à largura do bit do chamador. Nesse caso, 64 bits, pois é um script em execução no WSH (Host de Script do Windows) de 64 bits. O script obtém o valor do nó do registro de 64 bits HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\Logging, em vez do nó de 32 bits HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WBEM\CIMOM.

strComputer = "."
Const HKLM = &h80000002
Set objReg = Getobject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer _
    & "\root\default:stdregprov")
'Set up inParameters object
Set Inparams = objReg.Methods_("GetStringValue").Inparameters
Inparams.Hdefkey = HKLM
Inparams.Ssubkeyname = "Software\Microsoft\Wbem\CIMOM"
Inparams.Svaluename = "Logging"
set Outparams = objReg.ExecMethod_("GetStringValue", Inparams)

'Show output parameters object and the registry value HKLM\SOFTWARE\
WScript.Echo Outparams.GetObjectText_
WScript.Echo "WMI Logging is set to  " & Outparams.SValue

Se o valor de log no hive padrão for definido como 1, a saída do script deverá ser semelhante ao seguinte:

instance of __PARAMETERS
{
    ReturnValue = 0;
    sValue = "1";
};
WMI Logging is set to 1

Exemplo: como solicitar especificamente o Hive do Registro de 32 bits em um computador de 64 bits

O seguinte exemplo modificado do script padrão usa o sinalizador de cadeia de caracteres __ProviderArchitecture para solicitar acesso aos dados do registro de 32 bits em um computador de 64 bits. O chamador está conectado ao hive de 32 bits, independentemente de ser um aplicativo de 32 ou 64 bits.

strComputer = "."
Const HKLM = &h80000002
Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
objCtx.Add "__ProviderArchitecture", 32
Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
Set objServices = objLocator.ConnectServer(strComputer,"root\default","","",,,,objCtx)
Set objStdRegProv = objServices.Get("StdRegProv") 

Set Inparams = objStdRegProv.Methods_("GetStringValue").Inparameters
Inparams.Hdefkey = HKLM
Inparams.Ssubkeyname = "Software\Microsoft\Wbem\CIMOM"
Inparams.Svaluename = "Logging"
set Outparams = objStdRegProv.ExecMethod_("GetStringValue", Inparams,,objCtx)

'show output parameters object and the registry value HKLM\SOFTWARE\
WScript.Echo Outparams.GetObjectText_
WScript.Echo "WMI Logging is set to  " & Outparams.SValue

Exemplo: como forçar o WMI a acessar o Hive do Registro de 32 bits em um computador de 64 bits

A modificação a seguir do script acima adicionando os sinalizadores __ProviderArchitecture e __RequiredArchitecture ao parâmetro de contexto força o WMI a carregar o provedor de 32 bits e receber dados de 32 bits. Se o provedor não existir, ocorrerá um erro de carga do provedor. O objeto de contexto deve ser fornecido na conexão com o WMI, chamando SWbemLocator.ConnectServer.

strComputer = "."
Const HKLM = &h80000002
Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
objCtx.Add "__ProviderArchitecture", 32
objCtx.Add "__RequiredArchitecture", TRUE
Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
Set objServices = objLocator.ConnectServer(strComputer,"root\default","","",,,,objCtx)
Set objStdRegProv = objServices.Get("StdRegProv") 

' Use ExecMethod to call the GetStringValue method
Set Inparams = objStdRegProv.Methods_("GetStringValue").Inparameters
Inparams.Hdefkey = HKLM
Inparams.Ssubkeyname = "Software\Microsoft\Wbem\CIMOM"
Inparams.Svaluename = "Logging"
set Outparams = objStdRegProv.ExecMethod_("GetStringValue", Inparams,,objCtx)

'Show output parameters object and the registry value HKLM\SOFTWARE\
WScript.Echo Outparams.GetObjectText_
WScript.Echo "WMI Logging is set to  " & Outparams.SValue

Como obter e fornecer dados em um computador de 64 bits