.net 检查程序是否在C#中为当前用户运行[重复]

0md85ypi  于 2023-10-21  发布在  .NET
关注(0)|答案(4)|浏览(112)

这个问题已经有答案了

Get all process of current active session(1个答案)
3天前关闭。
我需要检查一个程序(xyz.exe)是否正在运行,但只针对当前用户。无论使用什么方法,都不能要求提升权限,而且必须运行得快(所以JavaScript已经过时了)。
Process.GetProcessesByName("xyz")返回所有登录用户的“xyz”结果.但我只关心当前用户。
有什么想法?

rxztt3cl

rxztt3cl1#

使用当前进程SessionId筛选进程列表:

public static bool IsProcessRunningSameSession(string processName)
    {
        var currentSessionID = Process.GetCurrentProcess().SessionId;
        return Process.GetProcessesByName(processName).Where(p => p.SessionId == currentSessionID).Any();
    }
ctrmrzij

ctrmrzij2#

我在这里找到了答案:http://dotbay.blogspot.com/2009/06/finding-owner-of-process-in-c.html
我会复制/粘贴它的情况下,该博客曾经路过。

////
        // 'WindowsIdentity' Extension Method Demo: 
        //   Enumerate all running processes with their associated Windows Identity
        ////

        foreach (var p in Process.GetProcesses())
        {
            string processName;

            try
            {
                processName = p.WindowsIdentity().Name;

            }
            catch (Exception ex)
            {

                processName = ex.Message; // Probably "Access is denied"
            }

            Console.WriteLine(p.ProcessName + " (" + processName + ")");
        }

下面是相应的类:

//-----------------------------------------------------------------------
// <copyright file="ProcessExtensions.cs" company="DockOfTheBay">
//     http://www.dotbay.be
// </copyright>
// <summary>Defines the ProcessExtensions class.</summary>
//-----------------------------------------------------------------------

namespace DockOfTheBay
{
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Security.Principal;

    /// <summary>
    /// Extension Methods for the System.Diagnostics.Process Class.
    /// </summary>
    public static class ProcessExtensions
    {
        /// <summary>
        /// Required to query an access token.
        /// </summary>
        private static uint TOKEN_QUERY = 0x0008;

        /// <summary>
        /// Returns the WindowsIdentity associated to a Process
        /// </summary>
        /// <param name="process">The Windows Process.</param>
        /// <returns>The WindowsIdentity of the Process.</returns>
        /// <remarks>Be prepared for 'Access Denied' Exceptions</remarks>
        public static WindowsIdentity WindowsIdentity(this Process process)
        {
            IntPtr ph = IntPtr.Zero;
            WindowsIdentity wi = null;
            try
            {
                OpenProcessToken(process.Handle, TOKEN_QUERY, out ph);
                wi = new WindowsIdentity(ph);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (ph != IntPtr.Zero)
                {
                    CloseHandle(ph);
                }
            }

            return wi;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr hObject);
    }
}
wdebmtf2

wdebmtf23#

这里是完整的程序。这是一个命令行C#应用程序。它很丑,没有评论。但这很有效。你给它一个EXE文件的名字(包括路径),它会检查它是否已经在运行,如果没有,就启动它。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace SingleRun
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = "";
            var prog = "";
            if (args.Length == 0) {
                MessageBox.Show("Please include a program to start.\n\nExample: \nSingleRun.exe \"C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe\"", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                System.Environment.Exit(1);
            }else{
                path = args[0];
                if (!File.Exists(path)) {
                    MessageBox.Show("\"" + path + "\" does not exist.\nPlease check the location.\nAnything with spaces in it needs to be inside double-quotes.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    System.Environment.Exit(1);
                }else{
                    var splits = path.Split('\\');
                    prog = splits[splits.Length - 1];
                    foreach (var p in Process.GetProcessesByName(prog.Replace(".exe",""))) {
                        string processOwner;
                        try {
                            processOwner = p.WindowsIdentity().Name;
                        }
                        catch (Exception ex) {
                            processOwner = ex.Message; // Probably "Access is denied"
                        }
                        if (processOwner.Contains(Environment.UserName)) {
                            MessageBox.Show("Program already running with PID " + p.Id, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            System.Environment.Exit(1);
                        }
                    }
                    Process newProcess = Process.Start(path);
                    Console.WriteLine("Launching " + prog + " with PID: " + newProcess.Id);
                }
            }
        }
    }

    /// <summary>
    /// Extension Methods for the System.Diagnostics.Process Class.
    /// </summary>
    public static class ProcessExtensions {
        /// <summary>
        /// Required to query an access token.
        /// </summary>
        private static uint TOKEN_QUERY = 0x0008;

        /// <summary>
        /// Returns the WindowsIdentity associated to a Process
        /// </summary>
        /// <param name="process">The Windows Process.</param>
        /// <returns>The WindowsIdentity of the Process.</returns>
        /// <remarks>Be prepared for 'Access Denied' Exceptions</remarks>
        public static WindowsIdentity WindowsIdentity(this Process process) {
            IntPtr ph = IntPtr.Zero;
            WindowsIdentity wi = null;
            try {
                OpenProcessToken(process.Handle, TOKEN_QUERY, out ph);
                wi = new WindowsIdentity(ph);
            }
            catch (Exception) {
                throw;
            }
            finally {
                if (ph != IntPtr.Zero) {
                    CloseHandle(ph);
                }
            }

            return wi;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr hObject);
    }
}
bksxznpy

bksxznpy4#

上面的代码很好用。但如果你只想知道当前用户是否看到打开的应用程序:如果进程不是来自当前用户,那么如果你试图获取句柄,你已经有了一个异常。所以,你可以用这个扩展做得更简单:

public static bool ProcessAccessibleForCurrentUser(this Process process)
    {
        try
        {
            var ptr = process.Handle;
            return true;
        }
        catch
        {
            return false;
        }
    }

相关问题