question

te-duncan avatar image
0 Votes"
te-duncan asked SongZhu-MSFT answered

Detect a crashed COM+ app via PowerShell ?

As far as I know you can recycle a COM+ app by using...

List COM+ components


$comAdmin = New-Object -com ("COMAdmin.COMAdminCatalog.1")
$applications = $comAdmin.GetCollection("Applications")
$applications.Populate()

foreach ($application in $applications)
{

 $components = $applications.GetCollection("Components",$application.key)
 $components.Populate()
 foreach ($component in $components)
 {

     $dllName = $component.Value("DLL")
     $componentName = $component.Name

     "Component Name:$componentName"
     "DllName: $dllName`n"
 }

}

Stop/Start Components


$comAdmin.StartApplication("appName")
$comAdmin.ShutdownApplication("appName")


But how can we detect that our COM+ app has crashed - can this be detected by a PowerShell script?

windows-api
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

SongZhu-MSFT avatar image
0 Votes"
SongZhu-MSFT answered

As far as I know, PowerShell is not able to detect whether the application crashed. You can use WMI to detect it.

Here is a code sample:

 #define CREATE 1
 #define DELETE 0
    
 using namespace std;
    
 typedef function<void(void)> TNotificationFunc;
 IWbemObjectSink* RegisterProcessCallback(IWbemServices* pSvc, TNotificationFunc callback, LPCWSTR ProcessName, BOOL flag);
    
    
 class EventSink : public IWbemObjectSink {
    
     friend IWbemObjectSink* RegisterProcessCallback(IWbemServices* pSvc, TNotificationFunc callback, LPCWSTR ProcessName, BOOL flag);
     CComPtr<IWbemServices> pSvc;
     CComPtr<IWbemObjectSink> pStubSink;
     LONG m_IRef;
     TNotificationFunc m_callback;
    
 public:
     EventSink(TNotificationFunc callback) :m_IRef(0), m_callback(callback) {}
     ~EventSink() {
     }
    
     virtual ULONG STDMETHODCALLTYPE AddRef() {
         return InterlockedIncrement(&m_IRef);
     }
    
     virtual ULONG STDMETHODCALLTYPE Release() {
         LONG IRef = InterlockedDecrement(&m_IRef);
         if (IRef == 0)
             delete this;
         return IRef;
     }
    
     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv) {
         if (riid == IID_IUnknown || riid == IID_IWbemObjectSink) {
             *ppv = (IWbemObjectSink*)this;
             AddRef();
             return WBEM_S_NO_ERROR;
         }
         else return E_NOINTERFACE;
     }
    
     virtual HRESULT STDMETHODCALLTYPE Indicate(
         LONG lObjectCount,
         IWbemClassObject __RPC_FAR* __RPC_FAR* apObjArray
     ) {
         for (int i = 0; i < lObjectCount; i++)
         {
             m_callback();
             _variant_t vtProp;
             HRESULT hr = S_OK;
             hr = apObjArray[i]->Get(_bstr_t(L"TargetInstance"), 0, &vtProp, 0, 0);
             if (!FAILED(hr))
             {
                 IUnknown* str = vtProp;
                 hr = str->QueryInterface(IID_IWbemClassObject, reinterpret_cast<void**>(&apObjArray[i]));
                 if (SUCCEEDED(hr))
                 {
                     _variant_t cn;
                     hr = apObjArray[i]->Get(L"Handle", 0, &cn, NULL, NULL);
                     if (SUCCEEDED(hr))
                     {
                         if ((cn.vt == VT_NULL) || (cn.vt == VT_EMPTY))
                             wcout << "ProcessId : " << ((cn.vt == VT_NULL) ? "NULL" : "EMPTY") << endl;
                         else
                             wcout << "ProcessId : " << cn.bstrVal << endl;
                     }
                     VariantClear(&cn);
                 }
             }
             VariantClear(&vtProp);
         }
         return WBEM_S_NO_ERROR;
     }
     virtual HRESULT STDMETHODCALLTYPE SetStatus(LONG IFlags, HRESULT hResult, BSTR strParam, IWbemClassObject __RPC_FAR* pObjParam) {
         return WBEM_S_NO_ERROR;
     }
 };
 void connect2WMI(IWbemServices** pSvc)
 {
     HRESULT hres;
     CComPtr<IWbemLocator> pLoc;
    
     hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
     if (FAILED(hres)) {
         cout << "Failed to create IWbemLocator object."
             << " Err code = 0x"
             << hex << hres << endl;
         throw std::exception("CreationEvent initialization failed");
     }
     hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, pSvc);
     if (FAILED(hres)) {
         cout << "Could not connect. Error code = 0x" << hex << hres << endl;
         throw std::exception("CreationEvent initialization failed");
     }
     hres = CoSetProxyBlanket(*pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
     if (FAILED(hres)) {
         cout << "Coult not set proxy blanket, Error code =0x" << hex << hres << endl;
         throw std::exception("CreationEvent initialization failed");
     }
 }
 IWbemObjectSink* RegisterProcessCallback(IWbemServices* pSvc, TNotificationFunc callback, LPCWSTR ProcessName, BOOL flag) {
     HRESULT hres;
     CComPtr<EventSink> pSink(new EventSink(callback));
     CComPtr<IUnsecuredApartment> pUnsecApp;
     hres = CoCreateInstance(CLSID_UnsecuredApartment, NULL, CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, (void**)&pUnsecApp);
     CComPtr<IUnknown> pStubUnk;
     pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
     IWbemObjectSink* pStubSink = NULL;
     pStubUnk->QueryInterface(IID_IWbemObjectSink, (void**)&pStubSink);
    
    
     wstring buffer = L"SELECT * FROM ";
     if (flag == CREATE)
         buffer += L"__InstanceCreationEvent";
     else if (flag == DELETE)
         buffer += L"__InstanceDeletionEvent";
     buffer = buffer + L" WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = '" + ProcessName + L"'";
     hres = pSvc->ExecNotificationQueryAsync(_bstr_t(L"WQL"), _bstr_t(buffer.c_str()), WBEM_FLAG_SEND_STATUS, NULL, pStubSink);
    
     if (FAILED(hres)) {
         cout << "ExecNotificationQueryAsync failed with = 0x" << hex << hres << endl;
         throw std::exception("CreationEvent initialization failed");
     }
     return pStubSink;
 }
    
 void CreateEventCallBack() { cout << "Create " << endl; /*connect()*/ }
 void DeleteEventCallBack() { cout << "Delete " << endl; /*disconnect()*/ }
    
 int main() {
     CoInitializeEx(0, COINIT_MULTITHREADED);
     IWbemServices* pSvc = NULL;
     connect2WMI(&pSvc);
     IWbemObjectSink* CreateSink = RegisterProcessCallback(pSvc, CreateEventCallBack, L"notepad.exe", CREATE);
     IWbemObjectSink* DeleleSink = RegisterProcessCallback(pSvc, DeleteEventCallBack, L"notepad.exe", DELETE);
    
     getchar();
     cout << "Exit " << endl;
     pSvc->CancelAsyncCall(CreateSink);
     pSvc->CancelAsyncCall(DeleleSink);
     CreateSink->Release();
     DeleleSink->Release();
     pSvc->Release();
     CoUninitialize();
 }



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.