如何发现我的流程是如何启动的

我们有一个winforms LOB应用程序,在正常情况下应该从应该进行基本版本检查并下载任何更新的组件的启动器启动,然后生成主进程。

我们看到的一个问题是,一些员工通过不运行更新应用程序发现它加载速度更快,但这可能导致人们没有最新的function并导致各种头痛的支持。

我希望能够做的是,如果他们没有通过初始化应用程序,则会发出警告。 理想情况下,我希望能够在不更改更新应用程序的情况下执行此操作(因为这意味着在每个客户端上安装新的MSI),而弹出的方法是找到一些方法来查找有关开始“我”并检查白/黑名单的过程,我永远无法找到办法做到这一点?


旁白:当然,如果我确实使用了更改更新应用程序,我可能会将其更改为将预共享密钥作为命令行参数传递,或者更好的是,更改应用程序以便我可以将其加载为一个类库,通过reflection实例化相关的类。 ClickOnce已被排除,因为它不支持为多个用户安装

请参见此处: 如何以托管方式在.NET中获取父进程

从链接:

using System.Diagnostics; PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process ID", Process.GetCurrentProcess().ProcessName); return Process.GetProcessById((int)pc.NextValue()); 

[编辑:有关此内容的更多信息,请参阅System.Diagnostics常见问题解答 。 感谢Justin的链接。]

我发现你的进程 – 我认为你可以控制 – 检查它的版本号与最新发布的版本号(放在中央db / ftp的某个地方,无论你在哪里寻找更新),然后你在一个地方拥有所有这些逻辑。 我认为这将是一个更简单的解决方案。

首先,如果你的员工有足够聪明的人发现发射器很慢以及如何绕过它,我敢打赌他们也会发现一些“秘密”的命令行开关。 我认为这种方法浪费时间。

其次,我认为Chris Marasti-Georg的答案是严格的:你必须找出父进程的名称,即启动你的应用程序的过程。 我对如何做到这一点没有具体的想法,但WMI似乎是一个很好的起点。 编辑: 西蒙P史蒂文斯回答了那一部分。

第三,我想你已经意识到了这一点,但无论如何我会说:你的问题是发射器。 如果它太慢以至于普通用户找不到绕过它的方法,那就太慢了。 您最好的解决方案不是修复主应用程序,而是修复启动器。 编辑:请参阅Anders Karlsson对更好机制的回答 。

您可以将PInvoke与Kernel32方法一起使用来查找父进程并检查它是否与更新程序匹配。 资源。 代码,如果它消失:

 using System; using System.Runtime.InteropServices; using System.Diagnostics; static class myProcessEx { //inner enum used only internally [Flags] private enum SnapshotFlags : uint { HeapList = 0x00000001, Process = 0x00000002, Thread = 0x00000004, Module = 0x00000008, Module32 = 0x00000010, Inherit = 0x80000000, All = 0x0000001F } //inner struct used only internally [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct PROCESSENTRY32 { const int MAX_PATH = 260; internal UInt32 dwSize; internal UInt32 cntUsage; internal UInt32 th32ProcessID; internal IntPtr th32DefaultHeapID; internal UInt32 th32ModuleID; internal UInt32 cntThreads; internal UInt32 th32ParentProcessID; internal Int32 pcPriClassBase; internal UInt32 dwFlags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] internal string szExeFile; } [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] static extern IntPtr CreateToolhelp32Snapshot([In]UInt32 dwFlags, [In]UInt32 th32ProcessID); [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] static extern bool Process32First([In]IntPtr hSnapshot, ref PROCESSENTRY32 lppe); [DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] static extern bool Process32Next([In]IntPtr hSnapshot, ref PROCESSENTRY32 lppe); // get the parent process given a pid public static Process GetParentProcess(int pid) { Process parentProc = null; try { PROCESSENTRY32 procEntry = new PROCESSENTRY32(); procEntry.dwSize = (UInt32)Marshal.SizeOf(typeof(PROCESSENTRY32)); IntPtr handleToSnapshot = CreateToolhelp32Snapshot((uint)SnapshotFlags.Process, 0); if (Process32First(handleToSnapshot, ref procEntry)) { do { if (pid == procEntry.th32ProcessID) { parentProc = Process.GetProcessById((int)procEntry.th32ParentProcessID); break; } } while (Process32Next(handleToSnapshot, ref procEntry)); } else { throw new ApplicationException(string.Format("Failed with win32 error code {0}", Marshal.GetLastWin32Error())); } } catch (Exception ex) { throw new ApplicationException("Can't get the process.", ex); } return parentProc; } // get the specific parent process public static Process CurrentParentProcess { get { return GetParentProcess(Process.GetCurrentProcess().Id); } } static void Main() { Process pr = CurrentParentProcess; Console.WriteLine("Parent Proc. ID: {0}, Parent Proc. name: {1}", pr.Id, pr.ProcessName); } }