2009-07-14 13 views
5

Wir haben eine Winforms-LOB-Anwendung, die unter normalen Umständen von einem Launcher gestartet werden sollte, der grundlegende Versionsüberprüfungen durchführen und aktualisierte Komponenten herunterladen sollte, bevor der Hauptprozess gestartet wird.Wie erkenne ich, wie mein Prozess gestartet wurde?

Ein Problem, das wir sehen, ist, dass einige Mitarbeiter es schneller geladen haben, indem sie die Update-Anwendung nicht ausführen, dies kann jedoch dazu führen, dass Menschen nicht die neuesten Funktionen haben und alle möglichen Kopfschmerzen zu unterstützen.

Was ich gerne tun könnte, ist eine Warnung auszugeben, wenn sie nicht durch die Initialisierungsanwendung gegangen sind. Idealerweise würde ich dies gerne tun wollen, ohne die Update - Anwendung ändern zu müssen (was bedeutet, dass ich ein neues MSI auf jedem Client installieren muss), und der Ansatz, der herauskommt, besteht darin, eine Möglichkeit zu finden, Informationen über die Prozess, der "mich" gestartet hat und gegen eine weiß/schwarze Liste zu überprüfen, für immer kann ich nicht einen Weg finden, dies zu tun?


Abgesehen: Natürlich, wenn ich zum Ändern der Update-Anwendung zurückgreifen haben, würde ich es wahrscheinlich ändern, entweder eine Pre-Shared Secret als Kommandozeilen-Argument übergeben, oder noch besser, ändert sich die Anwendung, so dass ich es einfach als eine Klassenbibliothek laden und die relevante Klasse durch Reflexion instanziieren könnte. ClickOnce wurde als does not support being installed for multiple users

Antwort

4

Siehe hier: How to get parent process in .NET in managed way

Aus dem Link:

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

[Edit: Auch die System.Diagnostics FAQ für einige weitere Informationen zu diesem sehen. Danke an Justin für den Link.]

+1

Link zu System.Diagnostics FAQ http://msdn.microsoft.com/en-us/netframework/aa569609.aspx#Question3 – Justin

+0

Gute Verbindung. Wird bearbeitet um es einzuschließen. –

+0

Funktioniert perfekt, selbst wenn das Tor geschlossen wird, nachdem das Pferd gebolzt hat ... –

0

ausgeschlossen. Sie können PInvoke mit einer Kernel32-Methode verwenden, um den übergeordneten Prozess zu finden und zu überprüfen, ob er mit Ihrem Updater übereinstimmt. Source.-Code, falls es geht weg:

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); 
    } 
} 
3

ich, wenn Ihr Prozess finden - was ich nehme an, Sie Kontrolle über - prüft die Versionsnummer gegen die neueste freigegebene Version Nummer (platziert irgendwo zentral db/ftp, wo u aussehen für das Update), dann haben Sie all diese Logik an einem Ort. Ich denke, das wäre eine einfachere Lösung.

+0

Für die Aufzeichnung haben wir einen Diagnosebildschirm, den der Support-Mitarbeiter hochziehen kann, der in großen unangenehmen Rötungen hervorsticht, wenn etwas als veraltet betrachtet wird.Ich wollte die Täter im Voraus fangen :) –

0

Erstens, wenn Ihre Mitarbeiter Leute haben, die intelligent genug sind, um herauszufinden, dass der Launcher langsam ist und wie man ihn umgehen kann, wette ich, dass sie einige 'geheime' Befehlszeilenschalter finden werden, auch. Ich würde diesen Ansatz als Zeitverschwendung betrachten.

Zweitens denke ich, die answer form Chris Marasti-Georg geht in die richtige Richtung: Sie müssen herausfinden, den Namen des übergeordneten Prozesses, d. H. Der Prozess, der Ihre App gestartet. Ich habe keine genaue Idee, wie man das macht, aber WMI scheint wie ein guter Ort zu beginnen. Bearbeiten:Simon P Stevens antwortete dieser Teil.

Drittens, ich nehme an, Sie sind sich dessen bewusst, aber ich werde es trotzdem sagen: Ihr Problem ist der Launcher. Wenn es so langsam ist, dass normale Benutzer einen Weg finden, es zu umgehen, ist es einfach zu langsam. Ihre beste Lösung ist nicht, die Hauptanwendung zu reparieren, sondern den Launcher zu reparieren. Bearbeiten: Siehe Anders Karlsson's answer für einen besseren Mechanismus.

+0

Das "zu langsame" Bit ist meistens das Ergebnis von Updates über ein WAN. Diese Updates sind bereits an geeignete geografische Standorte verteilt und werden auch gezippt. Zur Erinnerung, ich mag den vorinstallierten geheimen Ansatz nicht. –

+0

So wie ich Ihre Frage verstanden habe, dachte ich, dass der Loader * immer * langsam war, nicht nur, wenn er tatsächlich ein Update durchgeführt hat. Ich stehe korrigiert ;-) – Treb

Verwandte Themen