示例#1
0
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;
}
示例#2
0
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;
}