我是個剛學完Android,老板要把一個C#項目轉成java的新人,有些操作不能用java完成,目前正在編寫C++代碼,遇到一個問題,需要做一個鉤子,當有新進程啟動時候我需要獲取到這個進程的名字做一些操作,現有C#代碼如下:
public class GlobalHook
{
//ManagementEventWatcher watch_del = null;
//[DllImport("user32.dll")]
//private static extern bool
//SetForegroundWindow(IntPtr hWnd);
//[DllImport("user32.dll")]
//private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
//[DllImport("user32.dll")]
//private static extern bool IsIconic(IntPtr hWnd);
//// 消息函數
//[DllImport("user32.dll", EntryPoint = "PostMessageA")]
//public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
//[DllImport("user32.dll")]
//public static extern IntPtr FindWindow(string strclassName, string strWindowName);
//[DllImportAttribute("user32.dll")]
//public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
//public const int WM_SYSCOMMAND = 0x0112;
//public const int SC_MAXIMIZE = 0xF030;
public static ManagementEventWatcher watch_crt = null;
protected tray m_tray;
public GlobalHook(tray mm_tray)
{
this.m_tray = mm_tray;
StartWatchCreateProcess();
}
~GlobalHook()
{
if (watch_crt != null)
watch_crt.Stop();
}
protected void StartWatchCreateProcess()
{
WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent",
new TimeSpan(0, 0, 1),
"TargetInstance isa \"Win32_Process\"");
watch_crt = new ManagementEventWatcher(query);
watch_crt.EventArrived += new EventArrivedEventHandler(HandleProcessCreateEvent);
watch_crt.Start();
}
//監視進程啟動
protected void HandleProcessCreateEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject MBO = (ManagementBaseObject)e.NewEvent["TargetInstance"];
string temp = MBO["Name"].ToString();
if (temp != "")
{
string name = temp;
if (name.Contains("."))
name = temp.Substring(0, temp.IndexOf("."));
this.m_tray.CheckSingleProcessItemHook(name);
}
}
}
C++該怎樣寫?
C++一樣可以支持WMI query的方式
http://www.codeproject.com/Articles/12138/Process-Information-and-Notifications-using-WMI
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#include <atlcomcli.h>
#pragma comment(lib, "wbemuuid.lib")
#include "ProcessTerminationNotification.h"
class EventSink : public IWbemObjectSink
{
friend void ProcessTerminationNotification::registerTerminationCallback(TNotificationFunction callback, unsigned processId);
CComPtr<IWbemServices> pSvc;
CComPtr<IWbemObjectSink> pStubSink;
LONG m_lRef;
ProcessTerminationNotification::TNotificationFunction m_callback;
public:
EventSink(ProcessTerminationNotification::TNotificationFunction callback)
: m_lRef(0)
, m_callback(callback)
{}
~EventSink()
{}
virtual ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement(&m_lRef);
}
virtual ULONG STDMETHODCALLTYPE Release()
{
LONG lRef = InterlockedDecrement(&m_lRef);
if (lRef == 0)
delete this;
return lRef;
}
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
)
{
m_callback();
/* Unregister event sink since process is terminated */
pSvc->CancelAsyncCall(pStubSink);
return WBEM_S_NO_ERROR;
}
virtual HRESULT STDMETHODCALLTYPE SetStatus(
/* [in] */ LONG lFlags,
/* [in] */ HRESULT hResult,
/* [in] */ BSTR strParam,
/* [in] */ IWbemClassObject __RPC_FAR *pObjParam
)
{
return WBEM_S_NO_ERROR;
}
};
void ProcessTerminationNotification::registerTerminationCallback( TNotificationFunction callback, unsigned processId )
{
CComPtr<IWbemLocator> pLoc;
HRESULT 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("ProcessTerminationNotificaiton initialization failed");
}
// Step 4: ---------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
CComPtr<EventSink> pSink(new EventSink(callback));
// Connect to the local root\cimv2 namespace
// and obtain pointer pSvc to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&pSink->pSvc
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
throw std::exception("ProcessTerminationNotificaiton initialization failed");
}
// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------
hres = CoSetProxyBlanket(
pSink->pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
throw std::exception("ProcessTerminationNotificaiton initialization failed");
}
// Step 6: -------------------------------------------------
// Receive event notifications -----------------------------
// Use an unsecured apartment for security
CComPtr<IUnsecuredApartment> pUnsecApp;
hres = CoCreateInstance(CLSID_UnsecuredApartment, NULL,
CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment,
(void**)&pUnsecApp);
CComPtr<IUnknown> pStubUnk;
pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
pStubUnk->QueryInterface(IID_IWbemObjectSink,
(void **) &pSink->pStubSink);
// The ExecNotificationQueryAsync method will call
// The EventQuery::Indicate method when an event occurs
char buffer[512];
sprintf_s(buffer, "SELECT * "
"FROM __InstanceDeletionEvent WITHIN 1 "
"WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.ProcessId=%u", processId);
hres = pSink->pSvc->ExecNotificationQueryAsync(
_bstr_t("WQL"),
_bstr_t(buffer),
WBEM_FLAG_SEND_STATUS,
NULL,
pSink->pStubSink);
// Check for errors.
if (FAILED(hres))
{
cout << "ExecNotificationQueryAsync failed "
"with = 0x" << hex << hres << endl;
throw std::exception("ProcessTerminationNotificaiton initialization failed");
}
}