Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 已登录应用程序的用户_C#_.net_Process_Windows Identity - Fatal编程技术网

C# 已登录应用程序的用户

C# 已登录应用程序的用户,c#,.net,process,windows-identity,C#,.net,Process,Windows Identity,我使用以下代码获取当前用户和应用程序进程的所有者 当前用户: CurrentUser = WindowsIdentity.GetCurrent().Name; 流程所有者: String strQuery = String.Format("Select * From Win32_Process where Name='{0}'", ProcessName); ObjectQuery oQuery = new ObjectQuery(strQuery); ManagementObjectSea

我使用以下代码获取当前用户和应用程序进程的所有者

当前用户:

CurrentUser = WindowsIdentity.GetCurrent().Name;
流程所有者:

String strQuery = String.Format("Select * From Win32_Process where Name='{0}'", ProcessName);
ObjectQuery oQuery = new ObjectQuery(strQuery);

ManagementObjectSearcher oManSearcher = new ManagementObjectSearcher(oQuery);

foreach (ManagementObject oManItem in oManSearcher.Get())
{
    String[] s = new String[2];

    oManItem.InvokeMethod("GetOwner", (object[])s);

    ProcessOwner = s[0];

    break;
}
我需要从语法上确定我的应用程序实例运行在哪个用户帐户中

基本上,我允许每个登录用户有一个应用程序实例

当用户正常启动应用程序时,上述代码起作用。当用户右键单击快捷方式(或使用类似方法)并选择“以管理员身份运行”时,代码将崩溃。在这种情况下,进程所有者不是登录用户,而是管理员

这会对确定多实例造成严重破坏,更不用说正确的数据库路径等等

在我看来,正常启动的实例和以管理员身份启动的实例都是同一登录用户下的实例,只是所有者不同

如何确定进程所属的登录用户?如前所述,向当前用户检查流程所有者并不总是最佳检查

答复:

以下是根据选定答案开发的完整方法

public static String GetUsernameBySessionId(int sessionId, Boolean prependDomain)
{
    IntPtr buffer;
    int strLen;
    String username = "SYSTEM";
    if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSUserName, out buffer, out strLen) && strLen > 1)
    {
        username = Marshal.PtrToStringAnsi(buffer);
        WTSFreeMemory(buffer);
        if (prependDomain)
        {
            if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSDomainName, out buffer, out strLen) && strLen > 1)
            {
                username = String.Format("{0}\\{1}", Marshal.PtrToStringAnsi(buffer), username);
                WTSFreeMemory(buffer);
            }
        }
    }

    return username;
}
当前进程SessionId是:

Process.GetCurrentProcess().SessionId
System.Environment.UserName-获取当前登录到Windows操作系统的用户的用户名

这就是你要找的吗


编辑:如果您只需要在流程开始时获取值,则可能会起作用。如果他们切换用户并且进程继续,值可能会更改。

要获取应用程序的登录用户,我建议读取当前进程的SessionId,该进程独立于实际运行应用程序的用户。进程的SessionId可以通过以下方式读取:

System.Diagnostics.Process.GetCurrentProcess().SessionId
可以使用以下答案中的函数检索与SessionId关联的用户名:

函数
GetUsernameBySessionId
也需要此枚举:

public enum WtsInfoClass
{
    WTSInitialProgram = 0,
    WTSApplicationName = 1,
    WTSWorkingDirectory = 2,
    WTSOEMId = 3,
    WTSSessionId = 4,
    WTSUserName = 5,
    WTSWinStationName = 6,
    WTSDomainName = 7,
    WTSConnectState = 8,
    WTSClientBuildNumber = 9,
    WTSClientName = 10,
    WTSClientDirectory = 11,
    WTSClientProductId = 12,
    WTSClientHardwareId = 13,
    WTSClientAddress = 14,
    WTSClientDisplay = 15,
    WTSClientProtocolType = 16,
    WTSIdleTime = 17,
    WTSLogonTime = 18,
    WTSIncomingBytes = 19,
    WTSOutgoingBytes = 20,
    WTSIncomingFrames = 21,
    WTSOutgoingFrames = 22,
    WTSClientInfo = 23,
    WTSSessionInfo = 24,
    WTSSessionInfoEx = 25,
    WTSConfigInfo = 26,
    WTSValidationInfo = 27,
    WTSSessionAddressV4 = 28,
    WTSIsRemoteSession = 29
}

您应该使用互斥锁提供此功能:

改编自:

//
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
//获取应用程序GUID
字符串appGuid=((GuidAttribute)Assembly.getExecutionGassembly().GetCustomAttributes(typeof(GuidAttribute),false.GetValue(0)).Value.ToString();
WindowsIdentity currentUser=WindowsIdentity.GetCurrent();
//获取用户SID
字符串userSid=currentUser.User.ToString();
//构造应用程序和用户特定的互斥体ID
string mutexID=string.Format(@“Global\{{{{0}}}-{{{{1}}}),appGuid,userSid);
使用(互斥体互斥体=新互斥体(false,mutexID))
{
MutexAccessRule allowUserRule=新的MutexAccessRule(currentUser.User、MutexRights.FullControl、AccessControlType.Allow);
MutexSecurity securitySettings=新的MutexSecurity();
securitySettings.AddAccessRule(allowUserRule);
mutex.SetAccessControl(安全设置);
bool-hasHandle=false;
尝试
{
尝试
{
hasHandle=mutex.WaitOne(5000,false);
}
捕获(放弃mutexception)
{
//记录互斥在另一个进程中被放弃的事实,它仍然会被获取
hasHandle=true;
}
if(hasHandle==false)返回;
//启动应用程序
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(新Form1());
}
最后
{
if(hasHandle)mutex.ReleaseMutex();
}
}
}

将mutex.WaitOne上的超时时间调整为您希望应用程序在退出前等待独占访问的时间。

可能不会。一个进程可能以不同的用户身份运行(即以管理员身份运行),我认为如果是这样的话,这个变量会发生冲突。您的回答花了我几分钟时间才找到,因为您更改了它。谢谢你的更新。是的,原来的帖子没有WtsInfoClass声明,我用pinvoke.net得到了这个声明。
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
    // Get application GUID
    string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
    WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
    // Get user SID
    string userSid = currentUser.User.ToString();

    // Construct application & user specific mutex ID
    string mutexID = string.Format(@"Global\{{{0}}}-{{{1}}}", appGuid, userSid);

    using (Mutex mutex = new Mutex(false, mutexID))
    {
        MutexAccessRule allowUserRule = new MutexAccessRule(currentUser.User, MutexRights.FullControl, AccessControlType.Allow);
        MutexSecurity securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowUserRule);
        mutex.SetAccessControl(securitySettings);

        bool hasHandle = false;

        try
        {
            try
            {
                hasHandle = mutex.WaitOne(5000, false);
            }
            catch (AbandonedMutexException)
            {
                // Log the fact the mutex was abandoned in another process, it will still get aquired
                hasHandle = true;
            }

            if (hasHandle == false) return;

            // Start application
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
        finally
        {
            if (hasHandle) mutex.ReleaseMutex();
        }
    }
}