Introduction
When we want to install an application, sometimes we need to copy and paste the serial number separately. SNP (Serial Number Paster) is a tool that will paste serial numbers automatically.
For example, say you have an activation form where you need to copy and paste the serial number separately. SNP can do it with only one copy and paste action.
You should copy the whole serial number , for example (XXXX-XXXX-XXXX-XXXX), and click in the first text box, then press Ctrl+F11.
Background
Simulating user's mouse/keyboard input is interesting to me - may be for you also. Pressing a keyboard button is possible by Win23 API. I've used keybd_event. You can import these APIs using DllImport
attribute. Take a look at the following definition:
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, long dwFlags, ulong dwExtraInfo);
The argument of DllImport
is a Windows dll name which contains the function in next line (keybd_event
). All APIs which we want to import in .NET must begin with static extern keywords. The function name must exactly be like the API name. Arguments should convert to the proper data types in .NET. For more information, check this article.
Implementation
Pressing Up and Down a Key
I've added all necessary APIs in the KeyboardApi
class. So, to press down the control key, we should call the keybd_event
like this:
KeyboardAPI.keybd_event((byte)Keys.ControlKey, 0, KeyboardAPI.KEYDOWN, 0);
And to press up the control key:
KeyboardAPI.keybd_event((byte)Keys.ControlKey, 0, KeyboardAPI.KEYUP, 0);
To press down and up a key, I've written this function:
public void PressKey(Keys key)
{
KeyboardAPI.keybd_event((byte)key, 0, KeyboardAPI.KEYDOWN, 0);
KeyboardAPI.keybd_event((byte)key, 0, KeyboardAPI.KEYUP, 0);
}
Pressing a Modifier Key
PressModKey
function will help you to press up and down a specified modifier key. I've defined modifiers as:
public enum MODKEY { None, Ctrl, Alt, Shift, RWin, LWIN };
MODKEY
is defined only to simplify coding.
public void PressModKey(MODKEY modkey, bool PressDown)
{
switch(modkey)
{
case MODKEY.None :
break;
case MODKEY.Ctrl :
KeyboardAPI.keybd_event((byte)Keys.ControlKey, 0, PressDown ?
KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
break;
case MODKEY.Alt :
KeyboardAPI.keybd_event((byte)Keys.Menu, 0, PressDown ?
KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
break;
case MODKEY.Shift :
KeyboardAPI.keybd_event((byte)Keys.ShiftKey, 0,
PressDown ? KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
break;
case MODKEY.LWIN :
KeyboardAPI.keybd_event((byte)Keys.LWin, 0,
PressDown ? KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
break;
case MODKEY.RWin :
KeyboardAPI.keybd_event((byte)Keys.RWin, 0,
PressDown ? KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
break;
}
}
Hot Key
If you want to register a global keyboard combination which is able to have been called anywhere, you can use Hot Key. To register them, you should call RegisterHotKey
API. The prototype is:
[DllImport("User32.dll")]
public static extern int RegisterHotKey(
int hwnd,
int id,
uint fsModifiers,
uint vk);
hwnd
: handle of your form.
id
: a number which you've assigned to your hot key to tracing it.
fsModifiers
: keyboard modifiers like: Ctrl, Alt, Shift.
vk
: key code from this page.
Registering a Hot Key
To registering a hot key, I've written RegHotKey
function which will register Ctrl+F11.
public void RegHotKey()
{
if (KeyboardAPI.RegisterHotKey((int)Handle, HotKey_F11, KeyboardAPI.MOD_CONTROL, KeyboardAPI.VK_F11) == 0)
{
MessageBox.Show("Error = " + KeyboardAPI.GetLastError());
}
}
Note: The Most of Apis will return their exception messages using GetLastError
function.
The most important part of implementation: WndProc
All of windows in Windows operation system have WndProc
function which is responsible for receiving messages. These message contain all things which or window need them to work. Such as Mouse/Keyboard events. you should override it in your main form class. This function has an Message
argument type. It has WParam
parameter which, in our case, will indicate id of our hot key (which you registered it by RegisterHotKey function).
protected override void WndProc(ref Message m)
{
if ((int)m.WParam == HotKey_F11)
{
if( Clipboard.GetDataObject().GetDataPresent(DataFormats.Text, true) )
{
string sn = (string)Clipboard.GetDataObject().GetData(DataFormats.Text, true);
sn = sn.Trim();
string[] split = sn.Split(new char[] {'-',' ',},
StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < split.Length; i++)
{
try
{
Clipboard.SetDataObject(split[i], true, 5, 100);
}
catch
{
}
PressModKey(MODKEY.Ctrl, true);
PressKey(Keys.V);
PressModKey(MODKEY.Ctrl, false);
Thread.Sleep(100);
if (i < split.Length - 1 && ch_UseTab.Checked)
{
PressKey(Keys.Tab);
Thread.Sleep(100);
}
}
Clipboard.SetDataObject(sn , true);
}
}
base.WndProc (ref m);
}
As you have seen, I've read the clipboard which is contain the serial number (had copied by user). Then I've splited the serial number by some token('-', ' ') and copied the segments to clipboard in a for loop and pasted them using pressing Ctrl+V keys. If user had set the UseTab
option, A tab key will be pressed. Sleeps are for giving time to UI to past the segments to another application. Change the parameters of Sleep
function to see the results.
History
- Version 1.0: Aug. 8, 2012, First release.