|
|
// Notiflag.cpp : Defines the entry point for the application.
//***********************************************************************
// Reads a local XML file, hits the given url and gets back xml string
// with another url, places an icon in system tray and links it to the url..
// Copyright : Microsoft Corporation. PSSODEV team.
//
// Author : K J Babu (v-kjbad)
// Pramod Walvekar (v-pramwa)
//
//***********************************************************************
//includes
#include "stdafx.h"
#include "resource.h"
#include "Notiflag.h"
#include <crtdbg.h>
//#define _WIN32_IE 0x0500
#include <shellapi.h>
#include <shlwapi.h>
#include <wininet.h>
#include <ole2.h>
#include <initguid.h>
#include <mstask.h>
#include <wchar.h>
#include <prsht.h>
#include <MPC_main.h>
//#include <atlbase.h> //defined in notiflag.h
//#define WM_ICON WM_USER+333
#define WM_ICON 0xBFFF
#define ID_MYICON 5
// Global Variables:
HINSTANCE g_hInst; // current instance
WCHAR szTitle[_MAX_PATH + 1]; // title bar text
WCHAR szTaskName[_MAX_PATH + 1]; WCHAR szWindowClass[_MAX_PATH + 1]; // window class name
WCHAR szURL[_MAX_PATH + 1]; // URL to call if user clicks on the icon
HRESULT hr = ERROR_SUCCESS; HWND g_Hwnd;
//******************************************************************
// Main function
//
// checks for the program instance
// reads the client's incident list xml file
// makes a call to remoteURL and reads the returned xml
// adds program's executable path in the registry and
// loads the icon in system area (tray)
// waits for the single click on the icon and on single click
// removes the entry from the registry, load the IE window with URL
// and exits.
//******************************************************************
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MSG msg; int tmpDbgFlag; int nNumArgs = 0; LPCTSTR *cmdArgs = (LPCTSTR*)CommandLineToArgvW(GetCommandLineW(), &nNumArgs); #ifdef _DEBUG
MessageBox(0, cmdArgs[0], L"app path", 0); #endif
LoadString(hInstance, IDS_APP_TITLE, szTitle, _MAX_PATH); // check the previous instance of the program here
// return if program is already running.
HANDLE hMutex = CreateMutex(NULL,TRUE,szTitle); if(ERROR_ALREADY_EXISTS == GetLastError()) return 0; /*
* Set the debug-heap flag to keep freed blocks in the * heap's linked list - This will allow us to catch any * inadvertent use of freed memory */
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF; tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag(tmpDbgFlag);
// check if there are any command line parameters
if (nNumArgs > 1) { // check if the first parameter is either /t or -t, which indicates AddNotiTask
if((_tcscmp(cmdArgs[1], L"/t") == 0)||(_tcscmp(cmdArgs[1], L"-t") == 0)) { // as first argument is /t or -t, run the AddNotiTask component
hr = CallAddNotiTask(hInstance, cmdArgs, lpCmdLine); if(FAILED(hr)) goto endMain; } } else { hr = CallNotiflag(hInstance); if(FAILED(hr)) goto endMain;
//*** change the priorty of the program
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
// ***** All house keeping work done. start the program now...
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow)) goto endMain;
#ifdef _DEBUG
MessageBox(0, L"Loading Icon...", L"NotiFlag: msg", 0); #endif
// add the icon in system tray
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FLAGICON)); if(hIcon != NULL) { BOOL bRet = MyTaskBarAddIcon(g_Hwnd, ID_MYICON, hIcon); DestroyIcon(hIcon); if (bRet == FALSE)// failed to create the system icon
goto endMain; } #ifdef _DEBUG
MessageBox(0, L"Icon loaded! waiting for click", L"NotiFlag: msg", 0); #endif
// main message loop
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
#ifdef _DEBUG
MessageBox(0, L"closing NotiFlag program", L"NotiFlag: msg", 0); #endif
// remove the icon from system tray and do other cleaning, exit.
//
} CloseHandle(hMutex); return (int)msg.wParam; endMain: CloseHandle(hMutex); return -1; }
//*********************************************************************************
// MyRegisterClass
//
// PURPOSE: Registers the window class.
//*********************************************************************************
ATOM MyRegisterClass(HINSTANCE hInstance) { USES_CONVERSION; WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FLAGICON); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCTSTR)IDC_NOTIFLAG; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_FLAGICON ); return RegisterClassEx(&wcex); }
//*********************************************************************************
// InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//*********************************************************************************
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { // create the window with no display
g_Hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
return (g_Hwnd)?TRUE:FALSE; }
//*********************************************************************************
// WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//*********************************************************************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_DISABLE: // if user chose to disable task
hr = DisableTask(); // disable the task
if (FAILED(hr)) #ifdef _DEBUG
MessageBox(hWnd,L"Failed to disable task",L"PSSIncidentNotification",MB_OK); #endif
MyTaskBarDeleteIcon(g_Hwnd,ID_MYICON); // remove icon from tray
DestroyWindow(g_Hwnd); // end application
break; case IDC_SETFREQUENCY: // if user chose to change the frequency of the task
hr = EditTask(); // display task schedule settings so user can change it
if (FAILED(hr)) #ifdef _DEBUG
MessageBox(hWnd,L"No Changes in task",L"PSSIncidentNotification",MB_OK); #endif
break; default: break; } break; case WM_ICON: { if ((UINT)lParam == WM_LBUTTONDOWN) { // Show new Browser window with the given URL
ShellExecute(g_Hwnd, L"open", szURL, NULL, NULL, SW_SHOWNORMAL); MyTaskBarDeleteIcon(g_Hwnd,ID_MYICON); DestroyWindow(g_Hwnd); } //if(((UINT)lParam == 0x204) || ((UINT)lParam == 0x205))
if ((UINT)lParam == WM_RBUTTONDOWN) // if user clicks right button
{ POINT sPoint; HMENU hMenu=LoadMenu(g_hInst,MAKEINTRESOURCE(IDC_NOTIFLAG)); // load menu
if(hMenu!=NULL) { HMENU hSubMenu=GetSubMenu(hMenu,0); GetCursorPos(&sPoint); // get location of mouse
SetForegroundWindow(hWnd); TrackPopupMenu(hSubMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON ,sPoint.x,sPoint.y,0,hWnd,NULL); // track the menu
PostMessage(hWnd, WM_NULL, 0, 0); DestroyMenu(hMenu); } } break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
//****************************************************************************
// MyTaskBarAddIcon
//
// adds an icon to system tray.
// Returns : TRUE if successful, or FALSE otherwise.
//****************************************************************************
BOOL MyTaskBarAddIcon(HWND hwnd, UINT uID, HICON hicon) { NOTIFYICONDATA tnid={0}; // Find out what version of the shell we are using for tray icon stuff
HINSTANCE hShellDll; DLLGETVERSIONPROC pDllGetVersion; DLLVERSIONINFO dvi; BOOL bUseTrayBalloon = FALSE;
// balloon tooltip is supported only in shell32.dll 5.0, so check the version
hShellDll = LoadLibrary(L"Shell32.dll"); if(hShellDll != NULL) { // enable balloon tooltip if IE version is greater than 5
pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hShellDll, "DllGetVersion"); dvi.cbSize = sizeof(dvi); if(pDllGetVersion != NULL && SUCCEEDED((*pDllGetVersion)(&dvi))) if(dvi.dwMajorVersion >= 5) bUseTrayBalloon = TRUE; FreeLibrary(hShellDll); } //fill icon structure
tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = uID; tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; tnid.uCallbackMessage = WM_ICON; tnid.hIcon = hicon; LoadString(g_hInst, IDS_TOOLTIP, tnid.szTip, MAXSTRLEN(tnid.szTip)); if (bUseTrayBalloon) // if IE version supports this then...
{ tnid.uFlags |= NIF_INFO; tnid.uTimeout = 60000; // in milliseconds
tnid.dwInfoFlags = NIIF_INFO; LoadString(g_hInst, IDS_BALLOONTITLE, tnid.szInfoTitle, MAXSTRLEN(tnid.szInfoTitle)); LoadString(g_hInst, IDS_BALLOONTIP, tnid.szInfo, MAXSTRLEN(tnid.szInfo)); }
return Shell_NotifyIcon(NIM_ADD, &tnid); }
//****************************************************************************
// MyTaskBarDeleteIcon
//
// deletes an icon from the taskbar status area.
// Returns : TRUE if successful, or FALSE otherwise.
//****************************************************************************
BOOL MyTaskBarDeleteIcon(HWND hwnd, UINT uID) { NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = uID; return Shell_NotifyIcon(NIM_DELETE, &tnid); }
//****************************************************************************
// LoadThisXml
//
// Load the given file in XMLDOM object and returns that pointer
// Returns : XMLDom pointer
//***************************************************************************
CComPtr<IXMLDOMDocument> LoadThisXml(const WCHAR *csFileName) { // get smart pointer to IXMLDOMDocument interface
CComPtr<IXMLDOMDocument> pXmlDoc; VARIANT vFile; CComVariant vtest; VARIANT_BOOL vb=1; HRESULT hr; CComBSTR bstrVal(csFileName); // this has the output file
//initialize the variant
VariantInit(&vFile); vFile.vt = VT_BSTR; //specify that it contains a string
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXmlDoc); if (FAILED(hr)) return NULL;
//increase ref count, else pointer will be released twice before CoUnInitialize() and
// will throw exception
pXmlDoc.p->AddRef(); V_BSTR(&vFile) = bstrVal; pXmlDoc->put_async(VARIANT_FALSE); hr = pXmlDoc->load(vFile, &vb); if (FAILED (hr) || vb == 0) return NULL; VariantClear(&vFile);
return pXmlDoc; }
//****************************************************************************
// LoadHTTPRequestXml
//
// Makes the request to the asp page and gets the XML out of Response.
// Returns : XMLDom pointer
//****************************************************************************
CComPtr<IXMLDOMDocument> LoadHTTPRequestXml(WCHAR *csURL, CComPtr<IXMLDOMDocument> pDoc) { CComPtr<IXMLDOMDocument> pXmlDoc; CComPtr<IXMLHttpRequest> pRequest; CComPtr<IDispatch> pDispRes; CComPtr<IDispatch> pDisp; HRESULT hr; // create an instance of XMLHTTPRequest and open the connection
hr = CoCreateInstance(CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, IID_IXMLHttpRequest, (void**)&pRequest); if (FAILED(hr)) goto endRequestXml;
//hr = pRequest->open(CComBSTR(L("POST")), CComBSTR(csURL), _variantL(VARIANT_FALSE));
hr = pRequest->open( CComBSTR( L"POST" ), CComBSTR( csURL ), CComVariant(VARIANT_FALSE), CComVariant(), CComVariant()); if(FAILED(hr)) goto endRequestXml;
hr = pRequest->setRequestHeader(CComBSTR(L"ACCEPT_LANGUAGE"),CComBSTR(L"en-us")); if(FAILED(hr)) goto endRequestXml;
// send the xml now. Get the Dispatch pointer of XML
hr = pDoc->QueryInterface(IID_IDispatch, (void **)&pDisp); if (FAILED(hr)) goto endRequestXml; #ifdef _DEBUG
MessageBox(0, L"calling send", L"NotiFlag: LoadHTTPRequestXml", 0); #endif
// call send
VARIANT varDisp; varDisp.vt = VT_DISPATCH; varDisp.pdispVal = pDisp; hr = pRequest->send(varDisp); if (FAILED(hr)) goto endRequestXml; VariantClear(&varDisp);
#ifdef _DEBUG
MessageBox(0, L"calling getxmlresponse", L"NotiFlag: LoadHTTPRequestXml", 0); #endif
// Read the response
hr = pRequest->get_responseXML(&pDispRes); if (FAILED(hr)) goto endRequestXml; // get the XMLDom pointer from iDispatch
hr = pDispRes->QueryInterface(IID_IXMLDOMDocument, (void **)&pXmlDoc); if (FAILED(hr)) goto endRequestXml;
return pXmlDoc; endRequestXml: return NULL; }
//***********************************************************************************
// GetNodeValue
//
// Reads the node value from the given XMLDOMDocument and copies into csValue.
// Returns : 0 = success & -ve = error.
//***********************************************************************************
int GetNodeValue(CComPtr<IXMLDOMDocument> pXmlDoc,const WCHAR *csNode, WCHAR *csValue) { CComPtr<IXMLDOMNode> pNode; CComBSTR bstrIdValue(csNode); CComVariant vIdValue; HRESULT hr; // get to the node
hr = pXmlDoc->selectSingleNode(bstrIdValue, &pNode);
if (FAILED(hr) || pNode == NULL) return -1; // read the value of the specified tag
hr = pNode->get_nodeValue(&vIdValue); if (FAILED(hr)) return -1; { USES_CONVERSION; wcscpy( csValue, vIdValue.bstrVal ); } return 0; }
//***********************************************************************************
// CallNotiflag
//
// Loads local xml file and extracts url from it, hits the url, retrieves xml string
// Loads the retrieved xml string, checks a few conditions and if met,
// loads an icon in the system tray and when the user clicks on the icon,
// it takes him to that url in the HSS browser
// Returns : S_OK for success, E_FAIL for failure
//***********************************************************************************
HRESULT CallNotiflag(HINSTANCE hInstance) { #ifdef _DEBUG
MessageBox(0, L"Notiflag is active", L"Active", 0); #endif
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, _MAX_PATH); LoadString(hInstance, IDC_NOTIFLAG, szWindowClass, _MAX_PATH); MyRegisterClass(hInstance); hr = CoInitialize(NULL); if (FAILED(hr)) goto endNoti; { //*** to read the xml file info
//declare smart pointers to XMLDOMDocument Interface
CComPtr<IXMLDOMDocument> pSvrXmlDoc; CComPtr<IXMLDOMDocument> pUserXmlDoc;
//string variables to hold xml file path and node text
WCHAR csXmlFilePath[_MAX_PATH + 1]; WCHAR csUserXmlFile[_MAX_PATH + 1]; WCHAR csNode[_MAX_PATH + 1]; WCHAR csValue[1024]; WCHAR csUserProfile[_MAX_PATH + 1]; csValue[0] = '\0';
// get the user profile path
LoadString(hInstance, IDS_USERPROFILE, csUserProfile, _MAX_PATH); GetEnvironmentVariable(csUserProfile, csUserXmlFile, _MAX_PATH); //concatenate the xml file name to the profile path
LoadString(hInstance, IDS_XMLFILEPATH, csXmlFilePath, _MAX_PATH); _tcscat(csUserXmlFile, csXmlFilePath); #ifdef _DEBUG
MessageBox(0, csUserXmlFile, L"NotiFlag: client xml", 0); #endif
// load this xml file
if ((pUserXmlDoc = LoadThisXml(csUserXmlFile)) == NULL) goto endNoti; //get the value of the node "IncidentID"
LoadString(hInstance, IDS_INCIDENTID, csNode, _MAX_PATH); if (GetNodeValue(pUserXmlDoc, csNode, csValue)) goto endNoti;
if (csValue[0] != '\0') { //get the value of the node "RemoteURL"
LoadString(hInstance, IDS_REMOTEURL, csNode, _MAX_PATH); if (GetNodeValue(pUserXmlDoc, csNode, csValue)) goto endNoti; }
#ifdef _DEBUG
MessageBox(0, L"calling the asp file", L"NotiFlag: msg", 0); #endif
// load the server ASP page and load returned XML string in XMLDOM
if ((pSvrXmlDoc = LoadHTTPRequestXml(csValue, pUserXmlDoc)) == NULL) goto endNoti; _tcscpy(csValue, L"\0");
//get the value of the node "ResponseCount"
LoadString(hInstance, IDS_RESPONSECOUNT, csNode, _MAX_PATH); if (GetNodeValue(pSvrXmlDoc, csNode, csValue)) goto endNoti; if ((atoi((const char *)csValue)) <= 0) goto endNoti; // else proceed
#ifdef _DEBUG
MessageBox(0, L"reading values", L"NotiFlag: main", 0); #endif
// load the URL to hit
LoadString(hInstance, IDS_LOCATIONTOHIT, csNode, _MAX_PATH); if (GetNodeValue(pSvrXmlDoc, csNode, szURL) || szURL == NULL) goto endNoti; // load the serverdatetime
LoadString(hInstance, IDS_SERVERDATETIME, csNode, _MAX_PATH); if (GetNodeValue(pSvrXmlDoc, csNode, csValue)) goto endNoti; #ifdef _DEBUG
MessageBox(0, L"putting date and saving client xml", L"NotiFlag: main", 0); #endif
} //Close the COM library and release resources
CoUninitialize(); return hr=S_OK; endNoti: CoUninitialize(); return hr=E_FAIL; }
//***********************************************************************************
// CallAddNotiTask
//
// Creates a new task in the scheduler
// Returns : S_OK for success, E_FAIL for failure
//***********************************************************************************
HRESULT CallAddNotiTask(HINSTANCE hInstance, LPCTSTR *cmdArgs,LPTSTR lpCmdLine) { #ifdef _DEBUG
MessageBox(0, L"AddNotiTask is Active", L"Active", 0); MessageBox(0, cmdArgs[1], L"First argument", 0); #endif
hr = CoInitialize(NULL); if (FAILED(hr)) goto endAddNotiTask; { // smart interface pointers
CComPtr<ITaskScheduler> pITS; CComPtr<IUnknown> pITaskUnknown; CComPtr<IScheduledWorkItem> pIScheduledWorkItem; CComPtr<ITaskTrigger> pITaskTrigger; CComPtr<ITask> pITask; CComBSTR bstrAccName(lpCmdLine); CComBSTR bstrVal; WCHAR szUserName[_MAX_PATH + 1]; WCHAR szRegEntry[_MAX_PATH + 1]; DWORD cchUserName = MAXSTRLEN(szUserName);
if ( !GetUserName( szUserName, &cchUserName ) ) goto endAddNotiTask;
BOOL bTaskExists=FALSE;
// Create a Task Schedular object ...
hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pITS); if (FAILED(hr)) goto endAddNotiTask; ////////////////////////////////////////////////////////
// Check/Create a work item/Task
////////////////////////////////////////////////////////
LoadString(hInstance, IDS_TASKNAME, szTaskName, _MAX_PATH); // check if the work item already exists
if(SUCCEEDED(pITS->Activate((LPCWSTR)szTaskName, IID_ITask, &pITaskUnknown))) { bTaskExists = TRUE; hr = pITaskUnknown.QueryInterface(&pITask); goto endAddNotiTask; } else { // create a new work item
hr = pITS->NewWorkItem(szTaskName, // Name of task
CLSID_CTask, // Class identifier
IID_ITask, // Interface identifier
(IUnknown**)&pITask); // Address of task interface
} if (FAILED(hr)) goto endAddNotiTask; // set the account information
hr = pITask->QueryInterface(IID_IScheduledWorkItem, (void**)&pIScheduledWorkItem); if (FAILED(hr) || pIScheduledWorkItem==NULL) goto endAddNotiTask; hr = pIScheduledWorkItem->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON|TASK_FLAG_INTERACTIVE); // TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
if (FAILED(hr)) goto endAddNotiTask; hr = pIScheduledWorkItem->SetAccountInformation((LPCWSTR)szUserName, NULL); if (FAILED(hr)) goto endAddNotiTask; // get the exe path ...
{ bstrVal = cmdArgs[0]; hr = pITask->SetApplicationName(bstrVal); if (FAILED (hr)) goto endAddNotiTask; }
///////////////////////////////////////////////////////////////////
// Define TASK_TRIGGER structure.
// Check/Create the new trigger.
///////////////////////////////////////////////////////////////////
TASK_TRIGGER pTrigger; ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER);
if (bTaskExists) { hr = pIScheduledWorkItem->GetTrigger(0, &pITaskTrigger); if (FAILED(hr) || pITaskTrigger == NULL) goto endAddNotiTask; hr = pITaskTrigger->GetTrigger(&pTrigger); if (FAILED(hr)) goto endAddNotiTask; } else { WORD piNewTrigger; hr = pIScheduledWorkItem->CreateTrigger(&piNewTrigger, &pITaskTrigger); if (FAILED(hr)) goto endAddNotiTask; } if (FAILED(hr) || pITaskTrigger == NULL) goto endAddNotiTask; // add the entry in the registry
{ TCHAR szExePath[_MAX_PATH + 1]; HKEY hKey; if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\PSS\\Notification", 0, KEY_ALL_ACCESS, &hKey)) { #ifdef _DEBUG
MessageBox(0, L"no registry entry", L"notitask", 0); #endif
// if key doesnt exist, use default values
pTrigger.wStartHour = 2; // start from the 1st hour
pTrigger.wStartMinute = 0; pTrigger.MinutesDuration = 1440; // for 24 hours
pTrigger.MinutesInterval = 15; // every 1 hour
// Note that wBeginDay, wBeginMonth, and wBeginYear must
// be set to a valid day, month, and year respectively.
pTrigger.wBeginDay = 1; // Required - 1st
pTrigger.wBeginMonth = 12; // Required - December
pTrigger.wBeginYear = 2000; // Required - 2000
} else { #ifdef _DEBUG
MessageBox(0, L"registry entry exists", L"notitask", 0); #endif
// if key exists, read from registry
DWORD lpType = 4; // type buffer
DWORD lpData=0; // data buffer
DWORD lpcbData=sizeof(DWORD); // size of data buffer
LoadString(NULL, IDS_WSTARTHOUR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (LPBYTE)&lpData, &lpcbData )) return -1; pTrigger.wStartHour = (WORD)lpData; // start from the 1st hour
LoadString(NULL, IDS_WSTARTMINUTE, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (LPBYTE)&lpData, &lpcbData )) return -1; pTrigger.wStartMinute = (WORD)lpData; LoadString(NULL, IDS_MINUTESDURATION, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (LPBYTE)&lpData, &lpcbData )) return -1; pTrigger.MinutesDuration = (WORD)lpData; // for 24 hours
LoadString(NULL, IDS_FREQUENCY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.MinutesInterval = (WORD)lpData; // for 24 hours
LoadString(NULL, IDS_WBEGINDAY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.wBeginDay = (WORD)lpData; // date of the month
LoadString(NULL, IDS_WBEGINMONTH, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.wBeginMonth = (WORD)lpData; // month
LoadString(NULL, IDS_WBEGINYEAR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.wBeginYear = (WORD)lpData; // year
}
pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY; pTrigger.Type.Daily.DaysInterval = 1; // daily!!
// get the application's executable path
::GetModuleFileName(hInstance, szExePath, _MAX_PATH); if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\PSS\\Notification", 0, KEY_ALL_ACCESS, &hKey)) { DWORD dwDisposition; DWORD szwStartHour = 1; DWORD szwStartMinute = 0; DWORD szMinutesDuration=1440; DWORD szMinutesInterval =15; DWORD szwBeginDay = 1; DWORD szwBeginMonth = 12; DWORD szwBeginYear = 2000;
LoadString(NULL, IDS_REGKEY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, szRegEntry, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition)) return -1; LoadString(NULL, IDS_WSTARTHOUR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartHour, sizeof(szwStartHour))) return -1; LoadString(NULL, IDS_WSTARTMINUTE, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartMinute, sizeof(szwStartMinute))) return -1; LoadString(NULL, IDS_MINUTESDURATION, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesDuration, sizeof(szMinutesDuration))) return -1; LoadString(NULL, IDS_FREQUENCY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesInterval, sizeof(szMinutesInterval))) return -1; LoadString(NULL, IDS_WBEGINDAY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginDay, sizeof(szwBeginDay))) return -1; LoadString(NULL, IDS_WBEGINMONTH, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginMonth, sizeof(szwBeginMonth))) return -1; LoadString(NULL, IDS_WBEGINYEAR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginYear, sizeof(szwBeginYear))) return -1; } RegCloseKey(hKey); }
// Call ITaskTrigger::SetTrigger to set trigger criteria.
hr = pITaskTrigger->SetTrigger (&pTrigger); if (FAILED(hr)) goto endAddNotiTask;
/////////////////////////////////////////////////////////////////
// Call IUnknown::QueryInterface to get a pointer to
// IPersistFile and IPersistFile::Save to save
// the new task to disk.
/////////////////////////////////////////////////////////////////
CComPtr<IPersistFile> pIPersistFile; hr = pITask->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile);
if (FAILED(hr) || pIPersistFile == NULL) goto endAddNotiTask; hr = pIPersistFile->Save(NULL, FALSE); if (FAILED(hr)) goto endAddNotiTask; } CoUninitialize(); return hr = S_OK;
endAddNotiTask: CoUninitialize(); return hr=E_FAIL; }
HRESULT DisableTask() { hr = CoInitialize(NULL); if (FAILED(hr)) goto endDisable; { CComPtr<ITaskScheduler> pITS; CComPtr<IUnknown> pITaskUnknown; CComPtr<IScheduledWorkItem> pIScheduledWorkItem; CComPtr<ITaskTrigger> pITaskTrigger; CComPtr<ITask> pITask;
WCHAR szUserName[_MAX_PATH + 1]; DWORD cchUserName = MAXSTRLEN(szUserName);
if ( !GetUserName( szUserName, &cchUserName ) ) goto endDisable;
hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pITS); if (FAILED(hr)) goto endDisable; LoadString(NULL, IDS_TASKNAME, szTaskName, _MAX_PATH); if(SUCCEEDED(pITS->Activate((LPCWSTR)szTaskName, IID_ITask, &pITaskUnknown))) { hr = pITaskUnknown.QueryInterface(&pITask); if (FAILED(hr)) goto endDisable; }
hr = pITask->QueryInterface(IID_IScheduledWorkItem, (void**)&pIScheduledWorkItem); if (FAILED(hr) || pIScheduledWorkItem==NULL) goto endDisable; //set the flags to disable the task
hr = pIScheduledWorkItem->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON|TASK_FLAG_INTERACTIVE|TASK_FLAG_DISABLED); // TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
if (FAILED(hr)) goto endDisable; // set the account information
hr = pIScheduledWorkItem->SetAccountInformation((LPCWSTR)szUserName, NULL); if (FAILED(hr)) goto endDisable;
/////////////////////////////////////////////////////////////////
// Call IUnknown::QueryInterface to get a pointer to
// IPersistFile and IPersistFile::Save to save
// the new task to disk.
/////////////////////////////////////////////////////////////////
CComPtr<IPersistFile> pIPersistFile; hr = pITask->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile);
if (FAILED(hr) || pIPersistFile == NULL) goto endDisable; hr = pIPersistFile->Save(NULL, FALSE); if (FAILED(hr)) goto endDisable; } CoUninitialize(); return hr=S_OK;
endDisable: CoUninitialize(); return hr=E_FAIL; }
HRESULT EditTask() { hr = CoInitialize(NULL); if (FAILED(hr)) goto endEdit; { CComPtr<ITaskScheduler> pITS; CComPtr<ITask> pITask; CComPtr<ITaskTrigger> pITaskTrigger;
hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pITS); if (FAILED(hr)) goto endEdit; LoadString(NULL, IDS_TASKNAME, szTaskName, _MAX_PATH); hr = pITS->Activate(szTaskName, IID_ITask, (IUnknown**) &pITask);
if (FAILED(hr)) goto endEdit;
///////////////////////////////////////////////////////////////////
// Call ITask::QueryInterface to retrieve the IProvideTaskPage
// interface, and call IProvideTaskPage::GetPage to retrieve the
// task page.
///////////////////////////////////////////////////////////////////
TASKPAGE tpType = TASKPAGE_SCHEDULE; BOOL fPersistChanges = TRUE; HPROPSHEETPAGE phPage;
CComPtr<IProvideTaskPage> pIProvTaskPage;
hr = pITask->QueryInterface(IID_IProvideTaskPage, (void **)&pIProvTaskPage); if (FAILED(hr)) goto endEdit; hr = pIProvTaskPage->GetPage(tpType, fPersistChanges, &phPage); if (FAILED(hr)) goto endEdit; //////////////////////////////////////////////////////////////////
// Display the page using additional code
//////////////////////////////////////////////////////////////////
PROPSHEETHEADER psh; ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW; psh.phpage = &phPage; psh.nPages = 1;
INT_PTR psResult = PropertySheet(&psh); if (psResult <= 0) goto endEdit;
///////////////////////////////////////////////////////////////////
// Define TASK_TRIGGER structure.
// Check/Create the new trigger.
///////////////////////////////////////////////////////////////////
TASK_TRIGGER pTrigger; ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER);
hr = pITask->GetTrigger(0, &pITaskTrigger); if (FAILED(hr) || pITaskTrigger == NULL) goto endEdit; hr = pITaskTrigger->GetTrigger(&pTrigger); if (FAILED(hr)) goto endEdit;
// add the entry in the registry
{ DWORD szwStartHour = 1; DWORD szwStartMinute = 0; DWORD szMinutesDuration = 1440; DWORD szMinutesInterval =15; DWORD szwBeginDay = 1; DWORD szwBeginMonth = 12; DWORD szwBeginYear = 2000; WCHAR szRegEntry[_MAX_PATH + 1]; HKEY hKey;
szwStartHour = pTrigger.wStartHour; szwStartMinute = pTrigger.wStartMinute; szMinutesInterval = pTrigger.MinutesInterval; szMinutesDuration = pTrigger.MinutesDuration; szwBeginDay = pTrigger.wBeginDay; szwBeginMonth = pTrigger.wBeginMonth; szwBeginYear = pTrigger.wBeginYear;
LoadString(NULL, IDS_REGKEY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szRegEntry, 0, KEY_ALL_ACCESS, &hKey)) { LoadString(NULL, IDS_WSTARTHOUR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartHour, sizeof(szwStartHour))) goto endEdit; LoadString(NULL, IDS_WSTARTMINUTE, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartMinute, sizeof(szwStartMinute))) goto endEdit; LoadString(NULL, IDS_MINUTESDURATION, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesDuration, sizeof(szMinutesDuration))) goto endEdit; LoadString(NULL, IDS_FREQUENCY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesInterval, sizeof(szMinutesInterval))) goto endEdit; LoadString(NULL, IDS_WBEGINDAY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginDay, sizeof(szwBeginDay))) goto endEdit; LoadString(NULL, IDS_WBEGINMONTH, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginMonth, sizeof(szwBeginMonth))) goto endEdit; LoadString(NULL, IDS_WBEGINYEAR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginYear, sizeof(szwBeginYear))) goto endEdit; } RegCloseKey(hKey); } } CoUninitialize(); return hr=S_OK;
endEdit: CoUninitialize(); return hr=E_FAIL; }
|