Zavřít DOS aplikaci automaticky

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Nnet 8. 1. 2016 11:03

Ahoj, hledám možnost jak vytvořit script který mi bude hlídat DOS aplikaci běžící ve windows.

Script by měl tuto aplikaci zavřít automaticky po 30 minutách pokud ji uživatel nepoužívá.

Šlo by něco podobného vytvořit?
Prosím o nějakou nápovědu jak na to :)
Díky
Hádku s blbcem nevyhraješ!

Desktop: Intel Xeon E3-1245V3, DDR3 16GB ECC, 160GB Intel SSD, Nvidia Quadro K2000

NB: Intel Core i7 720QM, 8GB DDR3, 750GB HDD, ATI 5650
Nnet
Junior
Uživatelský avatar

Odeslat příspěvekod PiranhaGreg 8. 1. 2016 17:23

Čau, ona se hned nabízí otázka, jak poznáš že se aplikace používá? Když si uživatel pustí film, tak pokud ho nehodláš sledovat přes webku, nemáš šanci zjistit, jestli se po hodině ještě na ten film kouká, nebo šel pryč ;-).

Záleží tak trochu o jakou aplikaci jde. Asi bych začal s focusem. Vždy když zachytíš událost, že aplikace ztratila focus, spustíš timer na 30 minut. Při získání fokusu ten timer zase zrušíš. Pokud ti doběhne na nulu, "můžeš" tu aplikaci zavřít.

Tady jsem našel C# zdroják, kterej monitoruje všechny tyto změny. Přes podmínku se případně můžeš zaměřit pouze na tu jednu aplikaci

Kód: Vybrat vše
public class FocusMonitor
{
    public FocusMonitor()
    {
        AutomationFocusChangedEventHandler focusHandler = OnFocusChanged;
        Automation.AddAutomationFocusChangedEventHandler(focusHandler);
    }

    private void OnFocusChanged(object sender, AutomationFocusChangedEventArgs e)
    {
        AutomationElement focusedElement = sender as AutomationElement;
        if (focusedElement != null)
        {
            int processId = focusedElement.Current.ProcessId;
            using (Process process = Process.GetProcessById(processId))
            {
                Debug.WriteLine(process.ProcessName);
            }
        }
    }
}

Dále bych si hlídal, kdy naposledy uživatel nějakým způsobem interagoval s OS. Opět od poslední interakce spustit časovat. Když tak funkční kód v C#.

Nenapsal jsi v jakém jazyce ten skript chceš napsat. Tak si to pro ostatní když tak dogoogli ;-).
PiranhaGreg
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod Nargon 8. 1. 2016 18:55

Zavřít aplikaci je jednoduché. Nějaký 30ti minutový timer také. Ale jak je již zmíněno, jak poznáš nepoužívanou aplikaci. Nebo jak poznáš že je aplikace používaná?
Možná se svěř s tím co je to za aplikaci. Ten focus je dobrý nápad, ale pokud by to byla např "serverová" aplikace, tak tam by to chtělo spíš monitorovat zda tam probíhá síťová komunikace než to zda má okno focus. Nemluvě o tom že okno může mít focus, ale uživatel odejde od PC a nechá to tak běžet a pak se to nevypne.
Takže opravdu specifikuj co je to za aplikaci a jak se dá poznat "není využívaná". Pak lze vymyslet něco co bude i fungovat.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod X-Lorrien 8. 1. 2016 19:25

Toto jsem dělal do práce pro odpojování licencí, v případě jejich nevyužívání. Tam bylo dané, že aplikace - klidně dosovske okno - pokud se s ní pracuje, spotřebovává nějaký procesorový výkon, ten se dá v C# jednoduše monitorovat, a pokud je nulový , spustí se časovac. Pokud se do okna uživatel opět přepne, popřípadě aplikace sama potřebuje něco zpracovat, zvýší se zátěž na procesor a pokud tato je např. nad 5%, počítadlo se resetuje. Dělat to přes focus je vhodné, pouze pokud aplikace nepracuje na pozadí - tedy pracuje pouze pokud s ní pracuje uživatel.
X-Lorrien
Junior

Odeslat příspěvekod gandor 9. 1. 2016 12:31

Samozrejme ani toto ti nestaci, lebo velmi vela aplikacii ti periodicky bude nieco skumat, alebo budu v loope robit nejaku animaciu. Ako bolo povedane, zistit interakciu od uzivatela sa da len na konkretnu presnu app-ku
gandor
Mírně pokročilý

Odeslat příspěvekod Nnet 11. 1. 2016 06:47

Ah ani jsem nečekal tolik nápadů :)

Ano aplikace je pouze klient databáze běžící na serveru takže by šla sledovat síťová komunikace.
Dále aplikace se ovládá výhradně přes klávesnici a to většinou přes šipky.

Bohužel pro monimotování spotřeby prostředků to není, při používání se využití CPU drželo na 0 a využití RAM pendlovalo kolem 750kB :(

Edit: Takže by šlo použít kombinaci focus a sledování jestli měl uživatel nějaký vstup (klávesnici). Resetovat počítadlo pokaždé když jsou obě podmínky splněny :)
Hádku s blbcem nevyhraješ!

Desktop: Intel Xeon E3-1245V3, DDR3 16GB ECC, 160GB Intel SSD, Nvidia Quadro K2000

