2017-09-07 36 views
2

有没有可能确定如何启动c#应用程序?确定应用程序从哪个位置开始

在我来说,我要检查,如果这个应用程序(WPF)是由位于特定文件夹的快捷方式启动。

因此,有两种方法可以打开我的应用程序

  • 直接使用快捷
  • 启动另一个应用程序,它就像一个更新管理器,以保持我的应用程序是最新的。检查后,它开始我的应用程序与Process.Start()

而且我想确保应用程序只能用更新管理器启动。

+3

测试的代码听起来像一个[XY问题] (http://xyproblem.info/)给我。 –

+3

要求它采用只有你的UpdateManager知道的一些关键参数。 – Fildor

+0

你是否设法解决这个问题? –

回答

1

你可以使用一个技巧是检查父进程的PID,然后得到一些家长的处理信息。

如果父进程名是一样的东西“的explorer.exe”,那么应用程序从快捷方式或直接双击它在资源管理器中启动。

否则,它是从另一个应用程序启动:它会成为你更新应用程序,它也可能是使用相同的名称为您更新应用程序另一个应用程序...

这意味着你必须重新思考如何你想深入这个解决方案,你想要多深的安全控制。您可以将您的更新程序中的参数传递给主应用程序,也可以使用令牌交换实现一些进程间通信......不可能建立100%安全的系统。

正如有人评论上述,这似乎是一个XY问题......或者可能不是。也许这只是一个安全问题。建议修改你想要的软件。

如果您需要在.NET中获取处理信息(通过使用System.Management)的示例代码,然后只给一个尝试下面列出的代码。您只需将其放置在名为“Updater”的控制台应用程序项目中,并在代码中正确设置主应用程序的路径。

如果通过启动和关闭YourApplication发挥一点点这个例子。EXE在不同的情况下,那么你应该能够看到像这样的输出:

Parent process 'Updater.exe' [PID=5472] 
Parent process 'explorer.exe' [PID=12052] 

下面是在VS2017的.Net 4.6.1

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Management; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Process.Start(new ProcessStartInfo() 
     { 
      FileName = "YourApplication.exe" // path to your application 
     }); 

     while (Console.ReadKey(true).Key != ConsoleKey.Escape) 
     { 
      Process process = Process.GetProcessesByName("YourApplication").FirstOrDefault(); // your application's process name 
      if (process == null) 
      { 
       Console.WriteLine($"Process is not running..."); 
       continue; 
      } 
      ProcessManager pm = ProcessManager.FromLocalMachine(); 
      var processProperties = pm.GetProcessProperties(process.Id); 
      int parentProcessId = Convert.ToInt32(processProperties[EProcessProperty.ParentProcessId]); 

      try 
      { 
       var parentProcessProperties = pm.GetProcessProperties(parentProcessId); 
       string parentProcessName = parentProcessProperties[EProcessProperty.Name].ToString(); 
       Console.WriteLine($"Parent process '{parentProcessName ?? "Unknown"}' [PID={parentProcessId}]"); 
       Console.WriteLine("---------------------------------"); 
      } 
      catch { Console.WriteLine("Parent process information not found."); } 
     } 
    } 
} 

public class ProcessConnection 
{ 
    internal ManagementScope ManagementScope { get; } 

    internal ProcessConnection(string machineName, string user = null, string password = null, string domain = null) 
    { 
     ManagementScope = new ManagementScope 
     { 
      Path = new ManagementPath(@"\\" + machineName + @"\root\CIMV2"), 
      Options = new ConnectionOptions 
      { 
       Impersonation = ImpersonationLevel.Impersonate, 
       Authentication = AuthenticationLevel.Default, 
       EnablePrivileges = true, 
       Username = user == null ? null : (string.IsNullOrWhiteSpace(domain) ? user : $"{domain}\\{user}"), 
       Password = user == null ? null : password, 
      }, 
     }; 
     ManagementScope.Connect(); 
    } 
} 

public class ProcessManager 
{ 
    public static ProcessManager FromLocalMachine() => new ProcessManager() 
    { 
     Machine = Environment.MachineName, 
    }; 

