Jump to content

[Resolvido] Ajuda erro programa


a3deluxe
 Share

Recommended Posts

Boa tarde,

Precisava de uma ajudinha no seguinte programa, esta me a dar um erro.

O programa consiste no seguinte:

1- No Lauch Button - Abre Menu.exe ( como mostra a imagem)

prowatcher.jpg

2- Tem um TIMER, que quando abre um dos três programas do MENU.exe

começa a contar e quando encontra um dos três PROCESSOS, quando chega ao final do TIMER

fecha o programa que estiver em execução.

3- Se mexer no Rato o Timer volta ao 0

Aqui fica o código para uma ajudinha a ver onde tenho o erro.

//  

Public Class WatcherForm

Const MenuPath As String = "c:\TestMenu.exe"
Const MenuProcessName As String = "TestMenu"
Const TurnoffPath As String = "c:\file.rr"
Const TimerLimitSec As Integer = 5 ' In seconds

Dim MainProcessNames As String
Dim xProcess As Process
Dim TimerCount As Integer
Dim TimerLimitTicks As Integer ' In timer ticks

Public Structure MSLLHOOKSTRUCT
	Dim x As Integer
	Dim y As Integer
	Dim mouseData As Integer
	Dim flags As Integer
	Dim time As Integer
	Dim dwExtraInfo As Integer
End Structure

Const WH_MOUSE_LL As Integer = 14
Const HC_ACTION As Integer = 0

Delegate Function LowLevelMouseProcDelegate(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer

' Notice the ByRef parameters
Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As LowLevelMouseProcDelegate, ByVal hMod As IntPtr, ByVal dwThreadId As Integer) As IntPtr
Declare Function UnhookWindowsHookEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal hHook As IntPtr) As Boolean
Declare Function CallNextHookEx Lib "user32" Alias "CallNextHookEx" (ByVal hHook As IntPtr, ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer
Declare Function GetLastError Lib "kernel32" () As Integer

Dim MouseProcDelegate As LowLevelMouseProcDelegate
Dim hMouseHook As IntPtr

Private Sub WatcherForm_Load(sender As Object, e As EventArgs) Handles Me.Load
	Location = New Point(20, 20)
	TimerCount = 0
	ShowCount()
	TimerLimitTicks = TimerLimitSec * 5000 / WatcherTimer.Interval
	InstallMouseHook()
End Sub

Private Sub InstallMouseHook()
	' The delegate must be kept in a variable because it is going
	' to be passed to unmanaged code, otherwise it may be garbage collected.
	MouseProcDelegate = New LowLevelMouseProcDelegate(AddressOf LowLevelMouseProc)

	' For Windows 7, hMod can be IntPtr.Zero, but not for Windows XP
	Dim hMod As IntPtr = Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32()

	' Throws System Error 126 when the program is run in Debug mode if vshost is left enabled in Propertied->Debug
	hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProcDelegate, hMod, 0)
	If hMouseHook = IntPtr.Zero Then
		Dim LastError As Integer = GetLastError()
		Dim ErrorMessage As String = String.Format("Couldn't set mouse hook. Error {0}.", LastError)
		MsgBox(ErrorMessage, MsgBoxStyle.Critical)
		Application.Exit()
	End If
End Sub

Private Sub WatcherForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed

	If (IntPtr.op_Inequality(Me.hMouseHook, System.IntPtr.Zero)) Then
		ProcWatcher.WatcherForm.UnhookWindowsHookEx(Me.hMouseHook)
	End If

	'If hMouseHook <> IntPtr.Zero Then UnhookWindowsHookEx(hMouseHook)
End Sub

Private Sub LaunchButton_Click(sender As Object, e As EventArgs) Handles LaunchButton.Click
	Process.Start(MenuPath)
End Sub

