我需要检查程序(xyz.exe)是否正在运行,但仅适用于当前用户。无论使用何种方法都不需要提升权限,并且必须快速运行(因此WMI已经用完)。
Process.GetProcessesByName("xyz")
为所有登录用户返回“xyz”的结果...但我只关心当前用户。
想法?
答案 0 :(得分:1)
使用当前进程SessionId
来过滤进程列表:
public static bool IsProcessRunningSameSession(string processName)
{
var currentSessionID = Process.GetCurrentProcess().SessionId;
return Process.GetProcessesByName(processName).Where(p => p.SessionId == currentSessionID).Any();
}
答案 1 :(得分:0)
我在这里找到答案: 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);
}
}
答案 2 :(得分:0)
这是完整的程序。这是一个CommandLine 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);
}
}
答案 3 :(得分:0)
上面有正确的代码。但是,如果您只想知道当前用户是否看到打开的应用程序:如果该进程不是当前用户,那么如果您尝试获取句柄,则已经有例外。 所以,你可以通过这个扩展来做到这一点:
public static bool ProcessAccessibleForCurrentUser(this Process process)
{
try
{
var ptr = process.Handle;
return true;
}
catch
{
return false;
}
}