cs_eltchio
Messages postés3Date d'inscriptionmercredi 29 octobre 2003StatutMembreDernière intervention10 février 2010
-
5 févr. 2010 à 09:49
cs_eltchio
Messages postés3Date d'inscriptionmercredi 29 octobre 2003StatutMembreDernière intervention10 février 2010
-
10 févr. 2010 à 09:44
Bonjour à tous, j'essaye de créer un service windows qui a pour but de vérifier (toutes les 5 secondes) si une fenêtre est ouverte. Si c'est le cas, celui-ci lance un certain programme.
Je suis sous Windows XP et je développe en visual studio 2008.
Voici le code (Service1.vb):
Imports System.Timers
Public Class Service1
Private WithEvents montimer As System.Timers.Timer
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
montimer = New System.Timers.Timer(5000)
montimer.Start()
AddHandler montimer.Elapsed, AddressOf OnTimedEvent
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
montimer.Stop()
End Sub
Public Sub OnTimedEvent(ByVal source As Object, ByVal e As Timers.ElapsedEventArgs) Handles montimer.Elapsed
Dim objShell As Object
Dim hWnd As Integer
Dim Titre_Fenetre As String = Space(256)
Dim TitreFen As String
Dim j As Integer
Dim session_c As Integer
Dim auto_lock As Integer
Dim Connex As Integer
Dim bFlag As Boolean
Dim WinHandle As Integer
Dim testXFP As String
Dim Ret As Integer
Dim lngHandle As Integer
Dim lngStartButton As Integer
On Error Resume Next
objShell = CreateObject("WScript.Shell")
Do While (Not IsDBNull(hWnd)) And (hWnd <> 0) 'Passe en revue chaque fenêtre
Titre_Fenetre = Space$(255)
Ret = GetWindowText(hWnd, Titre_Fenetre, 256)
If Titre_Fenetre <> Space$(255) Then
If IsWindowVisible(hWnd) = 1 Then
TitreFen = Titre_Fenetre
TitreFen = TitreFen.Substring(TitreFen, Ret)
j = j + 1
If Val(j) < 10 Then j = "0" & j
session_c = InStr(TitreFen, "La session courante d'XFP est bloquée")
Connex = InStr(TitreFen, "Connexion")
auto_lock = InStr(TitreFen, "E2S Auto Lock")
If (session_c 1) Or (Connex 1) Or (auto_lock = 1) Then
bFlag = True
End If
End If
End If
hWnd = GetWindow(hWnd, 2)
Loop
If bFlag = True Then
objShell.Run("c:\Dynamics\Switch_Module.exe")
End If
objShell = Nothing
End Sub
End Class
Ensuite Dans un module :
Module ModAPI
Public Declare Function GetWindow Lib "user32" (ByVal hWnd As Integer, ByVal wCmd As Integer) As Integer
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Integer, ByVal lpString As String, ByVal cch As Integer) As Integer
Public Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Integer) As Integer
Public Declare Function GetDesktopWindow Lib "user32" () As Integer
Public Declare Function ShowWindow Lib "user32" (ByVal hWnd As Integer, ByVal nCmdShow As Integer) As Integer
Public Const SW_MAXIMIZE = 3
End Module
Voila, forcement cela ne marche pas. Le service se lance bien, passe bien dans le timer. Mais maintenant comment réécrire le code de la sub OnTimedEvent ?
( par ex: le objShell = CreateObject("WScript.Shell") --> System.object )
elguevel
Messages postés718Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention22 novembre 20163 5 févr. 2010 à 13:27
Salut,
Déja je ne comprend pas ton probleme ?
Mais bon commentons quand meme ton code.
A première vu :
- Bravo pour l'import du System.Timers, beaucoup font l'erreur de mettre le composant Timer sur leur service.
Le start et le stop on l'air correct, mais toutefois il faudrait que tu ajoutes dans le Stop un truc du genre :
If (Not montimer Is Nothing) Then
montimer.Dispose()
End If
NB : Je met l'instanciation du Timer dans un Constructeur ... juste une histoire de gout.
Après pour ta méthode OnTimedEvent, là ya tout à revoir ... c'est plus du VB que du .Net :
* On Error Resume Next --> remplacer par des "Try ... Catch"
* objShell = CreateObject("WScript.Shell") --> Garde çà pour du VBScript uniquement
* Titre_Fenetre <> Space$(255) -> je pense que ce test sera toujours Vrai
* Val(j) --> çà sert à rien, J étant déja un Integer
* InStr --> A oublier, VB6 (cf. String.indexOf())
* Space$ --> idem
* IsDBNull(hWnd) -> ouai :-s
* TitreFen = TitreFen.Substring(TitreFen, Ret) --> TitreFen est une String ?? Ca ne peut pas marcher
* objShell.Run --> voir la class Process()
* j = "0" & j --> très sale, j est un entier et tu le transforme en chaine
En gros explique nous ton probleme, et pour ta fonction, reprend la ligne par ligne et vois comment tu peux faire çà en .Net
Si tu veux etre sur de ne pas utilisé de la syntaxe VB6, va dans les références de ton projet et décoche "Microsoft.VisualBasic"
cs_eltchio
Messages postés3Date d'inscriptionmercredi 29 octobre 2003StatutMembreDernière intervention10 février 2010 5 févr. 2010 à 14:19
En gros mon problème n'est pas vraiment la retranscription des fonctions VB6 en .net (style InStr). C'est vrai que je n'ai pas été très clair dans ma question.
1. C'est sur, je vais retranscrire le code VB6 en .net
2. C'était aussi pour savoir si le module tel que je l'ai écrit est correcte. Car j'ai vu qu'il fallait utilisé ceci pour l'utilisation des dll :
- <dllImport("user32.dll", ... , ...)> _
Function Getwindow()
End Function
...
3. Le timer est correcte. Un bon point ^^
4. Vérifier si pas de problème niveau mémoire.
5. En bref, c'était pour voir les grosses erreurs que j'aurai pus commettre.
Donc je vais de suite retranscrire le code vb en .net, ensuite vous faire un feedback d'autre eventuel problème.
cs_eltchio
Messages postés3Date d'inscriptionmercredi 29 octobre 2003StatutMembreDernière intervention10 février 2010 10 févr. 2010 à 09:44
Bonjour, voilà le service fonctionne correctement. Même si j'ai laissé du code VB. Voici le code :
Imports System.Timers
Imports System.Diagnostics
Public Class Service1
Private WithEvents montimer As System.Timers.Timer
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
montimer = New System.Timers.Timer(5000)
montimer.Start()
AddHandler montimer.Elapsed, AddressOf OnTimedEvent
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
montimer.Stop()
If (Not montimer Is Nothing) Then
montimer.Dispose()
End If
End Sub
Public Sub OnTimedEvent(ByVal source As Object, ByVal e As Timers.ElapsedEventArgs) Handles montimer.Elapsed
Dim hWnd As Integer
Dim Titre_Fenetre As String = Space(255)
Dim TitreFen As String
Dim session_c As Integer
Dim auto_lock As Integer
Dim Connex As Integer
Dim bFlag As Boolean
Dim Ret As Integer
Try
' Si le programme est déjà lancé, on ne fait rien.
If Not (Process.GetProcessesByName("Switch_Module").Length > 0) Then
hWnd = GetForegroundWindow
Ret = GetWindowTextLength(hWnd)
GetWindowText(hWnd, Titre_Fenetre, (Ret + 1))
If (InStr(Titre_Fenetre, "La session courante d'XFP est bloquée") <> 0) Or _
(InStr(Titre_Fenetre, "Connexion") <> 0) Or _
(InStr(Titre_Fenetre, "E2S Auto Lock") <> 0) Then
bFlag = False
hWnd = GetWindow(GetDesktopWindow(), 5)
Do While (Not IsDBNull(hWnd)) And (hWnd <> 0)
Titre_Fenetre = Space$(255)
Ret = GetWindowText(hWnd, Titre_Fenetre, 255)
If Titre_Fenetre <> Space$(255) Then
If IsWindowVisible(hWnd) = 1 Then
TitreFen Titre_Fenetre TitreFen Left(TitreFen, Ret)
session_c = InStr(TitreFen, "La session courante d'XFP est bloquée")
Connex = InStr(TitreFen, "Connexion")
auto_lock = InStr(TitreFen, "E2S Auto Lock")
If (session_c 1) Or (Connex 1) Or (auto_lock = 1) Then
bFlag = True
End If
End If
End If
hWnd = GetWindow(hWnd, 2) Loop
If bFlag = True Then
Process.Start("c:\Dynamics\Switch_Module.exe")
End If
End If
End If
Catch ex As Exception
' écriture dans le journal d'évènement
End Try
End Sub
End Class
J'ai laissé tourner le service pendant deux jours et pas de problème mémoire. (vu le peu de code, heureusement ^^).
Dans le catch je vais simplement écrire dans le journal d'évènement de windows (beaucoups d'exemple sur le net à ce sujet).
Maintenant si vous pouvez me faire part de votre expérience pour que le code soit plus professionnel, je suis preneur.