Private Function LowLevelMouseProc(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer
	If nCode = HC_ACTION Then
		TimerCount = 0
		ShowCount()
	End If

	Return CallNextHookEx(hMouseHook, nCode, wParam, lParam)
End Function

Private Sub ShowCount()
	TimerCountLabel.Text = String.Format("TimerCount = {0}", TimerCount)
End Sub

Private Sub WatcherTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
	If (xProcess Is Nothing OrElse xProcess.ProcessName = "TestMenu") Then
		Dim array1 As Process() = Nothing
		If (Me.xProcess Is Nothing) Then
			array1 = Process.GetProcessesByName("TestMenu")
		Else
			Dim array2 As String = MainProcessNames
			Dim num1 As Integer = 0
			Do While (num1 < array2.Length())
				array1 = Process.GetProcessesByName(array2(num1))
				If (array1.Length() > 0) Then
[b]					Exit Loop  [/b] [b]-------> ERRO AQUI[/b]
				End If
				num1 = (num1 + 1)

			Loop
		End If
		If (array1.Length() > 0) Then
			Interaction.Beep()
			xProcess = array1(0)
			TimerCount = 0
			ShowCount()
			Return
		End If
	End If
	If (Me.xProcess Is [b]Not Nothing[/b]) Then  [b]-------> ERRO AQUI[/b]
		If (Me.xProcess.HasExited) Then
			System.IO.File.Delete("c:\file.rr")
		Else
		   TimerCount = (TimerCount + 1)
		   ShowCount()
			If (TimerCount >= TimerLimitTicks) Then
			   xProcess.Kill()
				System.Threading.Thread.Sleep(100)
				System.IO.File.Create("c:\file.rr").Dispose()
			End If
		End If
		If (xProcess.HasExited) Then
			xProcess = Nothing
			Interaction.Beep()
		End If
	End If
End Sub

End Class

Obrigado

Edited by a3deluxe
Link to comment
Share on other sites

Metes-te resolvido mas numa próxima, convinha dizer que erro te dá e em que linha do código te dá o erro.

Já agora, deves tentar usar sempre sintax de vb e não de vb6 com esses "Declare function"... usa DllImport em vez disso.

Link to comment
Share on other sites

O erro esta assinalado no codigo,

resolvi de outra maneira, usei varios Timer para cada um dos programas, nao consegui resolver desta maneira que era a melhor. nao tive qualquer ajuda aqui.

Link to comment
Share on other sites

Não li o código porque puseste "Resolvido" e eu calculei que apenas postasses o código todo para alguém fazer o debug por ti, mas agora que vi:

Edit: Eu vi este erro primeiro e pensei que era deste que tavas a falar, só depois é que vi que era apenas um 'aviso' para quem usasse o mesmo código, no entanto, vou te explicar o porquê na mesma:

na linha do

SetWindowsHookEx

erro 126 quer dizer "ERROR_MOD_NOT_FOUND", o que significa que o módulo não foi encontrado, como estás a usar o visual studio host process em debug, ao ires buscar o módulo pela classe reflection ele estará a ir buscar o módulo errado (já me aconteceu), ou desativas o vshost process ou tentas ir buscar de outra maneira tipo "Process.GetCurrentProcess().MainModule".

O erro que tens é de syntax, não podes usar 'Exit Loop' dentro de um 'Do... While', tens de usar 'Exit Do', quanto ao segundo erro, que erro é?

Quando quiseres identificar erro em código vb usa " ' " sem aspas, dessa maneira se alguém copiar o teu código para tentar reproduzir por ti, não ficará todo desformatado...

Fiz estas alterações ao teu código:

Const MenuPath As String = "c:\TestMenu.exe"
   Const MenuProcessName As String = "TestMenu"
   Const TurnoffPath As String = "c:\file.rr"
   Const TimerLimitSec As Integer = 5 ' In seconds
   Dim MainProcessNames As String
   Dim xProcess As Process
   Dim TimerCount As Integer
   Dim TimerLimitTicks As Integer ' In timer ticks
   Public Structure MSLLHOOKSTRUCT
    Dim x As Integer
    Dim y As Integer
    Dim mouseData As Integer
    Dim flags As Integer
    Dim time As Integer
    Dim dwExtraInfo As Integer
   End Structure
   Const WH_MOUSE_LL As Integer = 14
   Const HC_ACTION As Integer = 0
   Private Delegate Function LowLevelMouseProcDelegate(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer
   ' Notice the ByRef parameters
   <DllImport("user32.dll", SetLastError:=True)>
   Private Shared Function SetWindowsHookEx(ByVal hookType As Integer, ByVal lpfn As LowLevelMouseProcDelegate, ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr
   End Function
   <DllImport("user32.dll", SetLastError:=True)>
   Public Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function
   <DllImport("user32.dll")>
   Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, <[in]()> ByRef lParam As MSLLHOOKSTRUCT) As IntPtr
   End Function

   Dim MouseProcDelegate As LowLevelMouseProcDelegate
   Dim hMouseHook As IntPtr
   Private Sub WatcherForm_Load(sender As Object, e As EventArgs) Handles Me.Load
    Location = New Point(20, 20)
    TimerCount = 0
    ShowCount()
    TimerLimitTicks = TimerLimitSec * 5000 / WatcherTimer.Interval
    InstallMouseHook()
   End Sub
   Private Sub InstallMouseHook()
    ' The delegate must be kept in a variable because it is going
    ' to be passed to unmanaged code, otherwise it may be garbage collected.
    MouseProcDelegate = New LowLevelMouseProcDelegate(AddressOf LowLevelMouseProc)
    ' For Windows 7, hMod can be IntPtr.Zero, but not for Windows XP
    Dim hMod As IntPtr = Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32()
    ' Throws System Error 126 when the program is run in Debug mode if vshost is left enabled in Propertied->Debug
    hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProcDelegate, hMod, 0)
    If hMouseHook = IntPtr.Zero Then
	    Dim LastError As Integer = Marshal.GetLastWin32Error
	    Dim ErrorMessage As String = String.Format("Couldn't set mouse hook. Error {0}.", LastError)
	    MsgBox(ErrorMessage, MsgBoxStyle.Critical)
	    Application.Exit()
    End If
   End Sub
   Private Sub WatcherForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
    If (IntPtr.op_Inequality(Me.hMouseHook, System.IntPtr.Zero)) Then
	    ProcWatcher.WatcherForm.UnhookWindowsHookEx(Me.hMouseHook)
    End If
    'If hMouseHook <> IntPtr.Zero Then UnhookWindowsHookEx(hMouseHook)
   End Sub
   Private Sub LaunchButton_Click(sender As Object, e As EventArgs) Handles LaunchButton.Click
    Process.Start(MenuPath)
   End Sub
   Private Function LowLevelMouseProc(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer
    If nCode = HC_ACTION Then
	    TimerCount = 0
	    ShowCount()
    End If
    Return CallNextHookEx(hMouseHook, nCode, wParam, lParam)
   End Function
   Private Sub ShowCount()
    TimerCountLabel.Text = String.Format("TimerCount = {0}", TimerCount)
   End Sub
   Private Sub WatcherTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
    If (xProcess Is Nothing OrElse xProcess.ProcessName = "TestMenu") Then
	    Dim array1 As Process() = Nothing
	    If (Me.xProcess Is Nothing) Then
		    array1 = Process.GetProcessesByName("TestMenu")
	    Else
		    Dim array2 As String = MainProcessNames
		    Dim num1 As Integer = 0
		    Do While (num1 < array2.Length())
			    array1 = Process.GetProcessesByName(array2(num1))
			    If (array1.Length() > 0) Then
				    Exit Do
			    End If
		    Loop
	    End If
	    If (array1.Length() > 0) Then
		    Interaction.Beep()
		    xProcess = array1(0)
		    TimerCount = 0
		    ShowCount()
		    Return

Acho que não estraguei nada, removi-te o GetLastError p/invoke porque não é recomendado usar dentro de aplicações .net, deves usar o

Marshal.GetLastWin32Error

Substitui-te os Private Declare function por DllImport como deves usar em vb, Private Declare é vb6. no futuro deves usar o site pinvoke.net para obteres as declarações de funções nativas (p/invoke).

Tenta explicar qual é o erro que te dá para ver se te consigo 'limpar' mais o teu código.

Link to comment
Share on other sites

Pois, não te ajudei mais porque não entendo bem o que é que tás a tentar fazer...

tás a abrir o notepad e se não houver actividade por 5s ou o que for, fechas o notepad? É isso que pretendes?

Não entendo o que faz aí o hook do rato no meio, pretendes apenas ver o movimento do rato? Ou o 'movimento' de teclas/rato (tempo inativo) do sistema?

Link to comment
Share on other sites

1- O programa inicia executa outro programa um Menu com o Notepad,word e Paint.

2- Quando algum deles estiver aberto inicia o Timer.

3- se mexer o rato reinicia o timer e volta a 0

4- Se nao mexer ao fim de 5s fecha o programa que estiver aberto.

Quando fecha qualquer um cria o ficheiro file.rr

Link to comment
Share on other sites

Queres detectar movimento do rato no sistema todo ou na tua aplicação?

Só queres dar reset ao timer se o rato mecher? Não se as teclas forem premidas também? Porque poderias usar GetLastInputInfo se fosse este o caso e removias o hook, mas se é só o rato, vais ter de usar o hook...

Já agora, tu tás a complicar com o timer, podias simplesmente meter um intervalo de 5segundos e quando detectares movimento dares reset, e apenas meteres no código do timer para terminares o processo e escrever para o disco. Não precisas de usar variáveis separadas para contar, só complica.

Se tiveres alguma dúvida posta que talvez tenha tempo para te dar um exemplo.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.