Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何发现我的流程是如何启动的_C#_.net - Fatal编程技术网

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

C# 我如何发现我的流程是如何启动的,c#,.net,C#,.net,我们有一个winforms LOB应用程序,在正常情况下应该从一个启动器启动,该启动器应该在生成主进程之前执行基本版本检查并下载任何更新的组件 我们看到的一个问题是,一些工作人员发现,不运行更新应用程序会加快it的加载速度,但这可能会导致人们没有最新的功能,并导致各种各样令人头痛的问题 我想做的是,如果他们没有通过初始化应用程序进入,就抛出一个警告。理想情况下,我希望能够做到这一点,而不必更改更新应用程序(因为这意味着在每个客户端上安装一个新的MSI),而出现的方法是找到某种方法来查找启动“我”

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

我们看到的一个问题是,一些工作人员发现,不运行更新应用程序会加快it的加载速度,但这可能会导致人们没有最新的功能,并导致各种各样令人头痛的问题

我想做的是,如果他们没有通过初始化应用程序进入,就抛出一个警告。理想情况下,我希望能够做到这一点,而不必更改更新应用程序(因为这意味着在每个客户端上安装一个新的MSI),而出现的方法是找到某种方法来查找启动“我”的流程的信息,并对照白/黑列表进行检查,我似乎永远都找不到这样做的方法



旁白:当然,如果我真的改变了更新应用程序,我可能会改变它,要么传递一个预先共享的秘密作为命令行参数,或者更好的是,改变应用程序,这样我就可以把它作为类库加载,并通过反射实例化相关的类。ClickOnce被排除在外,因为它

您可以使用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);
    }
}

我发现,如果您的流程(我假设您可以控制)检查其版本号与最新发布的版本号(放在中央数据库/ftp的某个位置,无论您在哪里查找更新),那么您就可以将所有逻辑放在一个位置。我认为这是一个更简单的解决方案。

请参见此处:

从链接:

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

[编辑:有关这方面的更多信息,请参见。感谢Justin提供的链接。]

首先,如果您的工作人员足够聪明,能够发现启动器运行缓慢以及如何绕过它,我打赌他们也会找到一些“秘密”命令行开关。我认为这种做法是浪费时间。 其次,我认为这是一个正确的方向:你必须找出父进程的名称,即启动你的应用程序的进程。我不知道该怎么做,但似乎是一个好的开始。 编辑:回答了那个部分

第三,我想你知道这一点,但我还是要说:你的问题是发射器。如果它的速度太慢,以至于普通用户都想办法绕过它,那么它就是太慢了。你最好的解决方案不是修复主应用程序,而是修复启动器。
编辑:有关更好的机制,请参阅。

链接到System.Diagnostics常见问题解答,即使是在马匹脱缰后关闭闸门的情况下,也能很好地工作。“太慢”位主要是通过WAN拉取更新的结果。这些更新已经分发到了方便的地理位置,并且也进行了gzip。作为记录,我不喜欢预共享的秘密方法我理解你的问题的方式,我认为加载程序总是很慢,不仅仅是在它实际执行更新时。我被纠正了;-)为了记录在案,我们确实有一个诊断屏幕,支持人员可以拉出来,如果任何东西被认为过时,它会以严重的红色突出显示。我想提前抓住罪犯:)