NB: Intel Core i7 720QM, 8GB DDR3, 750GB HDD, ATI 5650
Nnet
Junior
Uživatelský avatar

Odeslat příspěvekod Nnet 12. 1. 2016 10:39

Tak narážím na problém že Vámi nalezené kody jsou v C++ ale já to potřebuji dostat do batch souboru.

Musí to běžet od WXP do W10.

Takže počítadlo na 30 minut a reset pokud je na okně process.exe focus a pokud je zároveň vstup před klávesnici tak se resetuje počítadlo jinak dojde k ukončení procesu process.exe.

Nenašel jsem nikde pořádný web kde by byly příkazy pro batch
Hádku s blbcem nevyhraješ!

Desktop: Intel Xeon E3-1245V3, DDR3 16GB ECC, 160GB Intel SSD, Nvidia Quadro K2000

NB: Intel Core i7 720QM, 8GB DDR3, 750GB HDD, ATI 5650
Nnet
Junior
Uživatelský avatar

Odeslat příspěvekod Nargon 12. 1. 2016 11:19

V batch na to zapomeň. Tam myslím nic takového není možné (ale klidně mě někdo opravte pokud se mýlím). Jedině snad v powershellu by to šlo, ale ten je snad předinstalován až ve win vista a výše. U XPček se myslím musí doinstalovat, pokud tam teda vůbec jde.
Ale s kódem ti neporadím. Powershell jsem párkrát zkoušel, zjistíl jsem že tam lze využít klasické .NET knihovny ale tím to končilo. Už si nevybavuji jak se s tím pracovalo. Dodnes mi stačí klasický cmd batch a na složitější věci si napíšu aplikaci než to smolit do powershellu.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod JirkaVejrazka 12. 1. 2016 11:34

V danem pripade bych se podival na AutoIt. Pres batch to skoro urcite nepujde bez doinstalovani externich programu, minimalne neceho od SysInternals. A to uz je mozna jednodussi si ten hlidaci program napsat v AutoIt a zkompilovat do EXE
JirkaVejrazka
Mírně pokročilý

Odeslat příspěvekod Nnet 12. 1. 2016 12:33

AutoIt je pěkné s tím to půjde jedna báseň :) uvidíme jak pak bude fungovat exe.

Kdyby se mi zadařilo, pošlu sem zdroják.
Hádku s blbcem nevyhraješ!

Desktop: Intel Xeon E3-1245V3, DDR3 16GB ECC, 160GB Intel SSD, Nvidia Quadro K2000

NB: Intel Core i7 720QM, 8GB DDR3, 750GB HDD, ATI 5650
Nnet
Junior
Uživatelský avatar

Odeslat příspěvekod Nnet 13. 1. 2016 09:13

Tak mám kod.. je to sice prasárna ale funguje :)

Jinak zátěž CPU je docela vysoká (cca 2%)

Ještě kod trochu upravím ale kdyby měl někdo nápad jak snížit zátěž ale zanechat rychlou odezvu na klávesy, uvitám jakékoliv připomínky ;)

Ps: Hlídá jestli se objeví process.exe, pokud ano a je aktivní pak hlídá šipky. Pokud se nic z toho neděje po dobu určenou časovačem (ms) tak ukončí Proces.exe
Kód: Vybrat vše

#NoTrayIcon
;
; AutoIt Version: 3.3
; Language:       English
; Platform:       Win9x/NT
; Author:         Lukas Ott



Dim $aktivniOkno
Dim $lastTitle
Dim $casovac
HotKeySet("{SCROLLLOCK}", "_Terminate")
$casovac = 60000
Program()

Func Program()

    Local $aMgp = 0
    Local $check = 0
   Local $hDLL = DllOpen("user32.dll")
   Local $hTimer = TimerInit()

   While 1

     If ProcessExists ( "Proces.exe" ) Then
     $aktivniOkno =  WinGetTitle( "[ACTIVE]" )
     $check = StringInStr($aktivniOkno , "Proces")
     $fDiff = TimerDiff($hTimer)
     Sleep(10)

       If NOT $check = 0 Then
         If _IsPressed("25", $hDLL) Then
         $hTimer = TimerInit()
         Sleep(500)

         Elseif _IsPressed("26", $hDLL) Then
         $hTimer = TimerInit()
         Sleep(500)

         Elseif _IsPressed("27", $hDLL) Then
         $hTimer = TimerInit()
         Sleep(500)

         Elseif _IsPressed("28", $hDLL) Then
         $hTimer = TimerInit()
         Sleep(500)

           Elseif $fDiff >= $casovac Then
         ProcessClose ( "Proces.exe" )
         Sleep(500)
         EndIf

       Elseif $fDiff >= $casovac Then
         ProcessClose ( "Proces.exe" )
         Sleep(500)
       EndIf
     else
     $hTimer = TimerInit()
     Sleep(500)
   EndIf

   WEnd
EndFunc

Func _Terminate()
    Exit
EndFunc   ;==>_Terminate



EDIT: Vypnutím grafického vystupu to spadlo na 1%
Hádku s blbcem nevyhraješ!

Desktop: Intel Xeon E3-1245V3, DDR3 16GB ECC, 160GB Intel SSD, Nvidia Quadro K2000

NB: Intel Core i7 720QM, 8GB DDR3, 750GB HDD, ATI 5650
Nnet
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků