Our application needs to communicate with another program through a COM interface. The interface will not work开发者_开发技巧 if the other program is started with "Run as Administrator". Would like to detect if this other process is in this state and warn the user. Any ideas?
Looking for .NET languages (C# or VB.NET).
TIA
You can try something like this:
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");
}
}
}
This could also be a good thing to have: Well-known security identifiers in Windows operating systems
That should be a good start point :-)
May be late, but i created this for me (bad code... try n catch, i know, but it works):
private void Msg_Click(object sender, RoutedEventArgs e)
{
//running at all
if (Process.GetProcessesByName("OUTLOOK").Any())
{
try
{
var app = (Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application");
}
//running normally
catch (InvalidCastException)
{
}
//running as admin
catch (System.Runtime.InteropServices.COMException)
{
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
}
精彩评论