How do I discover how my process was started

后端 未结 4 1252
萌比男神i
萌比男神i 2020-12-21 01:12

We\'ve got a winforms LOB application, which under normal circumstances should be started from a launcher that should do basic version checks and download any updated compon

相关标签:
4条回答
  • 2020-12-21 01:39

    You can use PInvoke with a Kernel32 method to find the parent process and check to see if it matches your updater. Source. Code, in case it goes away:

    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);
        }
    }
    
    0 讨论(0)
  • I find if your process - which I assume you have control over - checks its version number vs the latest released version number (placed somewhere central db/ftp wherever u look for the update) , then you have all that logic in one place. I think that would be a simpler solution.

    0 讨论(0)
  • 2020-12-21 01:41

    First, if your staff has people smart enough to figure out that the launcher is slow and how to get around it, I bet they will find out some 'secret' command line switch, too. I would consider that approach a waste of time.

    Second, I think the answer form Chris Marasti-Georg goes into the rigth direction: You have to figure out the name of the parent process, i.e. the process that launched your app. I have no specific idea on how to do this, but WMI seems like a good place to start. Edit: Simon P Stevens answered that part.

    Third, I suppose you are aware of this, but I will say it anyway: Your problem is the launcher. If it is so slow that normal users find a way to get around it, it is just too slow. Your best solution is not ti fix the main app, but to fix the launcher. Edit: See Anders Karlsson's answer for a better mechanism.

    0 讨论(0)
  • 2020-12-21 01:52

    See here: How to get parent process in .NET in managed way

    From the link:

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

    [Edit: Also see the System.Diagnostics FAQ for some more information about this. Thanks to Justin for the link.]

    0 讨论(0)
提交回复
热议问题