Diskuze: Suspend mojí aplikace

C# .NET .NET (C# a Visual Basic) Suspend mojí aplikace American English version English version

Avatar
denoy
Člen
Avatar
denoy:

Zdravím,

potřebuji poradit, potřebuji detekovat v mojí aplikace, když jí někdo (třeba pomocí process explorer) nastaví zmražení (suspend), potřebuji provést jednu funkci a ta stačí, když se provede i po odmražení aplikace, zkoušel jsem to přes SystemEvents.Po­werModeChanged, ale ten mi detekuje jen odpojení napájení, uspání celého notebooku etc ..

Neví někdo, jak na to?

 
Odpovědět 16.1.2013 21:33
Avatar
Luboš Běhounek (Satik):

Obavam se, ze Windows zadnou message v tomto pripade neposila, takze se o tom v programu nedozvis a nezbyde ti nez to resit nejakou berlickou. Chces reagovat primo na to odmrazeni nebo jen obecne mit jistotu, ze treba probehl nejaky kod, ktery se ma spustit v urcitou dobu?

Nahoru Odpovědět 16.1.2013 21:51
:)
Avatar
denoy
Člen
Avatar
denoy:

Potřebuji v moji aplikaci především vědět, jestli k nějakému zmražení došlo, jestli mi to zjistí na začátku, nebo až se odmrazí je jedno, tak trochu jsem s tím počítal a už jsem zkoušel timer, ten se zastaví při zmražení, takže tou berličkou je možná timer, ale musel bych to ošetřit ještě jinak, uložit čas kdy se app zapla, kdy vypla a potom timer každou sekundu dávat nějaké proměnné +1 a pokud se čas konce (v sekundách) mínus čas začátku nerovná té proměnné, tak je jasné, že došlo ke zmražení, ale znám windows, co když zamrzne na 1 sec, nepřidá se +1 a už to nebude sedět, zase je to takové řešení ... takové makové, nenapadá Tě něco jiného?

 
Nahoru Odpovědět 16.1.2013 22:01
Avatar
Luboš Běhounek (Satik):

No, asi nebude žádné úplně košér řešení, pokud to nelze odchytit přímo v aplikaci...

Potřebuješ takto hlídat celou aplikaci nebo ti stačí hlídat jen určité kritické úseky - třeba jen určité funkce?

Nahoru Odpovědět 16.1.2013 22:14
:)
Avatar
denoy
Člen
Avatar
denoy:

Jak to přesně myslíš?

Mám aplikaci, ta vykonává nějakou činnost u klienta, resp. toho klienta kontroluje, jestli je vše jak má, nepodvádí a nemá něco jinak, on si může mou aplikaci zmrazit, udělat nějaký podvůdek a mou aplikaci zase spustit a už na to nepřijde a já potřebuji tomuhle buď zabránit, nebo když už, tak to zjistit.

 
Nahoru Odpovědět 16.1.2013 22:19
Avatar
Odpovídá na denoy
David Jančík [sczdavos]:

No tjo, sme chvilku googlil a nic sem nenašel. Možná to půjde ňákou externí knihovnou čekovat. Ale ten nápad s tím timerem mi příjde dobrej. Dej si třeba každejch 5 vteřin tick. A ulož si aktuální datum.
lastDateTime = DateTime.Now;
Při dalším ticku dáš jen to odečteš od současné pomocí metůdky Subtract a mrkneš na rozdíl, kterýmu můžeš dát nějaké rozmezí. Inkrementací proměnné představující vteřiny to ale určitě nedělej.

Nahoru Odpovědět 16.1.2013 22:26
Čím více času dostaneš, tím méně ho máš.
Avatar
Odpovídá na denoy
Luboš Běhounek (Satik):

Pokud neděláš v aplikaci nic časově náročného, co by ji na delší čas zaseklo, tak asi nejjednodušší by byl timer - interval nastavíš třeba na 100ms a při každém ticku si uložíš aktuální čas a při dalším ho porovnáš, jestli neuplynulo víc, než třeba 200ms (nech tam nějakou toleranci).

Nahoru Odpovědět 16.1.2013 22:28
:)
Avatar
Luboš Běhounek (Satik):

Nebo druhá varianta je mít druhý proces, který třeba jednou za vteřinu zkontroluje stav toho hlavního procesu a když zjistí, že je suspended, tak tomu hlavnímu dá vědět - třeba přes mutex (a ten hlavní, až se rozjede, tak podle mutexu pozná, že se stalo něco nekalého).

