jak zabránit dvojnásobnému spuštění ?
Skript VBS: RSS_viewer.vbs , který zasílá aplikaci posloupnost kláves.příkazů funguje bezchybně, ale vyskytl se problém:
u spuštění stiskem klávesy při jejím delším zmáčknutí dojde zřejmě ke dvojnásobnému provedení akce a promíchání příkazů
Existuje nějaký systémový prostředek, který by umožnil výhradní přístup ?
Popř. něco jako semafor, aniž bych musel používat zápis na disk ?
u spuštění stiskem klávesy při jejím delším zmáčknutí dojde zřejmě ke dvojnásobnému provedení akce a promíchání příkazů
Existuje nějaký systémový prostředek, který by umožnil výhradní přístup ?
Popř. něco jako semafor, aniž bych musel používat zápis na disk ?
Tak existují kritické sekce (rychlejší, pracují na úrovni vlákna) a mutexy (pomalejší, pracují na úrovni procesů).
K použití ve VBS přesně nevím, ale našel jsem k tomu následující definice:
[code]
Type CRITICAL_SECTION
Reserved1 As Long
Reserved2 As Long
Reserved3 As Long
Reserved4 As Long
Reserved5 As Long
Reserved6 As Long
End Type
Declare Sub InitializeCriticalSection Lib "kernel32" Alias "InitializeCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
Declare Sub EnterCriticalSection Lib "kernel32" Alias "EnterCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
Declare Sub LeaveCriticalSection Lib "kernel32" Alias "LeaveCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
Declare Sub DeleteCriticalSection Lib "kernel32" Alias "DeleteCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
[/code]
K použití ve VBS přesně nevím, ale našel jsem k tomu následující definice:
[code]
Type CRITICAL_SECTION
Reserved1 As Long
Reserved2 As Long
Reserved3 As Long
Reserved4 As Long
Reserved5 As Long
Reserved6 As Long
End Type
Declare Sub InitializeCriticalSection Lib "kernel32" Alias "InitializeCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
Declare Sub EnterCriticalSection Lib "kernel32" Alias "EnterCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
Declare Sub LeaveCriticalSection Lib "kernel32" Alias "LeaveCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
Declare Sub DeleteCriticalSection Lib "kernel32" Alias "DeleteCriticalSection" (lpCriticalSection As CRITICAL_SECTION)
[/code]
Příklady, které uvádíš, je asi zdroj.kód ve Visual Basicu (ten nemám)
Právě to volání API ve VBS mi dělá problém
- nevím jak na to
- přepsat celé do VB bych snad svedl (ale nemám VB)
Pokud bych chtěl zůstat u VBS, zkouším použít jeho příkazy s atributy souboru:
(toho spouštěného)
[code]'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dim fso ' VSTUP DO KRITICKÉ SEKCE
Dim act
Set fso = CreateObject("Scripting.FileSystemObject")
Set act = fso.GetFile(WScript.ScriptFullName)
if act.Attributes and 2 then WScript.Quit ' test HIDDEN , if ANO zrušit akci
act.Attributes = act.Attributes or 2 ' nastavit HIDDEN
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xxxxxxxxx
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' VÝSTUP Z KRITICKÉ SEKCE
act.Attributes = (act.Attributes or 2) - 2
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[/code]
Funguje bezvadně.
------------------------------------------------------------------
Ošetření (vstupní část krit.sekce) se týká těchto příkazů - kterými začíná program:
1. shell.AppActivate("opWindow") 'okno Opera <- fokus
2. sleep 100ms-400ms
Dost času na to nějakým způsobem detekovat vytíženost procesoru (stačila by mi nějaká přibližná/relativní hodnota)
To je další faktor, který - bez ošetření - bude způsobovat, že při pomalých reakcích OS nezvládne rychle po sobě jdoucí klávesy, které vysílá program.
Mám tam proměnnou která řídí čas.interval mezi klávesami
Právě to volání API ve VBS mi dělá problém
- nevím jak na to
- přepsat celé do VB bych snad svedl (ale nemám VB)
Pokud bych chtěl zůstat u VBS, zkouším použít jeho příkazy s atributy souboru:
(toho spouštěného)
[code]'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dim fso ' VSTUP DO KRITICKÉ SEKCE
Dim act
Set fso = CreateObject("Scripting.FileSystemObject")
Set act = fso.GetFile(WScript.ScriptFullName)
if act.Attributes and 2 then WScript.Quit ' test HIDDEN , if ANO zrušit akci
act.Attributes = act.Attributes or 2 ' nastavit HIDDEN
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xxxxxxxxx
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' VÝSTUP Z KRITICKÉ SEKCE
act.Attributes = (act.Attributes or 2) - 2
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[/code]
Funguje bezvadně.
------------------------------------------------------------------
Ošetření (vstupní část krit.sekce) se týká těchto příkazů - kterými začíná program:
1. shell.AppActivate("opWindow") 'okno Opera <- fokus
2. sleep 100ms-400ms
Dost času na to nějakým způsobem detekovat vytíženost procesoru (stačila by mi nějaká přibližná/relativní hodnota)
To je další faktor, který - bez ošetření - bude způsobovat, že při pomalých reakcích OS nezvládne rychle po sobě jdoucí klávesy, které vysílá program.
Mám tam proměnnou která řídí čas.interval mezi klávesami
Nedaří se mi deklarace ve VisualBasic
Stáhl jsem si free-beta MS VB 2008 a vytvořil kostru konzolové aplikace:
[code]Module Module1
????? DEKLARACE typu Kritická sekce ?????
Declare Sub InitializeCriticalSection Lib "kernel32" Alias "InitializeCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Declare Sub EnterCriticalSection Lib "kernel32" Alias "EnterCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Declare Sub LeaveCriticalSection Lib "kernel32" Alias "LeaveCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Declare Sub DeleteCriticalSection Lib "kernel32" Alias "DeleteCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Sub Main()
Dim cs AS CRITICAL_SECTION
CALL InitializeCriticalSection(cs)
CALL EnterCriticalSection(cs)
' >>> blok příkazů
CALL LeaveCriticalSection(cs)
CALL DeleteCriticalSection(cs)
End Sub
End Module[/code]
Error >>> Příkaz Type již není podporován: použijte příkaz Structure
Type CRITICAL_SECTION
Reserved1 As Long
Reserved2 As Long
Reserved3 As Long
Reserved4 As Long
Reserved5 As Long
Reserved6 As Long
End Type
Error >>> Structure must contain at least one instance member variable or Event declar.
Structure CRITICAL_SECTION
......
End Structure
NEJDŮLEŽITĚJŠÍ:
Nejsem si jistý, jestli po zprovoznění bude fungovat tak jak bych potřeboval - tzn. že pokud je kritická sekce používána, proces musí být UKONČEN. (Navíc jde o samostatné procesy=aplikace)
Stáhl jsem si free-beta MS VB 2008 a vytvořil kostru konzolové aplikace:
[code]Module Module1
????? DEKLARACE typu Kritická sekce ?????
Declare Sub InitializeCriticalSection Lib "kernel32" Alias "InitializeCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Declare Sub EnterCriticalSection Lib "kernel32" Alias "EnterCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Declare Sub LeaveCriticalSection Lib "kernel32" Alias "LeaveCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Declare Sub DeleteCriticalSection Lib "kernel32" Alias "DeleteCriticalSection" (ByVal lpCriticalSection As CRITICAL_SECTION)
Sub Main()
Dim cs AS CRITICAL_SECTION
CALL InitializeCriticalSection(cs)
CALL EnterCriticalSection(cs)
' >>> blok příkazů
CALL LeaveCriticalSection(cs)
CALL DeleteCriticalSection(cs)
End Sub
End Module[/code]
Error >>> Příkaz Type již není podporován: použijte příkaz Structure
Type CRITICAL_SECTION
Reserved1 As Long
Reserved2 As Long
Reserved3 As Long
Reserved4 As Long
Reserved5 As Long
Reserved6 As Long
End Type
Error >>> Structure must contain at least one instance member variable or Event declar.
Structure CRITICAL_SECTION
......
End Structure
NEJDŮLEŽITĚJŠÍ:
Nejsem si jistý, jestli po zprovoznění bude fungovat tak jak bych potřeboval - tzn. že pokud je kritická sekce používána, proces musí být UKONČEN. (Navíc jde o samostatné procesy=aplikace)
Pokud je to mezi procesy, tak by zřejmě bylo třeba použít mutex:
CreateMutex
ReleaseMutex
WaitForSingleObject
Nějaký příklady pro VB jsou zde:
http://www.osix.net/modules/article/?id=6
http://stackoverflow.com/questions/947/how-to-use-a-mutex-in-visual-basic
http://www.developerfusion.com/article/5184/multithreading-in-vbnet/4/
CreateMutex
ReleaseMutex
WaitForSingleObject
Nějaký příklady pro VB jsou zde:
http://www.osix.net/modules/article/?id=6
http://stackoverflow.com/questions/947/how-to-use-a-mutex-in-visual-basic
http://www.developerfusion.com/article/5184/multithreading-in-vbnet/4/