    public static ProcessManager FromRemoteMachine(string machine, string user = null, string password = null, string domain = null) => new ProcessManager() 
    { 
     Machine = machine, 
     User = user, 
     Password = password, 
     Domain = domain, 
    }; 

    private ProcessManager() { } 

    public string Machine { get; private set; } 
    public string User { get; private set; } 
    public string Password { get; private set; } 
    public string Domain { get; private set; } 

    private ProcessConnection Connection { get; set; } 
    private ManagementScope ManagementScope => Connection == null ? (Connection = new ProcessConnection(Machine, User, Password, Domain)).ManagementScope : Connection.ManagementScope; 

    public EProcessStartStatus StartProcess(string processPath) 
    { 
     ManagementClass mc = new ManagementClass($"\\\\{Machine}\\root\\CIMV2", "Win32_Process", null); 
     ManagementBaseObject process = mc.GetMethodParameters("Create"); 
     process["CommandLine"] = processPath; 
     ManagementBaseObject createCode = mc.InvokeMethod("Create", process, null); 
     string createCodeStr = createCode["ReturnValue"].ToString(); 
     return (EProcessStartStatus)Convert.ToInt32(createCodeStr); 
    } 

    public bool KillProcess(string processName) 
    { 
     try 
     { 
      SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE Name = '{processName}'"); 
      ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 
      foreach (ManagementObject mo in searcher.Get()) mo.InvokeMethod("Terminate", null); 
      return true; 
     } 
     catch { return false; } 
    } 

    public bool KillProcess(int processId) 
    { 
     try 
     { 
      SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE ProcessId = '{processId}'"); 
      ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 
      foreach (ManagementObject mo in searcher.Get()) mo.InvokeMethod("Terminate", null); 
      return true; 
     } 
     catch { return false; } 
    } 

    public void SetProcessPriority(string processName, EProcessPriority priority) 
    { 
     SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE Name = '{processName}'"); 
     ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(ManagementScope, query); 
     foreach (ManagementObject managementObject in managementObjectSearcher.Get()) 
     { 
      ManagementBaseObject methodParams = managementObject.GetMethodParameters("SetPriority"); 
      methodParams["Priority"] = priority; 
      managementObject.InvokeMethod("SetPriority", methodParams, null); 
     } 
    } 

    public string GetProcessOwner(string processName) 
    { 
     SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE Name = '{processName}'"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 
     foreach (ManagementObject mo in searcher.Get()) 
     { 
      ManagementBaseObject methodParams = mo.GetMethodParameters("GetOwner"); 
      ManagementBaseObject owner = mo.InvokeMethod("GetOwner", null, null); 
      return owner["User"].ToString(); 
     } 
     return null; 
    } 

    public string GetProcessOwnerSID(string processName) 
    { 
     SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE Name = '{processName}'"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 
     foreach (ManagementObject mo in searcher.Get()) 
     { 
      ManagementBaseObject methodParams = mo.GetMethodParameters("GetOwnerSid"); 
      ManagementBaseObject OwnerSid = mo.InvokeMethod("GetOwnerSid", null, null); 
      return OwnerSid["Sid"].ToString(); 
     } 
     return null; 
    } 

