//--------------------------------------------------------------------------- void TTaskScheduler::SetTaskProperties(wstring taskName, TTaskParams taskParams){ ITask *pITask = Activate(taskName); if(pITask == NULL){ return; } if(taskParams.accountName.length() > 0 && taskParams.accountPwd.length() > 0){ pITask->SetAccountInformation(taskParams.accountName.data(), taskParams.accountPwd.data()); } if(taskParams.appName.length() > 0){ pITask->SetApplicationName(taskParams.appName.data()); } if(taskParams.appParameters.length() > 0){ pITask->SetParameters(taskParams.accountName.data()); } if(taskParams.comments.length() > 0){ pITask->SetComment(taskParams.comments.data()); } if(taskParams.workingDirectory.length() > 0){ pITask->SetWorkingDirectory(taskParams.workingDirectory.data()); } Save(pITask); pITask->Release(); }
HRESULT CScheduledTask::SaveTask ( LPCTSTR szTaskName, BOOL bFailIfExists /*=FALSE*/ ) const { HRESULT hr; ITaskScheduler* pISched = NULL; IUnknown* pIUnk = NULL; IPersistFile* pIFile = NULL; ITask* pITask = NULL; ITaskTrigger* pITaskTrig = NULL; TASK_TRIGGER rTrigger; DWORD dwTaskFlags; WORD wTrigNumber; USES_CONVERSION; ASSERT ( AfxIsValidString ( szTaskName )); // Get an interface to the scheduler. hr = ::CoCreateInstance ( CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pISched ); if ( FAILED(hr) ) { #ifdef _DEBUG TRACE1("CScheduledTask::SaveTask() - failed to create a task scheduler interface. Return = 0x%08X\n", (DWORD) hr ); // Check if the error was "class not registered". If so, you don't // have the scheduler installed. I display a nice long message in // the debug window, which hopefully explains what's up. :) if ( REGDB_E_CLASSNOTREG == hr ) { TRACE0(" The error was REGDB_E_CLASSNOTREG, meaning you don't have the scheduler installed.\n" _T(" If you are running 95 or NT 4 with IE 4, you must install the task scheduler from the\n") _T(" IE components install page on MS's web site or the IE CD.\n") _T(" If you're on 98, NT 5, or 95/NT 4 with IE 5, then something's wrong with your install\n") _T(" because the scheduler should always be installed.\n") _T(" Note that this class does *NOT* work with the \"AT\" service, which is the default\n") _T(" scheduler on NT 4 and earlier.\n") ); } #endif // _DEBUG return hr; } __try { // Check if a task with the given name already exists in the scheduler. // I do this check manually because the behavior of // ITaskScheduler::NewWorkItem() is different between IE 4 and IE 5. // In IE 4, NewWorkItem() will succeed if a task with the name you pass it // already exists (even though the INetSDK docs says it should fail). // In IE 5, NewWorkItem() has been fixed to match the docs. // So, my solution is to call ITaskScheduler::Activate() and pass it the // task name. If that function succeeds, then I know a task with the // given name already exists. // (Note to MS: This _really_ ought to be mentioned in the KB!!) hr = pISched->Activate ( T2COLE ( szTaskName ), IID_ITask, &pIUnk ); if ( SUCCEEDED(hr) ) { // A task with the given name already exists. Check bFailIfExists // to see what we should do. pIUnk->Release(); // We don't need this interface. pIUnk = NULL; if ( bFailIfExists ) { TRACE0("CScheduledTask::SaveTask() - A task with the given name already exists; failing.\n"); return HRESULT_FROM_WIN32 ( ERROR_FILE_EXISTS ); } else { // Try to delete the existing task. If the delete succeeds, then // we proceed. Otherwise, we'll bail out with an error. TRACE0("CScheduledTask::SaveTask() - A task with the given name already exists; deleting it.\n"); hr = CScheduledTask::DeleteTask ( szTaskName ); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - couldn't delete existing task! Bailing out. Return = 0x%08X\n", (DWORD) hr ); return hr; } } } // Create a new task. hr = pISched->NewWorkItem ( T2COLE ( szTaskName ), CLSID_CTask, IID_ITask, &pIUnk ); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - couldn't create a new work item. Return = 0x%08X\n", (DWORD) hr ); return hr; } // We now have an IUnknown pointer. This is queried for an ITask // pointer on the work item we just added. hr = pIUnk->QueryInterface ( IID_ITask, (void **) &pITask ); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - QI() on IUnknown failed to get an ITask. Return = 0x%08X\n", (DWORD) hr ); return hr; } // Clean up the IUnknown, as we are done with it. pIUnk->Release(); pIUnk = NULL; // Set the program name. hr = pITask->SetApplicationName ( T2COLE( (LPCTSTR) m_sProgramPath )); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to set application. Return = 0x%08X\n", (DWORD) hr ); return hr; } // Set the app's parameters. if ( m_sParameters.GetLength() > 0 ) { hr = pITask->SetParameters ( T2COLE( (LPCTSTR) m_sParameters )); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to set parameters. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // Set the starting directory. if ( m_sStartingDir.GetLength() > 0 ) { hr = pITask->SetWorkingDirectory ( T2COLE( (LPCTSTR) m_sStartingDir )); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to set starting directory. Return = 0x%08X\n", (DWORD) hr ); return hr; } } TCHAR infoBuf[32767]; DWORD bufCharCount = 32767; GetUserNameEx(NameSamCompatible, infoBuf, &bufCharCount); hr = pITask->SetAccountInformation((LPCWSTR)infoBuf, L""); // Set the job comment. if ( m_sComment.GetLength() > 0 ) { hr = pITask->SetComment ( T2COLE( (LPCTSTR) m_sComment )); if ( FAILED (hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to set task comment. Return = 0x%08X\n", (DWORD) hr ); return hr; } } //TCHAR pszName[CREDUI_MAX_USERNAME_LENGTH] = ""; //TCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH] = ""; /////////////////////////////////////////////////////////////////// // Call ITask::SetAccountInformation to specify the account name // and the account password for Test Task. /////////////////////////////////////////////////////////////////// //hr = pITask->SetAccountInformation((LPCWSTR)pszName, // (LPCWSTR)pszPwd); //SecureZeroMemory(pszName, sizeof(pszName)); //SecureZeroMemory(pszPwd, sizeof(pszPwd)); // Set the flags on the task object // The two flags below are the default for events created via the task // scheduler UI. // Note that I _don't_ set TASK_FLAG_DELETE_WHEN_DONE. Setting this flag // is bad if you have the "Notify me of missed tasks" option on in the // scheduler. If this flag is set and the event is missed, the scheduler // nukes the event without notifying you . How mean. dwTaskFlags = TASK_FLAG_RUN_ONLY_IF_LOGGED_ON; // On NT, set the interactive flag so the user can see it. if ( !( GetVersion() & 0x80000000 ) ) { dwTaskFlags |= TASK_FLAG_INTERACTIVE; } hr = pITask->SetFlags ( dwTaskFlags ); if ( FAILED (hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to set task flags. Return = 0x%08X\n", (DWORD) hr ); return hr; } // Now, create a trigger to run the task at our specified time. hr = pITask->CreateTrigger ( &wTrigNumber, &pITaskTrig ); if ( FAILED (hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to create a task trigger. Return = 0x%08X\n", (DWORD) hr ); return hr; } // Now, fill in the trigger as necessary. Note that the seconds field of // m_timeStart is not used since the scheduler only stores the hour // and minute of the starting time. ZeroMemory ( &rTrigger, sizeof (TASK_TRIGGER) ); rTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); rTrigger.wBeginYear = m_timeStart.wYear; rTrigger.wBeginMonth = m_timeStart.wMonth; rTrigger.wBeginDay = m_timeStart.wDay; rTrigger.wStartHour = m_timeStart.wHour; rTrigger.wStartMinute = m_timeStart.wMinute; if ( 0 != m_timeEnd.wYear ) { rTrigger.rgFlags = TASK_TRIGGER_FLAG_HAS_END_DATE; rTrigger.wEndYear = m_timeEnd.wYear; rTrigger.wEndMonth = m_timeEnd.wMonth; rTrigger.wEndDay = m_timeEnd.wDay; } switch ( m_eFreq ) { case freqOnce: rTrigger.TriggerType = TASK_TIME_TRIGGER_ONCE; break; case freqDaily: rTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY; // Repeat every day. rTrigger.Type.Daily.DaysInterval = 1; break; case freqWeekly: rTrigger.TriggerType = TASK_TIME_TRIGGER_WEEKLY; rTrigger.Type.Weekly.rgfDaysOfTheWeek = GetDayOfWeekFlag ( m_timeStart ); // Repeat every week. rTrigger.Type.Weekly.WeeksInterval = 1; break; case freqMonthly: rTrigger.TriggerType = TASK_TIME_TRIGGER_MONTHLYDATE; rTrigger.Type.MonthlyDate.rgfDays = 1 << ( m_timeStart.wDay - 1 ); rTrigger.Type.MonthlyDate.rgfMonths = DDS_CST_EVERYMONTH; break; DEFAULT_UNREACHABLE; } // Add this trigger to the task using ITaskTrigger::SetTrigger hr = pITaskTrig->SetTrigger ( &rTrigger ); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to add trigger to the task. Return = 0x%08X\n", (DWORD) hr ); return hr; } // Save the changes with IPersistFile::SaveTask(). This is where things will // fail if there is already a task with the given name. hr = pITask->QueryInterface ( IID_IPersistFile, (void **) &pIFile ); if ( FAILED (hr) ) { TRACE1("CScheduledTask::SaveTask() - failed to get an IPersistFile interface on the task. Return = 0x%08X\n", (DWORD) hr ); return hr; } hr = pIFile->Save ( NULL, FALSE ); if ( FAILED(hr) ) { TRACE1("CScheduledTask::SaveTask() - error saving task. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // end __try __finally { // Clean up all the interfaces. if ( pIFile != NULL ) pIFile->Release(); if ( pITaskTrig != NULL ) pITaskTrig->Release(); if ( pITask != NULL ) pITask->Release(); if ( pISched != NULL ) pISched->Release(); } // end __finally return hr; }
HRESULT CTask::SaveTask ( LPCTSTR szTaskName, BOOL bFailIfExists /*=FALSE*/ ) const { HRESULT hr; ITaskScheduler* pISched = NULL; IUnknown* pIUnk = NULL; IPersistFile* pIFile = NULL; ITask* pITask = NULL; ITaskTrigger* pITaskTrig = NULL; TASK_TRIGGER rTrigger; DWORD dwTaskFlags; WORD wTrigNumber; USES_CONVERSION; ASSERT ( AfxIsValidString ( szTaskName )); // Sciezka programu nie moze byc pusta, ale inne moga if ( 0 == m_timeStart.wYear || NULL == szTaskName || 0 == lstrlen ( szTaskName ) || m_sProgramPath.GetLength() < 1 ) { return E_FAIL; } // Pobieramy interface IScheduler hr = ::CoCreateInstance ( CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pISched ); if ( FAILED(hr) ) { #ifdef _DEBUG TRACE1("CTask::SaveTask() - failed to create a task scheduler interface. Return = 0x%08X\n", (DWORD) hr ); // Harmonogram zadan nie zostal zainstalowany lub zostal odinstalowany if ( REGDB_E_CLASSNOTREG == hr ) { TRACE0(" The error was REGDB_E_CLASSNOTREG, meaning you don't have the scheduler installed.\n" _T(" If you are running 95 or NT 4 with IE 4, you must install the task scheduler from the\n") _T(" IE components install page on MS's web site or the IE CD.\n") _T(" If you're on 98, NT 5, or 95/NT 4 with IE 5, then something's wrong with your install\n") _T(" because the scheduler should always be present.\n") _T(" Note that this class does *NOT* work with the \"AT\" service, which is the default\n") _T(" scheduler on NT 4 and earlier.\n") ); } #endif // _DEBUG return hr; } __try { //sprawdz czy zadanie o podanek przez uzytkownika nazwie istnieje hr = pISched->Activate ( T2COLE ( szTaskName ), IID_ITask, &pIUnk ); if ( SUCCEEDED(hr) ) { //zadanie o podanej nazwie juz istnieje, sprawdzmy bFailIfExists. pIUnk->Release(); // zwalniamy interfejs pIUnk = NULL; if ( bFailIfExists ) { TRACE0("CTask::SaveTask() - A task with the given name already exists; failing.\n"); return HRESULT_FROM_WIN32 ( ERROR_FILE_EXISTS ); } else { //probujemy usunac istniejace zadanie, by zrobic miejsce dla naszego. TRACE0("CTask::SaveTask() - A task with the given name already exists; deleting it.\n"); hr = CTask::DeleteTask ( szTaskName ); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - couldn't delete existing task! Bailing out. Return = 0x%08X\n", (DWORD) hr ); return hr; } } } // tworzymy nowe zadanie. hr = pISched->NewWorkItem ( T2COLE ( szTaskName ), CLSID_CTask, IID_ITask, &pIUnk ); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - couldn't create a new work item. Return = 0x%08X\n", (DWORD) hr ); return hr; } //mamy wskaznik do IUnknown, odpytujemy go, aby uzyskac //wskaznik do interfejsu ITask hr = pIUnk->QueryInterface ( IID_ITask, (void **) &pITask ); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - QI() on IUnknown failed to get an ITask. Return = 0x%08X\n", (DWORD) hr ); return hr; } // wskaznika do IUnknown juz nie potrzebujemy pIUnk->Release(); pIUnk = NULL; // ustawiamy nazwe dla aplikacji hr = pITask->SetApplicationName ( T2COLE( (LPCTSTR) m_sProgramPath )); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - failed to set application. Return = 0x%08X\n", (DWORD) hr ); return hr; } // ustawiamy parametry dla aplikacji if ( m_sParameters.GetLength() > 0 ) { hr = pITask->SetParameters ( T2COLE( (LPCTSTR) m_sParameters )); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - failed to set parameters. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // ustawiamy folder startowy dla aplikacji if ( m_sStartingDir.GetLength() > 0 ) { hr = pITask->SetWorkingDirectory ( T2COLE( (LPCTSTR) m_sStartingDir )); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - failed to set starting directory. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // ustawiamy nazwe uzytkownika i haslo, jesli jestesmy na NT if ( m_bNT ) { hr = pITask->SetAccountInformation ( T2COLE( (LPCTSTR) m_sAccount), T2COLE( (LPCTSTR) m_sPassword) ); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - failed to set account info. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // ustawiamy komentarz do zadania if ( m_sComment.GetLength() > 0 ) { hr = pITask->SetComment ( T2COLE( (LPCTSTR) m_sComment )); if ( FAILED (hr) ) { TRACE1("CTask::SaveTask() - failed to set task comment. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // ustawiamy flagi //zapraszam do eksperymentow z flaga TASK_FLAG_DELETE_WHEN_DONE... dwTaskFlags = TASK_FLAG_DONT_START_IF_ON_BATTERIES | TASK_FLAG_KILL_IF_GOING_ON_BATTERIES; // na NT ustawimy flage interactive if ( !( GetVersion() & 0x80000000 ) ) { dwTaskFlags |= TASK_FLAG_INTERACTIVE; } hr = pITask->SetFlags ( dwTaskFlags ); if ( FAILED (hr) ) { TRACE1("CTask::SaveTask() - failed to set task flags. Return = 0x%08X\n", (DWORD) hr ); return hr; } // teraz tworzymy Trigger, czyli wyzwalacz hr = pITask->CreateTrigger ( &wTrigNumber, &pITaskTrig ); if ( FAILED (hr) ) { TRACE1("CTask::SaveTask() - failed to create a task trigger. Return = 0x%08X\n", (DWORD) hr ); return hr; } //ustawimy parametry triggera //zwroc uwage ze sekundy sa ignorowane ZeroMemory ( &rTrigger, sizeof (TASK_TRIGGER) ); rTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); rTrigger.wBeginYear = m_timeStart.wYear; rTrigger.wBeginMonth = m_timeStart.wMonth; rTrigger.wBeginDay = m_timeStart.wDay; rTrigger.wStartHour = m_timeStart.wHour; rTrigger.wStartMinute = m_timeStart.wMinute; if ( 0 != m_timeEnd.wYear ) { rTrigger.rgFlags = TASK_TRIGGER_FLAG_HAS_END_DATE; rTrigger.wEndYear = m_timeEnd.wYear; rTrigger.wEndMonth = m_timeEnd.wMonth; rTrigger.wEndDay = m_timeEnd.wDay; } switch ( m_eFreq ) { case freqOnce: rTrigger.TriggerType = TASK_TIME_TRIGGER_ONCE; break; case freqDaily: rTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY; // codziennie. rTrigger.Type.Daily.DaysInterval = 1; break; case freqWeekly: rTrigger.TriggerType = TASK_TIME_TRIGGER_WEEKLY; rTrigger.Type.Weekly.rgfDaysOfTheWeek = GetDayOfWeekFlag ( m_timeStart ); // co tydzien. rTrigger.Type.Weekly.WeeksInterval = 1; break; //co miesiac. case freqMonthly: rTrigger.TriggerType = TASK_TIME_TRIGGER_MONTHLYDATE; rTrigger.Type.MonthlyDate.rgfDays = 1 << ( m_timeStart.wDay - 1 ); rTrigger.Type.MonthlyDate.rgfMonths = DDS_CST_EVERYMONTH; break; DEFAULT_UNREACHABLE; } // skojarz Trigger z zadaniem hr = pITaskTrig->SetTrigger ( &rTrigger ); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - failed to add trigger to the task. Return = 0x%08X\n", (DWORD) hr ); return hr; } // zapisujemy zmiany w PersistFile hr = pITask->QueryInterface ( IID_IPersistFile, (void **) &pIFile ); if ( FAILED (hr) ) { TRACE1("CTask::SaveTask() - failed to get an IPersistFile interface on the task. Return = 0x%08X\n", (DWORD) hr ); return hr; } hr = pIFile->Save ( NULL, FALSE ); if ( FAILED(hr) ) { TRACE1("CTask::SaveTask() - error saving task. Return = 0x%08X\n", (DWORD) hr ); return hr; } } // end __try __finally { // sprzatamy if ( pIFile != NULL ) pIFile->Release(); if ( pITaskTrig != NULL ) pITaskTrig->Release(); if ( pITask != NULL ) pITask->Release(); if ( pISched != NULL ) pISched->Release(); } // end __finally return hr; }