Get-WMIObject \Get-Cim 인스턴스는 실제로 무엇을 합니까?
새 WMI 인스턴스 공급자를 개발하는 중에 문제가 좀 있습니다.다음을 사용하여 공급자를 성공적으로 등록할 수 있는 경우regsvr32.exe
.그regsvr32
응용 프로그램에서 의 구현을 호출하고 다음 레지스트리 키 및 값을 만듭니다.
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F} : (default) = "WMI Provider"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\InprocServer32 : (default) = "C:\MyWmiProvider.dll"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\InprocServer32 : ThreadingModel = Neutral
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\Version : (default) = 1.0.0
(어디서{00000001-0000-0000-0000-00000000000F}
테스트 클래스 ID(CLSID)일 뿐입니다.)
또한 를 사용하여 MOF(Managed Object Format) 파일에 정의된 WMI 클래스 정의를 성공적으로 추가할 수 있습니다. 다음 명령을 실행하여 WMI 저장소에 내 정의가 있는지 확인할 수 있습니다.
Get-CimClass -Namespace "root/MyNamespace" | Where-Object CimClassName -like "MyClass_*"
다음은 MOF 파일의 예입니다.
#pragma namespace("\\\\.\\root\\MyNamespace")
#pragma autorecover
instance of __Win32Provider as $P
{
Name = "MyWmiProvider";
ClsId = "{00000001-0000-0000-0000-00000000000F}";
};
instance of __InstanceProviderRegistration
{
Provider = $P;
SupportsGet = FALSE;
SupportsPut = FALSE;
SupportsDelete = FALSE;
SupportsEnumeration = TRUE;
};
[dynamic, provider("MyWmiProvider")]
class MyClass_ExampleName
{
[key]
uint14 Id;
[PropertyContext("Name")]
String Name;
};
이제 다음을 실행하면 다음과 같습니다.
Get-CimInstance -Namespace "root/MyNamespace" -Class "MyClass_ExampleName"
이로 인해 PowerShell에서 다음 오류가 발생합니다.
Get-CimInstance : Provider load failure
At line:1 char:1
+ Get-CimInstance -Namespace "root/MyNamespace" -Class "MyClass_ExampleName"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (root/Surface:Device_Status:String) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041013,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
마찬가지로 이 명령을 실행할 때 생성되는 세 개의 이벤트 뷰어 로그도 있습니다.
-
내 WmiProvider 공급자가 결과 코드 0x80041013으로 시작했습니다.HostProcess = wmiprvse입니다.exe; 프로세스ID = 2144; ProviderPath = C:\MyWmiProvider.dll
-
ID = {FB6B3CF7-293E-0002-9316-73FB3E29D601}, 클라이언트 시스템 = RTR-USERNAME, 사용자 = MYDOMAIN\username, 클라이언트 프로세스 ID = 19416, 구성 요소 = 알 수 없음, 작업 = 시작IBM 서비스:: CreateInstanceEnum - root\MyNamespace : MyClass_ExampleName; 결과 코드 = 0x80041013; 가능한 원인 = 알 수 없음
-
내 WmiProvider 공급자가 결과 코드 0x80041013으로 시작했습니다.HostProcess = wmiprvse입니다.exe; 프로세스ID = 24636, ProviderPath = C:\MyWmiProvider.dll
(WMI가 DLL을 올바르게 찾은 것으로 표시됨)
전화를 걸어도 비슷한 결과가 나타납니다.Get-WMIObject
두 번째 Event Viewer 로그에 "Operation"이 "Start IWbemServices::"로 표시된 것을 제외하고는,ExecQuery - root\MyNamespace : MyClass_ExampleName"입니다.
정확히 무엇입니까?Get-WMIObject
그리고.Get-CimInstance
뒤에서 하는 거예요?
에 대한 출처를 찾아봤습니다.Get-WMIObject
[here] 그리고 간단한 6줄에도 불구하고, 존경 클래스와 함수 호출을 찾는 것은 자세한 세부 사항을 산출하지 않습니다.내 DLL 인터페이스에는 내보낸 네 가지 기능만 포함됩니다. ,DllCanUnloadNow()
,DllRegisterServer()
,그리고.DllUnregisterServer()
나는 둘 다Get-WMIObject
그리고.Get-CimInstance
WMI 클래스 팩토리를 가져오기 위해 에 처음 전화를 걸었지만 내에서 임시 파일에 문자열을 저장하는 함수 호출을 하면 PowerShell 명령을 호출할 때 임시 파일이 생성되지 않음을 알게 됩니다.
이 답변에 따라 새로운 프로젝트를 만들어 다음과 같은 내용을 부를 수 있도록 더욱 구체적으로 설명했습니다.
DEFINE_GUID(InstanceProviderClassID, 0x00000001, 0x00000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F);
IWbemServices * pLoc = NULL;
CoCreateInstance(InstanceProviderClassID, NULL, CLSCTX_INPROC_SERVER, IID_IWbemServices, (LPVOID *)&pLoc);
이 경우 에 대한 호출이 성공했습니다.저는 임시 로그 파일이 생성되었다는 것을 알아차렸고, 이는 실제로 호출되었음을 나타냅니다!
내가 가지고 있는 작업 인스턴스 공급자를 사용하여 이와 동일한 인쇄 문(또는 레지스트리 키/값을 만들기 위한 호출)을 함수에 넣더라도 이러한 PowerShell 명령을 호출할 때 이 함수가 호출되었음을 나타내는 내용은 저장되지 않습니다.
내가 여기서 뭘 놓쳤지요?
두 가지를 모두 실행할 때 함수가 호출되지 않는 이유는 무엇입니까?Get-WMIObject
그리고.Get-CimInstance
?
공급자가 올바르게 코딩되었음을 증명하면서 성공적으로 실행할 수 있지만 PowerShell 명령 중 하나를 실행할 때 "공급자 로드 오류"가 발생하는 이유는 무엇입니까?
(부록:이를 쉽게 하기 위해 모든 서비스 기능에 다음과 같은 라벨을 붙였습니다.WBEM_E_NOT_SUPPORTED
작업 인스턴스 공급자에서 이 작업을 수행해도 "공급자 로드 오류"가 나타나지 않고 "지원되지 않음"이 표시됩니다.")
Get-CimInstance
그리고.Get-WmiObject
겸용WMI와 통신하기 위한 NET API입니다. 첫 번째 경우에는 https://learn.microsoft.com/en-us/dotnet/api/microsoft.management.infrastructure 을 사용하고 후자의 경우에는 https://learn.microsoft.com/en-us/dotnet/api/system.management 을 사용합니다.이 두 가지 주요 차이점은 CIM API가 교차 플랫폼 호환성이 있는 반면 WMI API는 윈도우즈에서만 작동하는 CIM에 대한 윈도우즈 확장 기능을 가지고 있다는 것입니다.
PowerShell cmdlet, WMIC, wbemtest 등을 사용할지 여부에 관계없이 최종적으로 WMI COM API https://learn.microsoft.com/en-us/windows/win32/wmisdk/com-api-for-wmi 를 호출하여 WMI 공급자와 대화합니다.
https://learn.microsoft.com/en-us/windows/win32/wmisdk/writing-an-instance-provider 을 팔로우하셨습니까?COM 서버에 IWbemServices를 구현한 것 같지 않습니까?
언급URL : https://stackoverflow.com/questions/61788489/what-do-get-wmiobject-get-ciminstance-actually-do
'programing' 카테고리의 다른 글
Python 스크립트에서 PowerShell 함수 실행 (0) | 2023.08.16 |
---|---|
GCC가 변수를 할당하기 전에 임시 위치로 이동하는 이유는 무엇입니까? (0) | 2023.08.16 |
Fill remaining vertical space with CSS using display:flex (0) | 2023.08.11 |
스위프트를 사용하여 iOS에서 Numpad에 "완료" 버튼을 추가하는 방법은 무엇입니까? (0) | 2023.08.11 |
SUM과 SUBTOTAL의 차이점은 무엇입니까? (0) | 2023.08.11 |