    public IList<int> GetRunningProcesses() 
    { 
     IList<int> processes = new List<int>(); 
     SelectQuery query = new SelectQuery("SELECT * FROM Win32_Process"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 
     foreach (ManagementObject mo in searcher.Get()) processes.Add(int.Parse(mo["ProcessId"].ToString())); 
     return processes; 
    } 

    public IDictionary<EProcessProperty, object> GetProcessProperties(int processId) 
    { 
     SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE ProcessId = '{processId}'"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 

     Dictionary<EProcessProperty, object> properties = new Dictionary<EProcessProperty, object>(); 
     foreach (ManagementObject mo in searcher.Get()) 
     { 
      foreach (PropertyData pd in mo.Properties) 
      { 
       if (Enum.TryParse(pd.Name, out EProcessProperty e)) properties[e] = pd.Value; 
       else Console.WriteLine(pd.Name + " is not mapped in the properties enumeration."); 
      } 
     } 
     return properties; 
    } 

    public IDictionary<EProcessProperty, object> GetProcessProperties(string processName) 
    { 
     SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE Name = '{processName}'"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 

     Dictionary<EProcessProperty, object> properties = new Dictionary<EProcessProperty, object>(); 
     foreach (ManagementObject mo in searcher.Get()) 
     { 
      foreach (PropertyData pd in mo.Properties) 
      { 
       if (Enum.TryParse(pd.Name, out EProcessProperty e)) properties[e] = pd.Value; 
       else Console.WriteLine(pd.Name + " is not mapped in the properties enumeration."); 
      } 
     } 
     return properties; 
    } 

    public IList<int> GetProcessessFromExecutablePath(string executablePath) 
    { 
     SelectQuery query = new SelectQuery($"SELECT * FROM Win32_Process WHERE ExecutablePath = '{executablePath.Replace("\\", "\\\\")}'"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(ManagementScope, query); 
     return searcher.Get().Cast<ManagementObject>().Select(mo => Convert.ToInt32(mo["ProcessId"])).ToList(); 
    } 

} 

public enum EProcessPriority : uint 
{ 
    IDLE = 0x40, 
    BELOW_NORMAL = 0x4000, 
    NORMAL = 0x20, 
    ABOVE_NORMAL = 0x8000, 
    HIGH_PRIORITY = 0x80, 
    REALTIME = 0x100 
} 

public enum EProcessStartStatus 
{ 
    Success = 0, 
    AccessDenied = 2, 
    NoPermissions = 3, 
    Unknown = 8, 
    FileNotFound = 9, 
    Invalid = 21, 
} 

public enum EProcessProperty 
{ 
    Caption, 
    CommandLine, 
    CreationClassName, 
    CreationDate, 
    CSCreationClassName, 
    CSName, 
    Description, 
    ExecutablePath, 
    ExecutionState, 
    Handle, 
    HandleCount, 
    InstallDate, 
    KernelModeTime, 
    MaximumWorkingSetSize, 
    MinimumWorkingSetSize, 
    Name, 
    OSCreationClassName, 
    OSName, 
    OtherOperationCount, 
    OtherTransferCount, 
    PageFaults, 
    PageFileUsage, 
    ParentProcessId, 
    PeakPageFileUsage, 
    PeakVirtualSize, 
    PeakWorkingSetSize, 
    Priority, 
    PrivatePageCount, 
    ProcessId, 
    QuotaNonPagedPoolUsage, 
    QuotaPagedPoolUsage, 
    QuotaPeakNonPagedPoolUsage, 
    QuotaPeakPagedPoolUsage, 
    ReadOperationCount, 
    ReadTransferCount, 
    SessionId, 
    Status, 
    TerminationDate, 
    ThreadCount, 
    UserModeTime, 
    VirtualSize, 
    WindowsVersion, 
    WorkingSetSize, 
    WriteOperationCount, 
    WriteTransferCount, 
} 
1

如果只有2开始您的应用的方法,第二种方法应传递的参数(一个GUID?)来的Process.Start() - 由您的更新的应用程序生成的。

也许设计一些算法,允许应用程序只使用令牌启动。

1

据我所知,这是在路上不可能你想它是,但有一个窍门,您可以使用。首先改变你的WPF应用程序的入口方法来获取命令行参数,并且(例如)使用-u参数来区别应用程序的启动位置。然后在-u之后,您可以传递一个HWND或与您的更新程序匹配的进程ID。当然,你必须检查该应用程序是否正在运行,以及它是否是你的更新程序。

例如:

// updated process start 
ProcessStartInfo psi = new ProcessStartInfo("your/WPF/application.exe"); 
psi.Arguments = "-u " + Process.GetCurrentProcess().Id; 
// fill up rest of the properties you need 
Process.Start(psi); 

// wpf application's entry point 
void Main(string[] args) 
{ 
    string updaterProcessIdstr = string.Empty; 
    for (int i = 0; i < args.Length; i++) 
    { 
     if(args[i] == "-u") 
     { 
      updaterProcessIdstr = args[i + 1]; 
      i++; 
     } 
    } 
    int pid = int.Parse(updaterProcessIdstr); 
    Process updaterProcess = Process.GetProcessById(pid); 
    // do some validation here 
    // send something to stdin and read from stdout 
    // to determine if it was started from that updater. 
} 
相关问题