很多时候,有些程序希望它开机自动运行。当然实现的方式有很多种,如:注册表项、开始-程序-启动文件夹、计划任务、系统服务程序等等。
然而,计划任务是一般用户了解最少的一种。并且前两种是很容易修改和通过杀毒软件禁用的。
【This code is Task schedul 1.0 for Win XP】整理来自官网示例: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383581(v=vs.85).aspx
#include <windows.h> #include <initguid.h> #include <ole2.h> #include <mstask.h> #include <msterr.h> #include <objidl.h> #include <wchar.h> #include <stdio.h> void WGetUserName(WCHAR * username, int len) { // Get and display the name of the computer. char szName[ 255 ]; ULONG nLen = sizeof (szName); ::GetUserNameA(szName, & nLen); for (unsigned int i = 0 ; i < strlen(szName); i++ ) { username[i] = szName[i]; } username[strlen(szName)] = ' \0 ' ; } int main( int argc, char ** argv) { HRESULT hr = S_OK; ITaskScheduler * pITS; /////////////////////////////////////////////////////////////// // // Call CoInitialize to initialize the COM library and then // call CoCreateInstance to get the Task Scheduler object. /////////////////////////////////////////////////////////////// // hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, ( void **) & pITS); if (FAILED(hr)) { CoUninitialize(); return 1 ; } } else { return 1 ; } /////////////////////////////////////////////////////////////// // /// Get user name of the computer /////////////////////////////////////////////////////////////// // WCHAR username[ 512 ]; memset(username, 0 , sizeof (username)); WGetUserName(username, sizeof (username)); /////////////////////////////////////////////////////////////// // // Call ITaskScheduler::NewWorkItem to create new task. /////////////////////////////////////////////////////////////// // WCHAR pwszTaskName[ 512 ] = L " Veno Server WD_TEST_ " ; ITask * pITask; wcscat(pwszTaskName, username); hr = pITS->NewWorkItem(pwszTaskName, // Name of task CLSID_CTask, // Class identifier IID_ITask, // Interface identifier (IUnknown**)&pITask); // Address of task // interface pITS ->Release(); // Release object if (FAILED(hr)) { CoUninitialize(); fprintf(stderr, " Failed calling NewWorkItem, error = 0x%x\n " ,hr); return 1 ; } ////////////////////////////////////////////////////////////////// / // Call ITask::SetApplicationName to specify the Application name // for Test Task. ////////////////////////////////////////////////////////////////// / LPCWSTR pwszApplicationName = L " C:\\Windows\\System32\\notepad.exe " ; hr = pITask-> SetApplicationName(pwszApplicationName); if (FAILED(hr)) { wprintf(L " Failed calling ITask::SetApplicationName: " ); wprintf(L " error = 0x%x\n " ,hr); pITask -> Release(); CoUninitialize(); return 1 ; } //////////////////////////////////////////////////////////// / ////// set flag Only if logged on /// // //////////////////////////////////////////////////////////// / hr = pITask-> SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); if (FAILED(hr)) { wprintf(L " Failed calling ITask::EditWorkItem, " ); wprintf(L " error = 0x%x\n " ,hr); CoUninitialize(); return 1 ; } //////////////////////////////////////////////////////////// // set username for only for logged on hr = pITask->SetAccountInformation( username, NULL); // L"NT AUTHORITY\\SYSTEM"; if (FAILED(hr)) { wprintf(L " Failed calling ITask::SetApplicationName: " ); wprintf(L " error = 0x%x\n " ,hr); pITask -> Release(); CoUninitialize(); return 1 ; } ////////////////////////////////////////////////////////////////// / // Call ITask::CreateTrigger to create new trigger. ////////////////////////////////////////////////////////////////// / ITaskTrigger * pITaskTrigger; WORD piNewTrigger; hr = pITask->CreateTrigger(& piNewTrigger, & pITaskTrigger); if (FAILED(hr)) { wprintf(L " Failed calling ITask::CreatTrigger: " ); wprintf(L " error = 0x%x\n " ,hr); pITask -> Release(); CoUninitialize(); return 1 ; } ////////////////////////////////////////////////////// // Define TASK_TRIGGER structure. Note that wBeginDay, // wBeginMonth, and wBeginYear must be set to a valid // day, month, and year respectively. ////////////////////////////////////////////////////// TASK_TRIGGER pTrigger; ZeroMemory( &pTrigger, sizeof (TASK_TRIGGER)); // Add code to set trigger structure? pTrigger.wBeginDay = 1 ; // Required pTrigger.wBeginMonth = 1 ; // Required pTrigger.wBeginYear = 1999 ; // Required pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); pTrigger.wStartHour = 13 ; pTrigger.TriggerType = TASK_EVENT_TRIGGER_AT_LOGON; /// TASK_EVENT_TRIGGER_AT_SYSTEMSTART pTrigger.Type.Daily.DaysInterval = 1 ; ////////////////////////////////////////////////////////////////// / // Call ITaskTrigger::SetTrigger to set trigger criteria. ////////////////////////////////////////////////////////////////// / hr = pITaskTrigger->SetTrigger (& pTrigger); if (FAILED(hr)) { wprintf(L " Failed calling ITaskTrigger::SetTrigger: " ); wprintf(L " error = 0x%x\n " ,hr); pITask -> Release(); pITaskTrigger -> Release(); CoUninitialize(); return 1 ; } ////////////////////////////////////////////////////////////////// / // Call IPersistFile::Save to save trigger to disk. ////////////////////////////////////////////////////////////////// / IPersistFile * pIPersistFile; hr = pITask-> QueryInterface(IID_IPersistFile, ( void **)& pIPersistFile); hr = pIPersistFile-> Save(NULL, TRUE); if (FAILED(hr)) { wprintf(L " Failed calling IPersistFile::Save: " ); wprintf(L " error = 0x%x\n " ,hr); pITask -> Release(); pITaskTrigger -> Release(); pIPersistFile -> Release(); CoUninitialize(); return 1 ; } wprintf(L " The trigger was created and IPersistFile::Save was \n " ); wprintf(L " called to save the new trigger to disk.\n " ); ////////////////////////////////////////////////////////////////// / // Release resources. ////////////////////////////////////////////////////////////////// / pITask -> Release(); pITaskTrigger -> Release(); pIPersistFile -> Release(); CoUninitialize(); printf( " Created task.\n " ); return 0 ; }
【The shellexce command is easy for Win 7, and task scheldul 2.0 is also right.】
VOID Win7SchTasks() { TCHAR Location[MAX_PATH]; TCHAR cmd[ 255 ]; DWORD TapLocLen = 0 ; TapLocLen = GetCurrentDirectory( sizeof (Location),Location); if (TapLocLen == 0 ) { printf( " GetCurrentDirectory failed! Error is %d \n " , GetLastError()); return ; } char temp_path[MAX_PATH]; if (!GetVenoAppPaths(temp_path, sizeof (temp_path))) //这个函数的功能是得到一个可执文件的路径,可以自己写或者给temp_path赋一个指定的值。 { printf( " GetVenoAppPaths failed\n " ); return ; } sprintf(cmd, " /C schtasks /Create /tn \"Veno Server WD\" /tr \"\'%s\'\" /sc onlogon /rl HIGHEST /F " , temp_path); SHELLEXECUTEINFO sei; ZeroMemory ( &sei, sizeof (SHELLEXECUTEINFO)); sei.cbSize = sizeof (SHELLEXECUTEINFO); sei.lpVerb = " OPEN " ; sei.lpFile = " cmd.exe " ; sei.lpParameters = cmd; sei.nShow = SW_HIDE; sei.fMask = SEE_MASK_NOCLOSEPROCESS; ShellExecuteEx( & sei); WaitForSingleObject(sei.hProcess, INFINITE); printf( " Write SchTasks Complete\r\n " ); return ; }
因为在win XP 下ShellExecuteEx 是需要密码才能自动启动,它没有2.0开机启动的命令。而win7 有,所以这个用起来方便点,不过也因此带来其它问题,比如要重复执行,就要先删除再建。