Problems integrating Windows Sheduled Tasks into application
From: TVR Fan (nosuch_at_address.com)
Date: 03/26/04
- Next message: TVR Fan: "Re: Problems integrating Windows Sheduled Tasks into application"
- Previous message: Dmitry Friesen: "Re: How to create SDI Doc/View in MFC DLL?"
- Next in thread: TVR Fan: "Re: Problems integrating Windows Sheduled Tasks into application"
- Reply: TVR Fan: "Re: Problems integrating Windows Sheduled Tasks into application"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 26 Mar 2004 11:43:00 -0000
I'm writing a wizard that will add a job to the Windows Scheduled Tasks. The
first page is my own page where the user types a job name and selects an
application command. When the user preses Next, the Wizard generates the
actual command needed by Windows Scheduled Tasks, creates the new task and,
gets the handles to the tasks 'Schedule' and 'Settings' pages and adds them
and a final page to the wizard. The final page is mine again and provides
the Finish button, whereapon the new task is saved.
Unfortunately, when the task is saved, the schedule settings are not and I
get an access violation. The task has been added to the Windows Scheduled
Task but no schedules are set for it.
I've quite possibly implemented this in a brain dead way and won't take
offence at any terse replies, just so long as they help! :-)
Here's the code (with error checking removed for conciseness):
// The class CWizardSchedule controls the wizard and has the following
member
// variables
CWPSched01Welcome *m_pwpWelcomeDlg ; // a simple welcome screen
CWPSched10Task *m_pwpTaskDlg ; // For entering application
specific details
HPROPSHEETPAGE m_hpageScheduleDlg ; // this dialog is retrieved from
the task
HPROPSHEETPAGE m_hpageSettingsDlg ; // this dialog is retrieved from
the task
CWPSched99Finished *m_pwpFinishedDlg ; // A summary page with the
'Finished' button
// The Run() function actually sets up and calls the wizard
BOOL CWizardSchedule::Run(CWnd *pParentWindow)
{
CProperty*** wizardDlg ;
int iDlgReturn ;
ITask *pITask = NULL ;
// Initialise the options.
m_hpageScheduleDlg = NULL ;
m_hpageSettingsDlg = NULL ;
m_pwpFinishedDlg = new CWPSched99Finished ;
m_pwpTaskDlg->m_phpageScheduleDlg = &m_hpageScheduleDlg ;
m_pwpTaskDlg->m_phpageSettingsDlg = &m_hpageSettingsDlg ;
m_pwpTaskDlg->m_pwpFinishedDlg = m_pwpFinishedDlg ;
// Set the task interface pointers in the task pages so
// they point to a persistant object (the object is created
// within m_pwpTaskDlg)
m_pwpTaskDlg->m_ppITask = &pITask ;
m_pwpFinishedDlg->m_ppITask = &pITask ;
// Add pages to the wizard
wizardDlg.AddPage ( m_pwpWelcomeDlg ) ;
wizardDlg.AddPage ( m_pwpTaskDlg ) ;
// The task dialog will need to initialise the schedule and settings
dialogs
// once it has a task name.
// It will also add the finished page at that time.
//
// Run the wizard
//
wizardDlg.SetWizardMode () ;
iDlgReturn = wizardDlg.DoModal () ; // <-- this is the first highlited
point
// in my code when it goes Bang. It's
in /
// around the DestroyWindow() call at
the
// end of CProperty***::DoModal()
if ( iDlgReturn == ID_WIZFINISH )
{
// probably call the Persist interface
}
return true ;
}
// The CWPSched10Task::OnWizardNext() is where most of the com work is done
LRESULT CWPSched10Task::OnWizardNext()
{
// Checking of essential fields removed
if ( m_phpageScheduleDlg != NULL && *m_phpageScheduleDlg == NULL )
{
//=====================================================================
// We must create a new schedule object and add its pages to the wizard
// Checking of the return codes is removed for clarity
// Much of this code is lifted directly from the MSDN documentation
//=====================================================================
HRESULT hr = ERROR_SUCCESS;
// Call CoCreateInstance() to get a task scheduler object
ITaskScheduler *pITS;
hr = CoCreateInstance(CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(void **) &pITS);
// Call ITaskScheduler::NewWorkItem() or AddWorkItem() to get the task
// object
hr = pITS->NewWorkItem(m_stringJobTitle, // Name of task
CLSID_CTask, // Class identifier
IID_ITask, // Interface identifier
(IUnknown**)m_ppITask); // Address of task interface
pITS->Release(); // Release object
// Add the command and parameters
(*m_ppITask)->SetApplicationName ( m_strExecutable ) ;
(*m_ppITask)->SetParameters ( m_strParams ) ;
// Call ITask::QueryInterface() to get the IProvideTaskPage interface
IProvideTaskPage *pIProvTaskPage;
hr = (*m_ppITask)->QueryInterface(IID_IProvideTaskPage,
(void **)&pIProvTaskPage);
// Release the ITask interface. Don't do this as the task interface needs
to persist
// until the wizard closes.
//pITask->Release();
// Call IProvideTaskPage::GetPage() for the Schedule page
hr = pIProvTaskPage->GetPage(TASKPAGE_SCHEDULE,
TRUE, // persist changes
m_phpageScheduleDlg );
// Release the IProvideTaskPage interface.
pIProvTaskPage->Release();
// Call IProvideTaskPage::GetPage() for the Settings page
hr = pIProvTaskPage->GetPage(TASKPAGE_SETTINGS,
TRUE, // persist changes
m_phpageSettingsDlg );
// Release the IProvideTaskPage interface.
pIProvTaskPage->Release();
// Add the pages to the wizard
CProperty*** *pWizardDlg = (CProperty****)GetParent() ;
BOOL bResult ;
bResult = PropSheet_InsertPage (pWizardDlg->m_hWnd, 2,
*m_phpageScheduleDlg );
bResult = PropSheet_InsertPage (pWizardDlg->m_hWnd, 3,
*m_phpageSettingsDlg );
// Add the 'finished' page
pWizardDlg->AddPage ( m_pwpFinishedDlg ) ;
}
return CPropertyPage::OnWizardNext();
}
// CWPSched99Finished::OnWizardFinish() is where I try to save the
// task. It all appears to work but crashes with an access violation
// deep within windows and although the task is saved, any schedule
// that the user has defined is not.
// Again, error checking has been removed for clarity.
BOOL CWPSched99Finished::OnWizardFinish()
{
HRESULT hr = S_OK;
IPersistFile *pIPersistFile = NULL ;
// Just trying to see whether any schedules actually exist. It appears that
// none do, even when the user defines one.
WORD wCount ;
(*m_ppITask)->GetTriggerCount ( &wCount ) ;
/////////////////////////////////////////////////////////////////
// Call IUnknown::QueryInterface to get a pointer to
// IPersistFile and IPersistFile::Save to save
// the new task to disk.
/////////////////////////////////////////////////////////////////
hr = (*m_ppITask)->QueryInterface(IID_IPersistFile,
(void **)&pIPersistFile);
hr = pIPersistFile->Save(NULL,
TRUE);
// Free the interfaces
pIPersistFile->Release();
(*m_ppITask)->Release() ;
return CPropertyPage::OnWizardFinish();
}
The error I get is "Unhandled exception in PC_BaXMDI.exe (MSTASK.DLL):
0xC0000005: Access Violation"
Any help would be hugely welcomed!
---- Al.
- Next message: TVR Fan: "Re: Problems integrating Windows Sheduled Tasks into application"
- Previous message: Dmitry Friesen: "Re: How to create SDI Doc/View in MFC DLL?"
- Next in thread: TVR Fan: "Re: Problems integrating Windows Sheduled Tasks into application"
- Reply: TVR Fan: "Re: Problems integrating Windows Sheduled Tasks into application"
- Messages sorted by: [ date ] [ thread ]