问题
When requesting Win32_WinSAT from a x64 process I get the correct results (WinSATAssessmentState = 1), but when executed from a x86 I get "results not available" (WinSATAssessmentState = 3)
x64 Powershell:
PS C:\Users\alive> gwmi Win32_WinSAT
__GENUS : 2
__CLASS : Win32_WinSAT
__SUPERCLASS :
__DYNASTY : Win32_WinSAT
__RELPATH : Win32_WinSAT.TimeTaken="MostRecentAssessment"
__PROPERTY_COUNT : 8
__DERIVATION : {}
__SERVER : COMPNAME
__NAMESPACE : root\cimv2
__PATH : \\COMPNAME\root\cimv2:Win32_WinSAT.TimeTaken="MostRecentAssessment"
CPUScore : 7,2
D3DScore : 6,3
DiskScore : 7,65
GraphicsScore : 4,6
MemoryScore : 5,9
TimeTaken : MostRecentAssessment
WinSATAssessmentState : 1
WinSPRLevel : 4,6
PSComputerName : COMPNAME
x86 Powershell
PS C:\Users\alive> gwmi Win32_WinSAT
__GENUS : 2
__CLASS : Win32_WinSAT
__SUPERCLASS :
__DYNASTY : Win32_WinSAT
__RELPATH : Win32_WinSAT.TimeTaken="MostRecentAssessment"
__PROPERTY_COUNT : 8
__DERIVATION : {}
__SERVER : COMPNAME
__NAMESPACE : root\cimv2
__PATH : \\COMPNAME\root\cimv2:Win32_WinSAT.TimeTaken="MostRecentAssessment"
CPUScore : 0
D3DScore : 0
DiskScore : 0
GraphicsScore : 0
MemoryScore : 0
TimeTaken : MostRecentAssessment
WinSATAssessmentState : 3
WinSPRLevel : 0
PSComputerName : COMPNAME
Is there any flag or special method to be able to access this information from the x86 process?
Thanks.
回答1:
Your question fall in Requesting WMI Data on a 64-bit Platform.
By default, an application or script receives data from the corresponding provider when two versions of providers exist. The 32-bit provider returns data to a 32-bit application, including all scripts, and the 64-bit provider returns data to the 64-bit compiled applications. However, an application or script can request data from the nondefault provider, if it exists, by notifying WMI through flags on method calls. The __ProviderArchitecture and __RequiredArchitecture string flags have a set of values handled by WMI but not defined in SDK header or type library files. The values are placed in a context parameter to signal WMI that it should request data from the nondefault provider.
I don't know how to do that with PowerShell CmdLets, but you can use "System.Management" classes from the .NET Framework (COM object encapsulation).
# Setup the context information
$mContext = New-Object System.Management.ManagementNamedValueCollection
$mContext.Add( "__ProviderArchitecture", 64)
$mContext.Add( "__RequiredArchitecture", $true)
# Setup the Authrntification object
$ConOptions = New-Object System.Management.ConnectionOptions
#$ConOptions.Username = "computername\administrateur" # Should be used for remote access
#$ConOptions.Password = "toto"
$ConOptions.EnablePrivileges = $true
$ConOptions.Impersonation = "Impersonate"
$ConOptions.Authentication = "Default"
$ConOptions.Context = $mContext
# Setup the management scope (change with the computer name for remote access)
$mScope = New-Object System.Management.ManagementScope("\\localhost\root\cimV2", $ConOptions)
$mScope.Connect()
# Query
$queryString = "SELECT * From Win32_WinSAT"
$oQuery = New-Object System.Management.ObjectQuery ($queryString)
$oSearcher = New-Object System.Management.ManagementObjectSearcher ($mScope, $oQuery)
$oSearcher.Get();
I execute this script bith from 32 and 64 bits PowerShell in Windows 8 and both works.
来源:https://stackoverflow.com/questions/19120578/cannot-access-win32-winsat-from-32-bits-process