Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,422 questions
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
As far as I know you can recycle a COM+ app by using...
$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"
}
}
$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?
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();
}