x64 and x86 version

Oct 11, 2011 at 3:25 PM

Here on the official page http://globalmousekeyhook.codeplex.com/
when I download the binary I have two dlls. One for X64 and one for X86.
Which one should I choose in order to run it on both plattforms ?
Or do I have to intagrate both dll in my project ?

Oct 12, 2011 at 2:55 AM
Edited Oct 12, 2011 at 2:57 AM

The x86 build will run on both platforms.

I don't have much time right now, but I'll respond to your question and explain it more thoroughly tomorrow.

Oct 12, 2011 at 2:53 PM
Edited Oct 12, 2011 at 2:53 PM

As I stated last night, the x86 binary will run on both platforms with a 32-bit application.

The purpose of the x64 DLL is for 64-bit applications ONLY. In 64-bit Windows, there are some differences to the underlying API datatypes (MOUSEHOOKSTRUCTEX structure; LParam of CALLBACK PROC; etc.), which is the purpose for this DLL.

If you are creating an application and you want to have a separate build for each architecture (example http://tortoisehg.bitbucket.org/download/index.html), it would be best to add the MouseKeyboardActivityMonitor project from our source download, into your projects' Solution. Then add a reference to the MouseKeyboardActivityMonitor project, as is done in the demo project. This way, whichever architecture you are targeting will almost always be correct. Note: On a 64bit operating system, don't use "Any CPU" build - it won't work correctly for AppHooks.

Oct 12, 2011 at 3:16 PM

Hi,first of all, my compliments for the great work!!

I'm trying to use your code in an application compiled for x86 but it must run also on x64. I use the global hook just to perform auto-logout for the user who leaves the application/pc unused for a while.

It often happens that on Win7 64 (the app is compiled for x86, so it runs as 32bit app), the mouse events are not 'fired' so even if the user is still using either the application or he is outside the application, but he is using another app, say for example he is browsing the web, my application will disconnect the user since no mouse events are 'fired'. After, on the logout, I set the mousehooker.Enable = false and this instruction generates the following error: Invalid Hook HandleEverything seems to work fine on Win7 32.

I've tried both using your dll or adding the whole project to my solution.

Have you any ideas?

Oct 12, 2011 at 3:44 PM
Edited Oct 12, 2011 at 6:12 PM

There are a couple things that could be causing the issue.

First, Windows 7 x64 will remove a hook from the chain (i.e. destroy the handle) if hook processing takes too long.

Second, it is possible that the logout action removes the hook, in which case, the hook should be disabled before the subroutine for logging out is called.

Third, have you tried wrapping the code in a try { ... } catch (Exception ex) { ... } clause?

Oct 12, 2011 at 6:53 PM

@robynude:

Something else that I didn't think of before is, how are you testing the idle status?

The best way to test the idle status is to have a variable in which to store the timestamp from MouseEventExtArgs and/or KeyEventExtArgs, and upon each mouse and/or keyboard action, set the variable to e.Timestamp. Then have a timer running every so many seconds... 10-15 seconds should do depending on how accurate your program needs to be, and in the timer tick event, compare the current Environment.TickCount to the last timestamp. If it's more than X amount of time, then the user is idle. Here's a short example I threw together. You'd need to add more handlers though, like MouseDownExt, MouseWheel, etc.

 

private static int m_LastTimestamp;
private static MouseHookListener m_MouseListener;
private static System.Timers.Timer m_TickTock;

public static void Main(string[] args)
{
	
	m_LastTimestamp = Environment.TickCount;
	
	m_TickTock = new System.Timers.Timer();
	m_TickTock.Interval = 15000;	// 15 sec
	m_TickTock.Elapsed += TickTock_Elapsed;
	m_TickTock.Start();
	
	m_MouseListener = new MouseHookListener(new GlobalHooker());
	m_MouseListener.Enabled = true;
	m_MouseListener.MouseDownExt += MouseListener_MouseMoveExt;	
	
	// will wait for user input in this console before exiting
	Console.Write("Press any key to continue . . . ");
	Console.ReadKey(true);
	
	// get ready for application quit
	m_MouseListener.MouseMoveExt -= MouseListener_MouseMoveExt;
	m_MouseListener.Enabled = false;
	
	m_TickTock.Elapsed -= TickTock_Elapsed;
	m_TickTock.Stop();
}

private static void MouseListener_MouseMoveExt(object sender, MouseEventExtArgs e)
{
	m_LastTimestamp = e.Timestamp;
}

private static void TickTock_Elapsed(object sender, EventArgs e)
{
	// Windows ticks are measured in milliseconds
	// 600000 ms = 10 min
	if ((Environment.TickCount - m_LastTimestamp) >= 600000)
	{
		Console.WriteLine("Apple iBored.");
	}
}

Oct 12, 2011 at 7:01 PM

@PyrrhicVictor
I think this inactivity / idle status is a very obvious think people need to solve using global hooks.
Only way to do it using our library is to subscribe on relevant events as you suggested reset the timestamp.
We can avoid this overhead by providing a new class for this purpose which will attach directly to GlobalHooker?
Might be a good idea for a V4 feature.

Oct 12, 2011 at 7:17 PM

@gmamaladze

Agreed. 

Oct 13, 2011 at 8:39 AM
Edited Oct 13, 2011 at 2:53 PM

@PyrrhicVictor
I use a code similr to what you wrote, the difference is that on keyboard/mouse events, I reset the timer (stop and start). If the timer expires, do logout.

Mine is a winform app.

Here is the code:

private readonly KeyboardHookListener _keyboardHookManager;
private readonly MouseHookListener _mouseHookManager;

public MyForm()
{
.....
_keyboardHookManager = new KeyboardHookListener(new GlobalHooker());
_keyboardHookManager.KeyDown += ActHookKeyDown;
_keyboardHookManager.KeyPress += ActHookKeyPress;
_keyboardHookManager.KeyUp += ActHookKeyUp;

 _mouseHookManager = new MouseHookListener(new GlobalHooker());
 _mouseHookManager.MouseDown += ActHookOnMouseActivity;
 _mouseHookManager.MouseMove += ActHookOnMouseActivity;
 _mouseHookManager.MouseWheel += ActHookOnMouseActivity;

timerAutoLogout.Interval = 60 * 1000;  // 60 seconds
timerAutoLogout.Tick += new System.EventHandler(TimerAutoLogoutTick);

DoLogin();

}

private void DoLogin()
{
//show login form
......
// after successfull login
_keyboardHookManager.Enabled = true;
_mouseHookManager.Enabled = true;
timerAutoLogout.Enabled = true;
}

private void ActHookOnMouseActivity(object sender, MouseEventArgs e)
{
TimerAutoLogoutRestart();
}

private void ActHookKeyDown(object sender, KeyEventArgs e)
{
TimerAutoLogoutRestart();
}

private void ActHookKeyPress(object sender, KeyPressEventArgs e)
{
TimerAutoLogoutRestart();
}

private void ActHookKeyUp(object sender, KeyEventArgs e)
{
TimerAutoLogoutRestart();
}

private void TimerAutoLogoutRestart()
{
timerAutoLogout.Stop();
timerAutoLogout.Start();
}

private void TimerAutoLogoutTick(object sender, EventArgs e)
{
DoLogout();
}

private void DoLogout()
{
timerAutoLogout.Stop();
try
            {
                _keyboardHookManager.Enabled = false;
            }
            catch (Exception ex)
            {
                _logger.Error("Error stopping UserActivityHook KEYBOARD", ex);
            }
            try
            {
                _mouseHookManager.Enabled = false;
            }
            catch (Exception ex)
            {
                _logger.Error("Error stopping MOUSE ", ex); // <== here is where the exception is thrown
            }

DoLogin(); // wait for next login
}


I'm using .NET 2.0.
Doing some other tests, I discovered that If I run my application and your demo application on the same machine, both applications setted for global hook and setted to catch all events, the demo application stops receiving events as soon as I activate my application (by clicking on it) and the demo app restarts receiving events as soon as I click outside my application.
 
Oct 14, 2011 at 1:50 AM

@robynude

I've had an idea of why the error might be getting thrown, but need to test it. I'll get back to you as soon as I do.

Oct 14, 2011 at 8:20 AM

Thank you so much for you support!!!

Oct 17, 2011 at 8:26 AM
Hi,

yes, thanks very much. I tried it out. It works for both plattforms x86 and x64.

BR,
Matthias



Von: PyrrhicVictor <notifications@codeplex.com>
Gesendet: 12.10.2011 15:53:18
An: m.schneider_24@web.de
Betreff: Re: x64 and x86 version [GlobalMouseKeyHook:275461]

From: PyrrhicVictor

As I stated last night, the x86 binary will run on both platforms with a 32-bit application.

The purpose of the x64 DLL is for 64-bit applications ONLY. In 64-bit Windows, there are some differences to the underlying API datatypes (MOUSEHOOKSTRUCTEX structure; LParam of CALLBACK PROC; etc.), which is the purpose for this DLL.

If you are creating an application and you want to have a separate build for each architecture (example http://tortoisehg.bitbucket.org/download/index.html), it would be best to add the MouseKeyboardActivityMonitor project from our source download, into your projects Solution. Then add a reference to the MouseKeyboardActivityMonitor project, as is done in the demo project. This way, whichever architecture you are targeting will almost always be correct. Note: On a 64bit operating system, don't use "Any CPU" build - it won't work correctly for AppHooks.



SMS schreiben mit WEB.DE FreeMail - einfach, schnell und
kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192
Jan 14, 2012 at 7:37 PM

@PyrrhicVictor

Hi, your Oct 12 example does not work because apparently, console apps do not receive the mouse events. I spent a few hours wondering what's wrong. And when I changed from a console app to a forms app, it instantly worked.

Perhaps this has something to do with protection against keyloggers (when running as a service) like it is said on the project FAQ?

Anyway, just wanted to let you know. I have no need for my app to be a console app.

 

Cheers

Michael