Editováno 16.1.2013 22:30
Nahoru Odpovědět 16.1.2013 22:29
:)
Avatar
denoy
Člen
Avatar
denoy:

S tím druhým procesem mě to právě taky napadlo, vyzkouším, otestuji a uvidím.

sczdavos to je ještě lepší nápad ukládat DateTime místo té proměnné, už to dostává nějaké ohrádky, nějak to ucelit a snad to bude super, díky za rady!

 
Nahoru Odpovědět 16.1.2013 22:35
Avatar
denoy
Člen
Avatar
denoy:

Ještě otázečka, pomocí čeho zjistit, jestli je daný process právě suspend? Našel jsem pro C# jak suspend nastavit, ale né jak detekovat, potom jsem našel funkci OpenThread, prošel jsem jí, jestli neobsahuje i něco jako IsThreadSuspend (kéžby), každopádně nic takového (také jen nastavení suspendu, neví někdo pomocí čeho to detekovat?

Process explorer uvádí status 'suspend', takže to nějak detekovat nejspíše jde, asi nějakou externí funkcí, ale nenašel jsem jí

 
Nahoru Odpovědět 17.1.2013 8:35
Avatar
Odpovídá na denoy
David Jančík [sczdavos]:

Jo to je možná ještě lepší. Spustit si další proces (který bude kontrolovat stav toho prvního a naopak) a když zjistí, že je suspend tak ho spustí. Ale někdo to může suspendnout naráz... http://stackoverflow.com/…s-in-c-sharp

A když je suspend tak ti p.Responding vrátí False

Nahoru Odpovědět 17.1.2013 9:47
Čím více času dostaneš, tím méně ho máš.
Avatar
lcet.m
Člen
Avatar
lcet.m:

Watchdog bych nedělal - stejně ti ho někdo může killnout. Nevím, jak dlouhý čas potřebuje tvůj uživatel k "nekalé činnosti", ale jestli stačí kontrola třeba jednou za minutu, tak bych klidně dával aktuální čas zakryptovaný někam do souboru a pravidelně kontroloval, jestli DateTime.Now - predchoziCas == interval +- pár vteřin. Dvakrát za rok se ti to otestuje ;)

Já jsem kdysi dávno přesně něco takového řešil - šikula uživatel přišel na to, že když posune na PC hodiny, nebude v logu vidět, že skončil noční šichtu trochu dřív :)

S tím Process.Responding jsou problémy - vrátí ti false i když něco na momentík zakousne hlavní vlákno (klidně i otevírání souboru atd.)

 
Nahoru Odpovědět  +1 17.1.2013 11:04
Avatar
Odpovídá na lcet.m
Luboš Běhounek (Satik):

Watchdoga může killnout, čas v souboru přepsat, není problém u procesu zjistit, kam zapisuje - třeba v Process Monitoru (ale umí to tuším i správce úloh->sledování prostředků) :)

Nebo můžeš použít oba postupy - watchdog s hlavním programem se můžou hlídat navzájem a do souboru si budeš ještě ukládat čas.

A ukládal bych si ten čas i někam uvnitř programu, pro případ, že by uživatel čas v souboru přepsal a obešel nějak watchdoga (i když ho samozřejmě může přepsat i v paměti, ale to už BFU nezvládne).

Nahoru Odpovědět 17.1.2013 11:30
:)
Avatar
Luboš Běhounek (Satik):

Proces nemůže být sám o sobě suspended, proces je suspended, pokud jsou suspended všechna jeho vlákna.

Takhle nějak by to mohlo vypadat (moc jsem to netestoval):

bool IsProcessSuspended(int pid)
{
    Process proc = Process.GetProcessById(pid);
    foreach (ProcessThread pT in proc.Threads)
    {
        if (pT.WaitReason != ThreadWaitReason.Suspended)
        {
            return false;
        }
    }
    return true;
}
Editováno 17.1.2013 11:59
Nahoru Odpovědět  +1 17.1.2013 11:57
:)
Avatar
denoy
Člen
Avatar
denoy:

Satik díky moc, já už zkoušel response, ale tam byl timeout 5 sekund, takže jsem to musel řešit ještě jinak a obejít ten timeout, což se mi podařilo, ale tento script trvá ani né 2 milisekundy, takže timer co 1 desetinu sekundy ani nebude vadit, každopádně využiji těch ochran více, jako třeba i s tím časem.

 
Nahoru Odpovědět 17.1.2013 20:50
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 15 zpráv z 15.