C# 检测另一个进程是否作为“启动”;“以管理员身份运行”;
我们的应用程序需要通过COM接口与另一个程序通信。如果另一个程序以“以管理员身份运行”启动,该界面将不工作。要检测其他进程是否处于此状态,并警告用户。有什么想法吗 正在寻找.NET语言(C#或VB.NET)C# 检测另一个进程是否作为“启动”;“以管理员身份运行”;,c#,vb.net,C#,Vb.net,我们的应用程序需要通过COM接口与另一个程序通信。如果另一个程序以“以管理员身份运行”启动,该界面将不工作。要检测其他进程是否处于此状态,并警告用户。有什么想法吗 正在寻找.NET语言(C#或VB.NET) TIA您可以尝试以下方法: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Diagnostics; u
TIA您可以尝试以下方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security.Principal;
using System.Reflection;
namespace WindowsFormsApplication2
{
public class ProcessHelper
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int TOKEN_ASSIGN_PRIMARY =0x1;
private const int TOKEN_DUPLICATE = 0x2;
private const int TOKEN_IMPERSONATE = 0x4;
private const int TOKEN_QUERY = 0x8;
private const int TOKEN_QUERY_SOURCE = 0x10;
private const int TOKEN_ADJUST_GROUPS = 0x40;
private const int TOKEN_ADJUST_PRIVILEGES = 0x20;
private const int TOKEN_ADJUST_SESSIONID = 0x100;
private const int TOKEN_ADJUST_DEFAULT = 0x80;
private const int TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT);
public static bool IsProcessOwnerAdmin(string processName)
{
Process proc = Process.GetProcessesByName(processName)[0];
IntPtr ph = IntPtr.Zero;
OpenProcessToken(proc.Handle, TOKEN_ALL_ACCESS, out ph);
WindowsIdentity iden = new WindowsIdentity(ph);
bool result = false;
foreach (IdentityReference role in iden.Groups)
{
if (role.IsValidTargetType(typeof(SecurityIdentifier)))
{
SecurityIdentifier sid = role as SecurityIdentifier;
if (sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) || sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid))
{
result = true;
break;
}
}
}
CloseHandle(ph);
return result;
}
}
static class Program
{
[STAThread]
static void Main()
{
bool isAdmin = ProcessHelper.IsProcessOwnerAdmin("outlook");
}
}
}
这也可能是一件好事:
这应该是一个很好的起点:-)可能会迟到,但我为自己创建了这个(糟糕的代码…尝试n catch,我知道,但它有效):
private void Msg\u单击(对象发送者,路由目标)
{
//跑步
if(Process.getProcessByName(“OUTLOOK”).Any())
{
尝试
{
var app=(应用程序)System.Runtime.InteropServices.Marshal.GetActiveObject(“Outlook.Application”);
}
//正常运行
捕获(无效卡斯特例外)
{
}
//以管理员身份运行
捕获(System.Runtime.InteropServices.COMException)
{
}
捕获(例外情况除外)
{
Debug.WriteLine(ex);
}
}
}
您的问题似乎是COM为什么不能跨越在不同级别运行的应用程序之间的桥梁,而不是如何检测它。您是否正确保护了COM通道?COM使您无法发现托管服务器的进程。在设计上,它允许各种各样的托管技巧。你必须使用你掌握的关于这个过程的秘密知识。谢谢你的起点。当通过使用运行方式启动进程时,它将起作用。我在OpenProcess令牌上被拒绝访问。猜测,因为它是由内置管理员运行的,所以当前用户(是管理员用户)没有访问权限。我可以破解它,并说当我被拒绝访问时,我知道它正在作为服务器运行。如果您有任何其他建议,请提供更优雅的解决方案。仍然拒绝相同的访问。顺便说一句,我添加了private const int STANDARD_RIGHTS_REQUIRED=0x000F0000@兰迪:你能试着以管理员的身份运行你的应用程序,看看这是否有效吗?如果是,那么我可以建议您在检查流程用户信息之前进行应用程序模拟,并在完成后取消模拟。明白了吗?是的,它工作了,我得到了“S-1-5-32-544”的SID,它告诉我它是作为管理员运行的。但是,模拟是非启动程序,因为我的应用程序将弹出UAC屏幕。我还尝试获取SecurityInfo而不是openprocesstoken,它还返回拒绝访问。谢谢你的帮助。