Code:
/* Please give credit where credit is do. //
// //
// This code was writen by Nor. //
// using samples from MSDN and //
// http://www.cpprogramming.com //
// Use, Learn, Play. */
#define _WIN32_WINNT 0x0500
#include "Windows.h"
#include "Shlobj.h"
#include "Shellapi.h"
#include "resource.h"
char aboutbox[] = "This program will force myapp.exe to close\r\nWhen CTRL-Z is pressed\r\nUse it to quickly exit the game\r\nwhen it crashes\r\n -Nor";
HWND hDialog = 0;
MSG msg;
HINSTANCE TheInstance = 0;
bool run = true;
bool ctrl_key = false;
bool z_key = false;
DWORD RunSilent(char* strFunct, const char* strstrParams)
{
PROCESS_INFORMATION ProcessInfo; //Temp storage for RunSilent()
STARTUPINFO StartupInfo;
char Args[4096];
char *pEnvCMD = NULL;
char *pDefaultCMD = "CMD.EXE";
memset(&StartupInfo, 0, sizeof(StartupInfo));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow = SW_HIDE;
Args[0] = 0;
pEnvCMD = getenv("COMSPEC");
strcat(Args, strFunct);
strcat(Args, " ");
strcat(Args, strstrParams);
if (!CreateProcess( NULL, Args, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&StartupInfo,
&ProcessInfo))
{
return GetLastError();
}
Sleep(2000);
return 0;
}
////////// Start of file
//This code is from Q243953 in case you lose the article and wonder
//where this code came from.
class CLimitSingleInstance
{
protected:
DWORD m_dwLastError;
HANDLE m_hMutex;
public:
CLimitSingleInstance(TCHAR *strMutexName)
{
//Make sure that you use a name that is unique for this application otherwise
//two apps may think they are the same if they are using same name for
//3rd parm to CreateMutex
m_hMutex = CreateMutex(NULL, FALSE, strMutexName); //do early
m_dwLastError = GetLastError(); //save for use later...
}
~CLimitSingleInstance()
{
if (m_hMutex) //Do not forget to close handles.
{
CloseHandle(m_hMutex); //Do as late as possible.
m_hMutex = NULL; //Good habit to be in.
}
}
BOOL IsAnotherInstanceRunning()
{
return (ERROR_ALREADY_EXISTS == m_dwLastError);
}
};
////////// End of file
BOOL CALLBACK DialogProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND textbox;
switch (message)
{
case WM_INITDIALOG:
textbox = GetDlgItem(hwnd, IDC_EDIT1);
SendMessage (textbox, WM_SETTEXT, 0, (LPARAM) aboutbox );
return TRUE;
break;
case WM_COMMAND:
if ( LOWORD(wParam) == WM_RESTORE_FROM_TRAY ){
ShowWindow(hwnd, SW_RESTORE );
return TRUE;
}
if ( LOWORD(wParam) == WM_EXIT_FROM_TRAY ){
DialogProc( hwnd, WM_CLOSE, 0, 0 );
return TRUE;
}
return TRUE;
case WM_DESTROY:
return TRUE;
case WM_CLOSE:
DestroyWindow (hwnd);
PostQuitMessage(0);
run = false;
return TRUE;
case WM_SYSTEM_TRAY_MSG:
if( lParam == WM_RBUTTONDOWN ){
POINT pt;
MENUITEMINFO separatorBtn = {0};
separatorBtn.cbSize = sizeof(MENUITEMINFO);
separatorBtn.fMask = MIIM_FTYPE;
separatorBtn.fType = MFT_SEPARATOR;
HMENU hMenu = CreatePopupMenu();
if(hMenu){
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING, WM_RESTORE_FROM_TRAY,"&About" );
InsertMenuItem(hMenu, -1, FALSE, &separatorBtn);
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING, WM_EXIT_FROM_TRAY, "&Exit");
GetCursorPos(&pt);
SetForegroundWindow(hwnd);
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
PostMessage(hwnd, WM_NULL, 0, 0);
DestroyMenu(hMenu);
}
}
if( lParam == WM_LBUTTONDBLCLK ){
ShowWindow(hwnd, SW_RESTORE );
}
return TRUE;
case WM_SYSCOMMAND:
if (wParam == SC_MINIMIZE){
ShowWindow(hwnd,SW_HIDE);
return TRUE;
}
}
return FALSE;
}
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam){
BOOL Keystroke = false;
if (nCode == HC_ACTION)
{
PKBDLLHOOKSTRUCT p = ( PKBDLLHOOKSTRUCT ) lParam;
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if( p->vkCode == VK_CONTROL || p->vkCode == VK_LCONTROL || p->vkCode == VK_RCONTROL)
ctrl_key = true;
if( p->vkCode == 'Z' )
z_key = true;
break;
case WM_KEYUP:
case WM_SYSKEYUP:
if( p->vkCode == VK_CONTROL || p->vkCode == VK_LCONTROL || p->vkCode == VK_RCONTROL)
ctrl_key = false;
if( p->vkCode == 'Z' )
z_key = false;
break;
}
}
if( ctrl_key && z_key ){
RunSilent( "C:\\Windows\\System32\\taskkill.exe", "/IM myapp.exe /T /F" );
ctrl_key = false;
z_key = false;
return 1;
}
return CallNextHookEx( NULL, nCode, wParam, lParam );
}// End LowLevelKeyboardProc
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
//Ensure the program has the privilages needed to close another process.
if( !IsUserAnAdmin() ){
char szArgument[MAX_PATH];
strcpy(szArgument, GetCommandLine());
szArgument[strlen(szArgument)-2] = 0;
int error = (int)::ShellExecute(0, // owner window
"runas",
&szArgument[1],
0, // params
0, // directory
SW_SHOWNORMAL);
return 0;
}
//I only want one copy of this program running at any time
CLimitSingleInstance Instance(mytext);
if( Instance.IsAnotherInstanceRunning() )
return 0;
hDialog = CreateDialog (hInst, MAKEINTRESOURCE (IDD_DIALOG1), 0, (DLGPROC)DialogProc);
if (!hDialog)
{
char buf [100];
wsprintf (buf, "Error x%x", GetLastError ());
MessageBox (0, buf, "CreateDialog", MB_ICONEXCLAMATION | MB_OK);
return 1;
}
//System Tray Icon
NOTIFYICONDATA tnd;
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = hDialog;
tnd.uID = IDC_SYSTEMTRAY;
tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
tnd.uCallbackMessage = WM_SYSTEM_TRAY_MSG;
tnd.hIcon = LoadIcon (TheInstance, MAKEINTRESOURCE (IDI_ICON1));
strcpy(tnd.szTip,mytext);
Shell_NotifyIcon(NIM_ADD,&tnd);
HHOOK hhkLowLevelKybd = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, hInst, 0 );
if( hhkLowLevelKybd == NULL )
int error = GetLastError();
// process all windows messages on the queue
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
if (!IsDialogMessage (hDialog, &msg))
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
}
}
//Release hook
UnhookWindowsHookEx(hhkLowLevelKybd);
//destroy tastbar icon
Shell_NotifyIcon(NIM_DELETE,&tnd);
return msg.wParam;
}