是否有windows api来检测我的dll是否在系统服务或普通用户进程中运行?
之前我正在查看当前用户名并忽略“SYSTEM”,“LOCAL SERVICE”和“NETWORK SERVICE”。但是现在我看到在任何人登录之前svchost在某些情况下运行的情况下,GetUsername会返回machine_name $。 另外,我在vista中找不到来自GetUsername的machine_name $ result的任何文档,有没有人看到过这种行为?
答案 0 :(得分:3)
您可以查看进程令牌,以查看令牌中是否有众所周知的SID NT Authority \ Service是否处于活动状态。如果是,那么您正在运行服务。您可以使用CheckTokenMembership查看您的进程是否在令牌中激活特定SID的情况下运行。
答案 1 :(得分:2)
这是用于配置服务的任何用户帐户。可能是任何事情,系统管理员可以选择这些帐户。这当然意味着您可以不可靠地使用它来检测您的代码是否在服务中运行。
你应该让使用你的DLL的服务告诉你它是一个服务,它总是知道。自动检测很棘手,GetProcessWindowStation()应该是一个领先者。使用UOI_FLAGS标志在返回的句柄上调用GetUserObjectInformation,并检查是否获得USEROBJECTFLAGS.dwFlags = WSF_VISIBLE。我猜想可能会出现RDP的一些退化情况,但你可以看看用户是否有看到过程输出的可能性。
答案 2 :(得分:2)
对于Windows Vista及更高版本,可以将当前会话检查为加载到session0中的服务以及加载到session1及更高版本中的用户进程。我没有测试,但这样的东西应该工作:
if (Win32MajorVersion < 6) return PROCESSTYPE_CANNOTDETECT;
DWORD SessionId;
if ( ProcessIdToSessionId( GetCurrentProcessId(), &SessionId )
&& (0 == SessionId) )
{
return PROCESSTYPE_SERVICE_OR_DRIVER;
}
else
{
return PROCESSTYPE_USERAPP;
}
答案 3 :(得分:0)
正如其他答案已经说明的那样,检查当前用户名是非常不可靠的。服务可以设置为使用任何帐户,甚至包括真实用户的帐户。
我过去曾研究过类似的问题:可执行文件可以确定它是作为服务运行还是作为普通程序运行?结论似乎没有正式的方式来判断。我发现唯一合理可靠的方法是检查服务程序启动时必须调用的其中一个函数的成功或失败。显然,该技术不适用于服务使用的DLL。
据我所知,dll没有好办法自行确定。要么主持程序要告诉dll。否则你需要重新检查你的设计。为什么dll实际上需要知道这个?还有其他方法可以让它不需要知道它吗?
答案 4 :(得分:0)
您可以尝试调用StartServiceCtrlDispatcher
函数(请参阅http://msdn.microsoft.com/en-us/library/ms686324.aspx)并检查错误代码。在服务中,它将是ERROR_SERVICE_ALREADY_RUNNING
。