I have a Win32 program which I can direct to monitor another Win32 process.
I want to find a way for the monitoring program to determine if the monitored process is running as a Win32 service.
Not all services run as SYSTEM and not all services have services.exe as a direct parent, so I don't regard these obvious t开发者_如何学Goechniques as being robust enough.
To be clear, what I'm looking for is a way to write the function:
bool isService(HANDLE aProcessHandle) { ... }
You can do this easily using WMI. I realize that you did not specify C#, but the WMI api is available on all platforms in quite similar fashion.
First we need an object shaped like a Win32_Service
public class Win32_Service
{
public Win32_Service(ManagementBaseObject obj)
{
AcceptPause = (bool)(obj["AcceptPause"] ?? false);
AcceptStop = (bool)(obj["AcceptStop"] ?? false);
Caption = (string)(obj["Caption"] ?? "");
CheckPoint = (UInt32)(obj["CheckPoint"] ?? 0);
CreationClassName = (string)(obj["CreationClassName"] ?? "");
Description = (string)(obj["Description"] ?? "");
DesktopInteract = (bool)(obj["DesktopInteract"] ?? false);
DisplayName = (string)(obj["DisplayName"] ?? "");
ErrorControl = (string)(obj["ErrorControl"] ?? "");
ExitCode = (UInt32)(obj["ExitCode"] ?? 0);
InstallDate = (DateTime)(obj["InstallDate"] ?? DateTime.MinValue);
Name = (string)(obj["Name"] ?? "");
PathName = (string)(obj["PathName"] ?? "");
ProcessId = (UInt32)(obj["ProcessId"] ?? 0);
ServiceSpecificExitCode = (UInt32)(obj["ServiceSpecificExitCode"] ?? 0);
ServiceType = (string)(obj["ServiceType"] ?? "");
Started = (bool)(obj["Started"] ?? false);
StartMode = (string)(obj["StartMode"] ?? "");
StartName = (string)(obj["StartName"] ?? "");
State = (string)(obj["State"] ?? "");
Status = (string)(obj["Status"] ?? "");
SystemCreationClassName = (string)(obj["SystemCreationClassName"] ?? "");
SystemName = (string)(obj["SystemName"] ?? "");
TagId = (UInt32)(obj["TagId"] ?? 0);
WaitHint = (UInt32)(obj["WaitHint"] ?? 0);
}
bool AcceptPause;
bool AcceptStop;
string Caption;
UInt32 CheckPoint;
string CreationClassName;
string Description;
bool DesktopInteract;
string DisplayName;
string ErrorControl;
UInt32 ExitCode;
DateTime InstallDate;
string Name;
string PathName;
UInt32 ProcessId;
UInt32 ServiceSpecificExitCode;
string ServiceType;
bool Started;
string StartMode;
string StartName;
string State;
string Status;
string SystemCreationClassName;
string SystemName;
UInt32 TagId;
UInt32 WaitHint;
};
Now we query WMI for services. Here I just pull all services. If you have more specific criteria, simply modify the query "Select * from Win32_Service"
var services = new System.Collections.Generic.List<Win32_Service>();
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * from Win32_Service"))
{
using (ManagementObjectCollection results = searcher.Get())
{
foreach (ManagementObject obj in results)
{
services.Add(new Win32_Service(obj));
}
}
}
Now you can use Linq to query services
.
Reference: http://msdn.microsoft.com/en-us/library/ms974579.aspx
精彩评论