local keyboard hook

B

bizcor

Is it possible to do a local keyboard hook to a process running in a
new thread. The process is a command line application and is
instanciated when a button is pressed on the main form. I have had the
hook working Globally, but this means that the hook logs keystokes
from the main app as well as the keystrokes fom the CMD process. The
hook is WH_KEYBOARD. I have tryed passing the threadId into setkeyhook
and thence to SetWindowsHookEx but the KeyboardProc never gets called.
Has anybody got any ideas?
 
W

Willy Denoyette [MVP]

bizcor said:
Is it possible to do a local keyboard hook to a process running in a
new thread. The process is a command line application and is
instanciated when a button is pressed on the main form. I have had the
hook working Globally, but this means that the hook logs keystokes
from the main app as well as the keystrokes fom the CMD process. The
hook is WH_KEYBOARD. I have tryed passing the threadId into setkeyhook
and thence to SetWindowsHookEx but the KeyboardProc never gets called.
Has anybody got any ideas?


Processes do not run in threads, cmd runs a separate process not related to the thread that
spawned this process.
What you need is the thread in the cmd process that owns the main window handle, you can get
this TID by a call (through PInvoke) to "User32" GetWindowThreadProcessId API .


Willy.
 
B

bizcor

Thanks Willy

I have now tried this and cannot get it to work!
can you look at the code snppits below to see if I am doing it
correctly:

Many thanks Steve[bizcor]

Code from Main form....

private void button11_Click(object sender, System.EventArgs e)
{
try
{
ThreadStart mts = new ThreadStart(runApplication);
Thread t = new Thread( mts );
t.Start();
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
}

}

private static void runApplication()
{
try
{
process1 = new Process();
process1.StartInfo.FileName = @"c:\phylip\seqboot.exe";
process1.EnableRaisingEvents = true;
process1.Exited+=new EventHandler(process1_Exited);
logger.SetFileName(@"c:\logger.txt");

// This does not work
//uint threadid1 = GetCurrentThreadId();
//Debug.Write("Current thread id 1 is: ");
//Debug.WriteLine(threadid1);
//uint threadid2 = (uint)AppDomain.GetCurrentThreadId();
//Debug.Write("Current thread id 2 is: ");
//Debug.WriteLine(threadid2);
//logger.StartLogger(threadid1);

process1.Start();

// Try Willys method
// Get processes window handle
IntPtr hdlWin = process1.MainWindowHandle;

// Set trHandle to null ?
IntPtr trdHandle = (IntPtr)0;

//Call method to get window thread
IntPtr retThread = GetWindowThreadProcessId(hdlWin,trdHandle);

Debug.Write("Window Thread is: ");
Debug.WriteLine(retThread.ToInt32());

//Call startlogger to set the hook
logger.StartLogger((uint)retThread.ToInt32());
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
}

Methods from Keylogger class ....


public bool StartLogger(uint byThread)
{
if(!isstarted)
{
FileInfo finfo = new FileInfo(sbDefaultFileName.ToString());
if(File.Exists(sbDefaultFileName.ToString()))
{
finfo.Delete();
}

using (StreamWriter swLog = finfo.CreateText())
{
swLog.Close();
}
finfo = null;


_ptrHookID = SetHook(_proc, byThread);
isstarted = true;
return true;
}
else
{
return false;
}
}

private static IntPtr SetHook(KeyboardProc _proc, uint byThread)
{
//Set hook from the current process
//Use using to allow auto Dispose
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
if(byThread==0)
{
Debug.WriteLine(curModule.ModuleName.ToString());
return SetWindowsHookEx(WH_KEYBOARD, _proc,
GetModuleHandle(curModule.ModuleName), 0);
}
else
{
Debug.WriteLine(curModule.ModuleName.ToString());
return SetWindowsHookEx(WH_KEYBOARD, _proc,
GetModuleHandle(curModule.ModuleName), byThread
);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top