-
Mar 17th, 2011, 05:43 PM
#1
Thread Starter
Hyperactive Member
[vb2008]same identical code that works only in 6 PC out of 10
I have made a little Hotkeys utility for Poker Tables. I hook the keys and, depending from the key, I simulate a mouse click over the related table button.
To simulate the click I use the SendInput Api, using the code found in the Pinvoke page http://pinvoke.net/default.aspx/user32/sendinput.html, wit only little differences (.mkhi don't exists in the NativeMethods Class... a code error?? )
The Sub that make the job is this:
Code:
Private Sub DoMouse(ByVal flags As NativeMethods.MOUSEEVENTF, ByVal Wheel As Integer)
'wheel = +-120 if wheel event, 0 in other cases
'added hoping to improve the code, but nothing changes, Hwnd is a global variable
SetFocus(Hwnd)
Dim input As New NativeMethods.INPUT
Dim mi As New NativeMethods.MOUSEINPUT
input.dwType = NativeMethods.InputType.Mouse
input.mi = mi
input.mi.dwExtraInfo = IntPtr.Zero
input.mi.dx = 0
input.mi.dy = 0
input.mi.time = 0
input.mi.mouseData = Wheel ' can be used for WHEEL event see msdn
input.mi.dwFlags = flags
Dim cbSize As Integer = Marshal.SizeOf(GetType(NativeMethods.INPUT))
Dim result As Integer = NativeMethods.SendInput(1, input, cbSize)
If result = 0 Then Debug.WriteLine(Marshal.GetLastWin32Error)
End Sub
From the NativeMethods class I have removed all the code not related to the mouse, like this exemple:
Code:
<StructLayout(LayoutKind.Explicit, pack:=1, Size:=28)> _
Friend Structure INPUT
<FieldOffset(0)> Public dwType As InputType
<FieldOffset(4)> Public mi As MOUSEINPUT
End Structure
The Click sub is called from code like this:
Code:
Cursor.Position = New Point(WinX, WinY)
DoMouse(NativeMethods.MOUSEEVENTF.LEFTDOWN, 0)
Cursor.Position = New Point(WinX, WinY)
DoMouse(NativeMethods.MOUSEEVENTF.LEFTUP, 0)
This code works PERFECTLY in about 6 PCs out of ten, and does not work at all in 4 PCs out of ten. And this independently from the OS or the hardware.
Now the question is at the same time simple and complex: how is possible that the same identical code works in some PCs and don't works in others? Where is the problem?
The program assembler is set to work with Framework 2.0.
Last edited by phil2000; Mar 17th, 2011 at 05:49 PM.
-
Mar 17th, 2011, 05:57 PM
#2
Addicted Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
I can't tell you how many times code works perfectly on one computer and fails on another. It can be lots of things.
OS is different
Security/Group policies are different
MS updates might be applied on some and not on others.
And many more reasons, I am sure.
When I test code, I have several computers here I test it out on. If the code breaks on one machine, I use that machine and run the project in VS and debug it till I find why its failing.
To debug, if the code is failing silently without throwing an unhandled exception, that probably means the exception is being caught and I would set breakpoints at all my catch blocks.
Last edited by 7777; Mar 17th, 2011 at 06:01 PM.
-
Mar 17th, 2011, 05:59 PM
#3
Re: [vb2008]same identical code that works only in 6 PC out of 10
Not all things are identical .
1. Different .net/windows service packs
2. Different localization settings
3. Different user security settings
4. Different profile settings
5. Run as admin/UAC settings
6. Virus protection (keyboard hooks are a common thing to block)
7. Folder permissions, owners
-
Mar 17th, 2011, 06:00 PM
#4
Thread Starter
Hyperactive Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
Originally Posted by 7777
When I test code, I have several computers here I test it out on. If the code breaks on one machine, I use that machine and run the project in VS and debug it till I find why its failing.
In my case this is impossible... the PCs in which the code don't works are not available... other cities.
-
Mar 17th, 2011, 06:03 PM
#5
Re: [vb2008]same identical code that works only in 6 PC out of 10
Not impossible, but maybe slow, you can do remote debugging on the other side of the world, if you can VPN in.
-
Mar 17th, 2011, 06:04 PM
#6
Addicted Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
Well with 4 out of 10 failing, statistically if you were to simply try this code on 2 or 3 more computers(that you did have access too), you would probably find out the problem. My first guess is that its one bug thats affecting all 4 and not 4 separate and different bugs.
-
Mar 17th, 2011, 06:05 PM
#7
Thread Starter
Hyperactive Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
Originally Posted by Grimfort
Not all things are identical .
Ok mates, but listen to me...
The VB.net code IS NOT a compiled code: it is interpreted from the Framework that have the job to verify HW and SW and improve the code in consequence... OR NOT?????
Everywhere you read: the .NET code is less quick than the compiled code, but it works better because the Framework make all the necessary controls.
EDIT: if can help... I have canged the previous deprecated Mouse_Event API to improve the code, because this API itself had some problems on some PCs... now some PCs in wich the Mouse_Event worked don't works with the SendInput Api, and vice versa some PCs in which the Mouse_Event didn't work... work with the SendInput Api.... to be mad
Last edited by phil2000; Mar 17th, 2011 at 06:10 PM.
-
Mar 17th, 2011, 06:06 PM
#8
Re: [vb2008]same identical code that works only in 6 PC out of 10
If you are giving someone a .exe, it is compiled code. If you are giving someone your code, they are compiling it themselves.
The JIT part of it kicks in the first time you run an app, but that does not make the code work on that machine, it merely allows it to run optimized, not run correctly.
Last edited by Grimfort; Mar 17th, 2011 at 06:13 PM.
-
Mar 17th, 2011, 06:09 PM
#9
Addicted Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
You could save what you have. Create a duplicate project, and remove try catch blocks, so the program throws an unhandled exception. If you must have try catch for the code to work, then test the exception in the catch block and only catch the exception you expect to occur, and let the others bubble up.
The beta tester will then need to copy the exception and send it to you, so you can figure it out.
-
Mar 17th, 2011, 06:13 PM
#10
Addicted Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
Unless you are sending the user your vb project and they are using the vb compiler to compile your code, then it is already compiled to MSIL (or just IL). When the user runs the exe the framework compiles the MSIL to native code. So basically its a 2 step compile process. With C++ you can compile directly to native code, in VB.net this is pretty much impossible.
-
Mar 17th, 2011, 06:21 PM
#11
Addicted Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
You might find some more information about this by googling ngen.exe. This is a tool that microsoft offers that will compile your MSIL to native code before it is used. This will improve performance, and I have used it on larger websites to generate all the native code so that its not done on the fly.
But sadly, you can not just distribute the native code ngen creates. It's pretty much only useful when run on the target machine, to improve performance(and can not be used to protect your intellectual propertyfrom be reflected out)
-
Mar 17th, 2011, 06:27 PM
#12
Re: [vb2008]same identical code that works only in 6 PC out of 10
Have you any notion which part is failing?
Do a build with a messagebox to show that the hotkeys are working first.
-
Mar 18th, 2011, 02:22 AM
#13
Fanatic Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
I have the exact same thing. Lots of documentation and how-to of the "SendInput" API, but it never worked with me.
Try to display a messagebox with "getlasterror":
Code:
Public Function GetLastError() As String
Return New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error()).Message
End Function
Code:
msgbox(GetLastError())
-
Mar 18th, 2011, 08:14 AM
#14
Re: [vb2008]same identical code that works only in 6 PC out of 10
What does "not work at all" mean?
-
Mar 18th, 2011, 09:57 AM
#15
Re: [vb2008]same identical code that works only in 6 PC out of 10
My experience is this is par for the course when trying to simulate mouse input. Have you verified that all machines involved have exactly the same monitor resolution and DPI? In short, can you confirm everyone has the button in exactly the same place? It's possible your code is clicking, just not on the button.
-
Mar 18th, 2011, 11:40 AM
#16
Re: [vb2008]same identical code that works only in 6 PC out of 10
It's also possible the architecture of the 4 failing PC's are different. When you start invoking API's, that is no longer managed code which means the framework cannot guarantee it will run accordingly.
-
Mar 18th, 2011, 01:06 PM
#17
Re: [vb2008]same identical code that works only in 6 PC out of 10
Originally Posted by Grimfort
Have you any notion which part is failing?
Do a build with a messagebox to show that the hotkeys are working first.
My question exactly. There is no clear definition of "does not work at all".
-
Mar 18th, 2011, 08:35 PM
#18
Fanatic Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
I'll give a definition: You call the API, but nothing happens. No event is sent to the window (handle). Usually this means the OS is failing behind the scenes, but I haven't called "GetLastError" the time I 'tried' to use the SendInput API.
I'll try to find my old project and reply the error I get.
Ok, first error I got was:
The parameter is incorrect
This means my INPUT structure is broken or deprecated... sigh this again
vb Code:
Public Declare Function SendInput Lib "user32.dll" (ByVal cInputs As Integer, ByRef pInputs As INPUT, ByVal cbSize As Integer) As Integer
Public Structure INPUT
Dim dwType As Integer
Dim mkhi As MOUSEKEYBDHARDWAREINPUT
End Structure
Public Structure KEYBDINPUT
Public wVk As Short
Public wScan As Short
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
Public Structure HARDWAREINPUT
Public uMsg As Integer
Public wParamL As Short
Public wParamH As Short
End Structure
Public Structure MOUSEKEYBDHARDWAREINPUT
Public mi As MOUSEINPUT
Public ki As KEYBDINPUT
Public hi As HARDWAREINPUT
End Structure
Public Structure MOUSEINPUT
Public dx As Integer
Public dy As Integer
Public mouseData As Integer
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
Public Const INPUT_MOUSE As UInt32 = 0
Public Const INPUT_KEYBOARD As Integer = 1
Public Const INPUT_HARDWARE As Integer = 2
Public Const KEYEVENTF_EXTENDEDKEY As UInt32 = &H1
Public Const KEYEVENTF_KEYUP As UInt32 = &H2
Public Const KEYEVENTF_UNICODE As UInt32 = &H4
Public Const KEYEVENTF_SCANCODE As UInt32 = &H8
Public Const XBUTTON1 As UInt32 = &H1
Public Const XBUTTON2 As UInt32 = &H2
Public Const MOUSEEVENTF_MOVE As UInt32 = &H1
Public Const MOUSEEVENTF_LEFTDOWN As UInt32 = &H2
Public Const MOUSEEVENTF_LEFTUP As UInt32 = &H4
Public Const MOUSEEVENTF_RIGHTDOWN As UInt32 = &H8
Public Const MOUSEEVENTF_RIGHTUP As UInt32 = &H10
Public Const MOUSEEVENTF_MIDDLEDOWN As UInt32 = &H20
Public Const MOUSEEVENTF_MIDDLEUP As UInt32 = &H40
Public Const MOUSEEVENTF_XDOWN As UInt32 = &H80
Public Const MOUSEEVENTF_XUP As UInt32 = &H100
Public Const MOUSEEVENTF_WHEEL As UInt32 = &H800
Public Const MOUSEEVENTF_VIRTUALDESK As UInt32 = &H4000
Public Const MOUSEEVENTF_ABSOLUTE As UInt32 = &H8000
EDIT
Ow wait, you can't pass a handle through this function either. Well, I recommend going back to keybd_event and mouse_event. Worked with me without any trouble.
Code:
If key = Keys.LButton Then
If value = True Then mouse_event(&H2, 0, 0, 0, 1)
If value = False Then mouse_event(&H4, 0, 0, 0, 1)
ElseIf key = Keys.RButton Then
If value = True Then mouse_event(&H8, 0, 0, 0, 1)
If value = False Then mouse_event(&H10, 0, 0, 0, 1)
ElseIf key = Keys.MButton Then
If value = True Then mouse_event(&H20, 0, 0, 0, 1)
If value = False Then mouse_event(&H40, 0, 0, 0, 1)
ElseIf key = Keys.XButton1 Then
If value = True Then mouse_event(&H80, 0, 0, &H1, 1)
If value = False Then mouse_event(&H100, 0, 0, &H1, 1)
ElseIf key = Keys.XButton2 Then
If value = True Then mouse_event(&H80, 0, 0, &H2, 1)
If value = False Then mouse_event(&H100, 0, 0, &H2, 1)
Else
'keyboard input
If value = True Then keybd_event(key, KEYEVENTF.KEYDOWN)
If value = False Then keybd_event(key, KEYEVENTF.KEYUP)
End If
Last edited by bergerkiller; Mar 18th, 2011 at 08:52 PM.
-
Mar 20th, 2011, 05:01 PM
#19
Thread Starter
Hyperactive Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
Mouse_Event is deprecated...
Question:
My program uses an enormouse number of APIs based on the User32.dll
So I ask: User32 means that that dll works at 32 bit also with 64 bit processors? Since I make a large use of User32.dll may be will be better instead that complie the program for AnyCpu, compile it directly for x86?... or nothing changes?
-
Mar 20th, 2011, 06:04 PM
#20
Fanatic Member
Re: [vb2008]same identical code that works only in 6 PC out of 10
Well there is no "user64.dll" as far I can tell, and 32 bit dlls work fine in the 64 bit version. The bit version mostly changes processor and system memory, for example values are stored differently and are processed in larger chunks.
.
Could someone post "SendInput" code that actually WORKS? I have seen code using only the input structure, using purely the MOUSEINPUT etc. functions or the MOUSEKEYBDHARDWAREINPUT like I had. What are the correct parameters for this API? It has too many different methods...
EDIT
Found an example on the web that used a single byte array instead of the mi/ki/hi variables to mimic the union. I'll try it out tomorrow.
Last edited by bergerkiller; Mar 20th, 2011 at 07:12 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|