8 Replies Latest reply on Jul 25, 2012 1:17 PM by ZellOr

    Überprüfen ob eine Anwendung gerade verwendet wird

    ZellOr Apprentice
      Hallo zusammen,

      Ich wollte mal Fragen was Ihr für Szenarien/Konstrukte habt, um zu überprüfen ob gerade eine bestimmte Anwendung gestartet ist.

      Ich selbst hab Mir dazu folgenden eScript-Vierzeiler samt PowerShell-Script ausgedacht. Sollte etwas unklar sein, dann fragt einfach

      .\Script.inc

      Set('Path','$( [RegEx]::Escape("%ProgramFilesDir%\Mozilla\Firefox\") ).+')
      CallScript('.\Extern$\Is-DsmApplicationInUse.ps1')
      If %Is-DsmApplicationInUse%='True'
      ExitProcEx(Undone,'Die Anwendung wird gerade verwendet.')

      ...Hier kommte das "eigentliche" eScript rein...


      .\Extern$\Is-DsmApplicationInUse.ps1

      #    | Copyright (c) since 2012 by K.-Ch. Zellemann

             Function Is-DsmApplicationInUse
             {  PARAM
                (  [Parameter(
                      Mandatory = $TRUE
                   )]
                   [ValidateNotNullOrEmpty( )]
                   [System.String]
                   ${Path}
                );

                BEGIN
                {  [System.String] ${l_FileName} = ${NULL};
                   [System.Boolean] ${l_HasMatched} = ${FALSE};

                      ${Path} = $ExecutionContext.InvokeCommand.ExpandString( ${Path} );
                };

                PROCESS
                {     ForEach( $ProcessExecutable in $( Get-WmiObject -Class CIM_ProcessExecutable ) )
                      {  ${l_FileName} = ${ProcessExecutable}.Antecedent.Split( "=" )[ 1 ].Trim( "`"" );
                         ${l_FileName} = $( Get-Item -Path ${l_FileName} ).FullName;

                         If( ${l_FileName} -Match ${Path} )
                         {  ${l_HasMatched} = ${TRUE};
                            Break;
                         };
                      };
                };

                END
                {  Set-NiVar -Name "Is-DsmApplicationInUse" -Value ${l_HasMatched}.ToString( );
                };
             };

             Is-DsmApplicationInUse -Path $( Get-NiVar -Name "Path" );

      #    |


      Danke und Gruß
      ZellOr
        • 1. Re: Überprüfen ob eine Anwendung gerade verwendet wird
          NicoS1 Master
          Hallo,

          in der einfachsten Variante mit Abbrechen Button und ohne externes Script schauts so aus:

          : proc_check
          Set('WMI_Name','0')
          WMISimpleQuery('\\.\root\cimv2','Win32_Process','Name=prozessname.exe','WMI_')
          Name
          EndProc
          If %WMI_Name%='prozessname.exe'
          MsgBoxEx('Es steht ein Update für XXXXX zur Installation an. Derzeit ist die Anwendung noch geöffnet. Bitte beenden Sie alle geöffneten XXXXX Fenster und bestätigen Sie diese Message Box mit "OK". Falls Sie das Update abbrechen werden Sie erneut daran erinnert.','choice','',mbOKCancel)
          If %choice%='CANCEL'
            ExitProc(Undone)
          Sleep('5')
          goto proc_check


          Gruß
          • 2. Re: Überprüfen ob eine Anwendung gerade verwendet wird
            Ratzratz Expert
            Hallo ZellOr,

            wir machen das, indem wir per WMISimpleQuery einfach prüfen, ob ein zur Anwendung gehörender Prozess (z.B. wie_auch_immer.exe) noch läuft.

            Z.B. bei der Aktualisierung von Firefox darf die firefox.exe gerade nicht laufen.

            Im eScript sieht das so aus aus wie im Anhang.

            Gruß
            Matthias
            • 3. Re: Überprüfen ob eine Anwendung gerade verwendet wird
              Markus.Zierer Expert
              Prinzipiell kannst Du das zwar machen, ich würde aber zur Methode mit der WMI Abfrage raten, da Du in dem Fall auch mit DSM Variablen arbeiten kannst. Natürlich kannst Du das auch mit PowerShell machen, wenn Du das PS1 Script über CallScript ausführst, kannst Du auch auf DSM Variablen zugreifen. Hier gab es in der Vergangenheit aber immer Probleme wenn Du ein x64 W7 als OS hattest. Ich hab noch nicht geprüft ob das in der 7.1 jetzt immer noch der Fall ist.
              • 4. Re: Überprüfen ob eine Anwendung gerade verwendet wird
                NVUser Specialist
                Ich nehme dafür auch immer die WMI-Abfrage:

                Set('_WMI_Name','0')
                Set('_task_name','firefox.exe')
                !
                WMISimpleQuery('\\.\root\cimv2','Win32_Process','Name=%_task_name%','_WMI_')
                Name
                EndProc
                !
                EndProc
                If %_WMI_Name%='%_task_name%'
                MsgBox
                  Für die Aktualisierung des Flashplayers muß Firefox geschlossen werden. Schließen Sie ALLE Firefoxfenster  B E V O R  Sie auf klicken!
                EndProc
                Sleep('3')
                KillProcess('%_task_name%',kpByFileName+kpKillAll)
                !


                Funktioniert zuverlässig und der Prozess wird beim Ignorieren der Meldung "hart" beendet...

                Grüße Torsten
                • 5. Re: Überprüfen ob eine Anwendung gerade verwendet wird
                  NicoS1 Master
                  Ich persönlich kann die Variante von Torsten (NVUser) leider nicht empfehlen... jetzt nicht wegen der technischen Seite, eher wegen Benutzerfreundlichkeit.

                  Ich selbst hab es einige Zeit lang so praktiziert, aber der Umstand, dass die Messagebox den Fokus nimmt, und ein User der gerade am tippen ist mit der Leer- oder Entertaste den Prozess abschießt führt bei einigen Usern doch zu Ärger. Vor allem wenn sie ungespeicherte Arbeiten offen hatten, mitten in Präsentationen sind usw. :-/

                  Wir haben bei den meisten Anwendungen ganz darauf verzichtet den Holzhammer mit KillProcess anzuwenden.

                  Man kann es auch kombinieren... das würde dann so aussehen:

                  Der User bekommt die normale MessageBox mit "OK" oder "Abbrechen" Button, falls er abbrechen wählt wird ein Wert den wir in der Registry hinterlegt haben hochgezählt. Wenn er bereits 3x abgebrochen hat kommt eine MessageBox hoch, die in darauf hinweist, dass das Update jetzt nicht mehr verschoben werden kann, und mit einem Klick auf OK der Prozess beendet wird.

                  Bei besonders kritischen Sachen haben wir früher mit VBScript, mittlerweile einfach mit MsgBoxT von NWC, eine zeitgesteuerte MessageBox angezeigt, die, wenn der User nicht innerhalb von 30 Minuten bestätigt automatisch weiter macht im Script.
                  • 6. Re: Überprüfen ob eine Anwendung gerade verwendet wird
                    NVUser Specialist
                    ^^ Mmmh, dann verschiebt sich die "Ausversehen-OK-Button-Drücken-Problematik" auch nur um 3 weitere Msg-Boxen, wenn einer es wirklich bis zum Limit treibt. Wir hatten hier bisher allerdings noch keine Userbeschwerden. Zumal auch die zeitgesteuerte Lösung dahingehend keinerlei Sicherheit bietet, wenn der User länger weg ist und vorher nicht gespeichert hat.
                    Die Handhabung eines Kill-Prozesses hängt natürlich ganz von den Bedingungen im Unternehmen und der Anwendung ab - in Abschätzung mit dem Risiko...


                    Gruß
                    Torsten
                    • 7. Re: Überprüfen ob eine Anwendung gerade verwendet wird
                      Andy74 Expert

                      Ich persönlich kann die Variante von Torsten (NVUser) leider nicht empfehlen... jetzt nicht wegen der technischen Seite, eher wegen Benutzerfreundlichkeit.

                      Ich selbst hab es einige Zeit lang so praktiziert, aber der Umstand, dass die Messagebox den Fokus nimmt, und ein User der gerade am tippen ist mit der Leer- oder Entertaste den Prozess abschießt führt bei einigen Usern doch zu Ärger. Vor allem wenn sie ungespeicherte Arbeiten offen hatten, mitten in Präsentationen sind usw. :-/

                      Wir haben bei den meisten Anwendungen ganz darauf verzichtet den Holzhammer mit KillProcess anzuwenden.

                      Man kann es auch kombinieren... das würde dann so aussehen:

                      Der User bekommt die normale MessageBox mit "OK" oder "Abbrechen" Button, falls er abbrechen wählt wird ein Wert den wir in der Registry hinterlegt haben hochgezählt. Wenn er bereits 3x abgebrochen hat kommt eine MessageBox hoch, die in darauf hinweist, dass das Update jetzt nicht mehr verschoben werden kann, und mit einem Klick auf OK der Prozess beendet wird.

                      Bei besonders kritischen Sachen haben wir früher mit VBScript, mittlerweile einfach mit MsgBoxT von NWC, eine zeitgesteuerte MessageBox angezeigt, die, wenn der User nicht innerhalb von 30 Minuten bestätigt automatisch weiter macht im Script.




                      Das ist aber auch nicht besser, nach 30 Sekunden einfach weiterzumachen

                      Wenn schon die MsgBoxT dann einfach den Abbrechen Button als Default vorbelegen und nur weitermachen, wenn JA gedrückt wurde. Das ganze mit 60 Sekunden Wartezeit und noch in einer Schleife, die 3x durchlaufen wird. Dann Popt das Fenster 3x hoch.

                      Wenn dann wirklich keiner da ist, bricht das Script also nach ca. 3 Minuten ab und läuft dann eben beim nächsten Polling Intervall wieder...... so haben wir es gelöst.
                      • 8. Re: Überprüfen ob eine Anwendung gerade verwendet wird
                        ZellOr Apprentice
                        So, mein Urlaub ist vorbei...jetzt gehts wieder weiter mit DSM (7.1)

                        "WMISimpleQuery" scheint für den Anwendungsfall die praktikabelste Lösung zu sein. Jetzt hadert es bei Mir aber mit der Überprüfung während der Deinstallation. Leider kann Ich ExitProc(Ex) hier erst ab ": $BeginUninstallScript" nutzen (Warum ist Mir klar). Allerdings werden jetzt Befehle wie "CreateLink" oder "MSIInstallProduct" automatisch rückgängig gemacht (Ist von Mir auch so gewollt) bevor Ich überhaupt weiß ob die Anwendung gerade verwendet wird...

                        So sieht z.B. gerade mein 7-Zip-Paket aus (einschließlich Meiner gerade genannten  Problematik)

                        !# Scriptbasierte Installationsbedingung
                        Set('l_Win32_Process_Name','NULL')
                        !
                        WMISimpleQuery('\\.\root\cimv2','Win32_Process','Name=7zFM.exe','l_Win32_Process_')
                        Name

                        EndProc
                        WMISimpleQuery('\\.\root\cimv2','Win32_Process','Name=7zG.exe','l_Win32_Process_')
                        Name

                        EndProc
                        !
                        If not %l_Win32_Process_Name%='NULL'
                        ExitProcEx(Undone,'Eine scriptbasierte Installationsbedingung ist fehlgeschlagen. (Der Prozess "%l_Win32_Process_Name%" ist bereits gestartet!)')
                        !
                        !# "7-Zip for 32-bit Windows" installieren.
                        MSIInstallProduct('.\Extern$\Setup\Setup.msi','NORMAL',MsiInstMach)
                        |.\Extern$\Files\Common Files\Setup.mst;
                        params:
                        EndProc/TS
                        !
                        !# Zusätzliche Registrierungsdatenbank-Einträge erstellen/ändern.
                        !#
                        !# @reg HKEY_CURRENT_USER\Software\7-Zip\[Lang]
                        !#       Sprache der Benutzeroberfläche setzen.
                        RegLoadEx('.\Common Registry.nir',)/TU
                        !
                        !# Selbstdefinierte Verknüpfungen erstellen.
                        CreateLink('7-Zip File Manager','%ProgramFilesDir%\7-Zip\7zFM.exe','','','Programs\Accessories\','',)/TU
                        !
                        If CheckInstallMode(imUninstall)
                        : $BeginUninstallScript
                        !
                        ! # Überreste der (De)installation entfernen.
                        RemoveFolder('%ProgramFilesDir%\7-Zip\',iSubDirs)/TS
                        If Exist('%ProgramFilesDir%\7-Zip\')
                          MoveFileAtNextStart('%ProgramFilesDir%\7-Zip\','')/TS

                        !# EOF


                        Danke an alle die schon was zu Meinem Thema geschrieben haben oder noch wollen