win32utils-devel@rubyforge.org
2004-Jul-31 20:56 UTC
[Win32utils-devel] Bug in new_work_item
Hi all, Windows 2000 Ruby 1.8.2 R7 VC++ 6.0 I noticed that if I try to call new_work_item and give the task a name that already exists, I get a segfault: C:\eclipse\workspace\win32-taskscheduler>ruby test.rb "0.1.0" test.rb:22:in `new_work_item'': NewWorkItem() function failed (Win32::TaskSchedul erError) from test.rb:22 test.rb:22: [BUG] Segmentation fault ruby 1.8.2 (2004-07-29) [i386-mswin32] abnormal program termination Here''s test.rb: require "win32/taskscheduler" include Win32 p TaskScheduler::VERSION trigger = { "start_year" => 2009, "start_month" => 4, "start_day" => 11, "start_hour" => 7, "start_minute" => 14, "trigger_type" => TaskScheduler::DAILY, "type" => { "days_interval" => 1 } } ts = TaskScheduler.new ts.new_work_item("foo",trigger) I did find two things that I thought might solve the problem but didn''t seem to help. The first is to call ptr->pITS->Release() after the NewWorkItem() call. I''m not sure if that''s necessary or not, but they do that in their sample program on MSDN. The second thing I tried was adding CoUninitialize() if the call to NewWorkItem() failed before raising an exception. Neither helped. I also tried calling ts_free() explicitly before an exception was raised - still no luck. I''ve checked in some updated code, so take a look at what I''ve got in CVS and see if you can duplicate the problem and, if possible, figure out why it''s segfaulting. :) Thanks. Dan PS - I''ll submit a bug report for the Tracker __________________________________ Do you Yahoo!? Yahoo! Mail - You care about security. So do we. http://promotions.yahoo.com/new_mail
win32utils-devel@rubyforge.org
2004-Aug-01 02:24 UTC
[Win32utils-devel] Bug in new_work_item
> Hi all, >...> I''ve checked in some updated code, so take a look at > what I''ve got in CVS and see if you can duplicate the > problem and, if possible, figure out why it''s > segfaulting. :) > > Thanks. > > Dan > > PS - I''ll submit a bug report for the Tracker >Hi, all I attached fixed taskscheduler.c Regards, Park Heesob -------------- next part -------------- /**************************************************************************** * taskscheduler.c - source for the win32-taskscheduler package * * Author: Daniel J. Berger ****************************************************************************/ #include "ruby.h" #include <windows.h> #include <initguid.h> #include <ole2.h> #include <mstask.h> #include <msterr.h> #include <objidl.h> #include <wchar.h> #include <stdio.h> #include "taskscheduler.h" static VALUE cTaskSchedulerError; static char error[ERROR_BUFFER]; static VALUE ts_allocate(VALUE klass){ TSStruct* ptr = (TSStruct*)malloc(sizeof(TSStruct)); return Data_Wrap_Struct(klass,0,ts_free,ptr); } static VALUE ts_init(VALUE self) { ITaskScheduler *pITS; HRESULT hr = S_OK; TSStruct* ptr; Data_Get_Struct(self,TSStruct,ptr); ptr->pITS = NULL; ptr->pITask = NULL; ///////////////////////////////////////////////////////////////// // Call CoInitialize to initialize the COM library and then // 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(); rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } ptr->pITS = pITS; ptr->pITask = NULL; return self; } static VALUE ts_enum(VALUE self) { TSStruct* ptr; HRESULT hr; IEnumWorkItems *pIEnum; LPWSTR *lpwszNames; VALUE rbEnum; char dest[NAME_MAX]; DWORD dwFetchedTasks = 0; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } ///////////////////////////////////////////////////////////////// // Call ITaskScheduler::Enum to get an enumeration object. ///////////////////////////////////////////////////////////////// hr = ptr->pITS->Enum(&pIEnum); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } rbEnum = rb_ary_new(); ///////////////////////////////////////////////////////////////// // Call IEnumWorkItems::Next to retrieve tasks. Note that // this example tries to retrieve five tasks for each call. ///////////////////////////////////////////////////////////////// while (SUCCEEDED(pIEnum->Next(TASKS_TO_RETRIEVE, &lpwszNames, &dwFetchedTasks)) && (dwFetchedTasks != 0)) { /////////////////////////////////////////////////////////////// // Process each task. Note that this example prints the // name of each task to the screen. ////////////////////////////////////////////////////////////// while (dwFetchedTasks) { WideCharToMultiByte( CP_ACP, 0, lpwszNames[--dwFetchedTasks], -1, dest, NAME_MAX, NULL, NULL ); rb_ary_push(rbEnum,rb_str_new2(dest)); CoTaskMemFree(lpwszNames[dwFetchedTasks]); } CoTaskMemFree(lpwszNames); } pIEnum->Release(); return rbEnum; } static VALUE ts_activate(VALUE self,VALUE job) { TSStruct* ptr; HRESULT hr; wchar_t cwszTaskName[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(job), RSTRING(job)->len+1, cwszTaskName, NAME_MAX ); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::Activate Task /////////////////////////////////////////////////////////////////// hr = ptr->pITS->Activate(cwszTaskName,IID_ITask, (IUnknown**) &(ptr->pITask)); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_delete(VALUE self,VALUE job) { TSStruct* ptr; HRESULT hr; wchar_t cwszTaskName[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(job), RSTRING(job)->len+1, cwszTaskName, NAME_MAX ); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::Delete /////////////////////////////////////////////////////////////////// hr = ptr->pITS->Delete(cwszTaskName); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_run(VALUE self) { TSStruct* ptr; HRESULT hr; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITask::Run to start execution of Task /////////////////////////////////////////////////////////////////// hr = ptr->pITask->Run(); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_save(VALUE self) { TSStruct* ptr; HRESULT hr; IPersistFile *pIPersistFile; LPOLESTR ppszFileName; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } ///////////////////////////////////////////////////////////////// // Call IUnknown::QueryInterface to get a pointer to // IPersistFile and IPersistFile::Save to save // the new task to disk. ///////////////////////////////////////////////////////////////// hr = ptr->pITask->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } /////////////////////////////////////////////////////////////////// // Call ITask::Save /////////////////////////////////////////////////////////////////// hr = pIPersistFile->Save(NULL,TRUE); if (FAILED(hr)) { strcpy(error,ErrorDescription(GetLastError())); pIPersistFile->Release(); rb_raise(cTaskSchedulerError,error); } pIPersistFile->Release(); ///////////////////////////////////////////////////////////////// // Call CoInitialize to initialize the COM library and then // CoCreateInstance to get the Task Scheduler object. // Added by phasis68 ///////////////////////////////////////////////////////////////// CoUninitialize(); hr = CoInitialize(NULL); if(SUCCEEDED(hr)){ hr = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &(ptr->pITS) ); if(FAILED(hr)){ CoUninitialize(); rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } ptr->pITask->Release(); return Qtrue; } static VALUE ts_terminate(VALUE self,VALUE job) { TSStruct* ptr; HRESULT hr; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITask::Terminate to terminate execution of Task /////////////////////////////////////////////////////////////////// hr = ptr->pITask->Terminate(); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_set_target_computer(VALUE self,VALUE host) { TSStruct* ptr; HRESULT hr; wchar_t cwszHostName[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(host), RSTRING(host)->len+1, cwszHostName, NAME_MAX ); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetTargetComputer /////////////////////////////////////////////////////////////////// hr = ptr->pITS->SetTargetComputer(cwszHostName); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_set_account_information(VALUE self,VALUE usr,VALUE pwd) { TSStruct* ptr; HRESULT hr; wchar_t cwszUsername[NAME_MAX]; wchar_t cwszPassword[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } if((usr==Qnil || RSTRING(usr)->len==0) && (pwd==Qnil || RSTRING(pwd)->len==0)){ /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetAccountInformation /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetAccountInformation(L"",NULL); } else{ MultiByteToWideChar(CP_ACP,0,StringValuePtr(usr), RSTRING(usr)->len+1,cwszUsername,NAME_MAX); MultiByteToWideChar(CP_ACP,0,StringValuePtr(pwd), RSTRING(pwd)->len+1,cwszPassword,NAME_MAX); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetAccountInformation /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetAccountInformation(cwszUsername,cwszPassword); } switch(hr) { case S_OK : return Qtrue; case E_ACCESSDENIED : return INT2NUM(0); case E_INVALIDARG : return INT2NUM(-1); case E_OUTOFMEMORY : return INT2NUM(-2); case SCHED_E_NO_SECURITY_SERVICES : return INT2NUM(-3); #ifdef SCHED_E_UNSUPPORTED_ACCOUNT_OPTION case SCHED_E_UNSUPPORTED_ACCOUNT_OPTION : return INT2NUM(-4); #endif #ifdef SCHED_E_ACCOUNT_INFORMATION_NOT_SET case SCHED_E_ACCOUNT_INFORMATION_NOT_SET : return INT2NUM(-5); #endif default : return INT2NUM(-6); } } static VALUE ts_get_account_information(VALUE self) { TSStruct* ptr; HRESULT hr; LPWSTR lpcwszUsername; char user[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"null pointer error (account_information"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetAccountInformation /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetAccountInformation(&lpcwszUsername); if(SUCCEEDED(hr) && hr != SCHED_E_NO_SECURITY_SERVICES){ WideCharToMultiByte( CP_ACP, 0, lpcwszUsername, -1, user, NAME_MAX, NULL, NULL ); CoTaskMemFree(lpcwszUsername); return rb_str_new2(user); } else{ strcpy(error,ErrorDescription(GetLastError())); CoTaskMemFree(lpcwszUsername); rb_raise(cTaskSchedulerError,error); } } static VALUE ts_set_application_name(VALUE self,VALUE app) { TSStruct* ptr; HRESULT hr; wchar_t cwszAppname[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar(CP_ACP,0,StringValuePtr(app),RSTRING(app)->len+1,cwszAppname,NAME_MAX); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetApplicationName /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetApplicationName(cwszAppname); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_application_name(VALUE self) { TSStruct* ptr; HRESULT hr; LPWSTR lpcwszAppname; char app[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetApplicationName /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetApplicationName(&lpcwszAppname); if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP, 0, lpcwszAppname, -1, app, NAME_MAX, NULL, NULL ); CoTaskMemFree(lpcwszAppname); return rb_str_new2(app); } else { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_set_parameters(VALUE self,VALUE param) { TSStruct* ptr; HRESULT hr; wchar_t cwszParameters[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar(CP_ACP,0,StringValuePtr(param), RSTRING(param)->len+1,cwszParameters,NAME_MAX); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetParameters /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetParameters(cwszParameters); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_parameters(VALUE self) { TSStruct* ptr; HRESULT hr; LPWSTR lpcwszParameters; char param[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetParameters /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetParameters(&lpcwszParameters); if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP, 0, lpcwszParameters, -1, param, NAME_MAX, NULL, NULL ); CoTaskMemFree(lpcwszParameters); return rb_str_new2(param); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_set_working_directory(VALUE self, VALUE direc) { TSStruct* ptr; HRESULT hr; wchar_t cwszDirectory[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(direc), RSTRING(direc)->len+1, cwszDirectory, NAME_MAX ); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetWorkingDirectory /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetWorkingDirectory(cwszDirectory); if(FAILED(hr)){ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_working_directory(VALUE self) { TSStruct* ptr; HRESULT hr; LPWSTR lpcwszDirectory; char dir[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetWorkingDirectory /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetWorkingDirectory(&lpcwszDirectory); if(SUCCEEDED(hr)){ WideCharToMultiByte( CP_ACP, 0, lpcwszDirectory, -1, dir, NAME_MAX, NULL, NULL ); CoTaskMemFree(lpcwszDirectory); return rb_str_new2(dir); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_set_priority(VALUE self,VALUE pri) { TSStruct* ptr; HRESULT hr; DWORD dwPriority; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } dwPriority = NUM2UINT(pri); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetPriority /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetPriority(dwPriority); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_priority(VALUE self) { TSStruct* ptr; HRESULT hr; DWORD dwPriority; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL){ rb_raise(cTaskSchedulerError,"null pointer error (priority)"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetPriority /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetPriority(&dwPriority); if(SUCCEEDED(hr)){ if(dwPriority & IDLE_PRIORITY_CLASS){ return rb_str_new2("idle"); } if(dwPriority & NORMAL_PRIORITY_CLASS){ return rb_str_new2("normal"); } if(dwPriority & HIGH_PRIORITY_CLASS){ return rb_str_new2("high"); } if(dwPriority & REALTIME_PRIORITY_CLASS){ return rb_str_new2("realtime"); } #ifdef BELOW_NORMAL_PRIORITY_CLASS if(dwPriority & BELOW_NORMAL_PRIORITY_CLASS){ return rb_str_new2("below_normal"); } #endif #ifdef ABOVE_NORMAL_PRIORITY_CLASS if(dwPriority & ABOVE_NORMAL_PRIORITY_CLASS){ return rb_str_new2("above_normal"); } #endif return rb_str_new2("unknown"); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_new_work_item(VALUE self,VALUE job,VALUE trigger) { TSStruct* ptr; HRESULT hr; wchar_t cwszTaskName[NAME_MAX]; ITaskTrigger *pITaskTrigger; WORD piNewTrigger; TASK_TRIGGER pTrigger; VALUE i, htmp; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL) { rb_raise(cTaskSchedulerError,"null pointer error (new_work_item)"); } if(ptr->pITask != NULL) { ptr->pITask->Release(); ptr->pITask = NULL; } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(job), RSTRING(job)->len+1, cwszTaskName, NAME_MAX ); ///////////////////////////////////////////////////////////////// // Call ITaskScheduler::NewWorkItem to create new task. ///////////////////////////////////////////////////////////////// hr = ptr->pITS->NewWorkItem( cwszTaskName, // Name of task CLSID_CTask, // Class identifier IID_ITask, // Interface identifier (IUnknown**)&(ptr->pITask) // Address of task interface ); if(FAILED(hr)){ ptr->pITask = NULL; // added by phasis68 for ts_free prevent rb_raise(cTaskSchedulerError,"NewWorkItem() function failed"); } if(TYPE(trigger)==T_HASH) { /////////////////////////////////////////////////////////////////// // Call ITask::CreateTrigger to create new trigger. /////////////////////////////////////////////////////////////////// hr = ptr->pITask->CreateTrigger(&piNewTrigger,&pITaskTrigger); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,"CreateTrigger() failed"); } ////////////////////////////////////////////////////// // Define TASK_TRIGGER structure. Note that wBeginDay, // wBeginMonth, and wBeginYear must be set to a valid // day, month, and year respectively. ////////////////////////////////////////////////////// ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); if((i=rb_hash_aref(trigger, rb_str_new2("start_year")))!=Qnil) pTrigger.wBeginYear = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_month")))!=Qnil) pTrigger.wBeginMonth = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_day")))!=Qnil) pTrigger.wBeginDay = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_year")))!=Qnil) pTrigger.wEndYear = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_month")))!=Qnil) pTrigger.wEndMonth = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_day")))!=Qnil) pTrigger.wEndDay = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_hour")))!=Qnil) pTrigger.wStartHour = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_minute")))!=Qnil) pTrigger.wStartMinute = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("minutes_duration")))!=Qnil) pTrigger.MinutesDuration = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("minutes_interval")))!=Qnil) pTrigger.MinutesInterval = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("random_minutes_interval")))!=Qnil) pTrigger.wRandomMinutesInterval = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("flags")))!=Qnil) pTrigger.rgFlags = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("trigger_type")))!=Qnil) pTrigger.TriggerType = (TASK_TRIGGER_TYPE)NUM2INT(i); htmp =rb_hash_aref(trigger, rb_str_new2("type")); if(TYPE(htmp)!=T_HASH) htmp = Qnil; switch(pTrigger.TriggerType) { case TASK_TIME_TRIGGER_DAILY: if(htmp!=Qnil){ if((i=rb_hash_aref(htmp, rb_str_new2("days_interval")))!=Qnil) pTrigger.Type.Daily.DaysInterval = NUM2INT(i); } break; case TASK_TIME_TRIGGER_WEEKLY: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("weeks_interval")))!=Qnil) pTrigger.Type.Weekly.WeeksInterval = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days_of_week")))!=Qnil) pTrigger.Type.Weekly.rgfDaysOfTheWeek = NUM2INT(i); } break; case TASK_TIME_TRIGGER_MONTHLYDATE: if(htmp!=Qnil){ if((i=rb_hash_aref(htmp, rb_str_new2("months")))!=Qnil) pTrigger.Type.MonthlyDate.rgfMonths = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days")))!=Qnil) pTrigger.Type.MonthlyDate.rgfDays = humanDaysToBitField(NUM2INT(i)); } break; case TASK_TIME_TRIGGER_MONTHLYDOW: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("weeks")))!=Qnil) pTrigger.Type.MonthlyDOW.wWhichWeek = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days_of_week")))!=Qnil) pTrigger.Type.MonthlyDOW.rgfDaysOfTheWeek = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("months")))!=Qnil) pTrigger.Type.MonthlyDOW.rgfMonths = NUM2INT(i); } break; } /////////////////////////////////////////////////////////////////// // Call ITaskTrigger::SetTrigger to set trigger criteria. /////////////////////////////////////////////////////////////////// hr = pITaskTrigger->SetTrigger (&pTrigger); if (FAILED(hr)) { //rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); rb_raise(cTaskSchedulerError,"SetTrigger() failed"); } pITaskTrigger->Release(); return Qtrue; } return Qtrue; } static VALUE ts_get_trigger_count(VALUE self) { TSStruct* ptr; HRESULT hr; WORD TriggerCount; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetTriggerCount /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetTriggerCount(&TriggerCount); if(SUCCEEDED(hr)) { return UINT2NUM(TriggerCount); } else { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_get_trigger_string(VALUE self,VALUE index) { TSStruct* ptr; HRESULT hr; WORD TriggerIndex; LPWSTR ppwszTrigger; char str[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } TriggerIndex = NUM2INT(index); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetTriggerString /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetTriggerString(TriggerIndex,&ppwszTrigger); if(SUCCEEDED(hr)){ WideCharToMultiByte(CP_ACP,0,ppwszTrigger,-1,str,NAME_MAX,NULL,NULL); CoTaskMemFree(ppwszTrigger); return rb_str_new2(str); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_delete_trigger(VALUE self,VALUE index) { TSStruct* ptr; HRESULT hr; WORD TriggerIndex; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } TriggerIndex = NUM2INT(index); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::DeleteTrigger /////////////////////////////////////////////////////////////////// hr = ptr->pITask->DeleteTrigger(TriggerIndex); if(FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_trigger(VALUE self,VALUE index) { TSStruct* ptr; HRESULT hr; WORD TriggerIndex; VALUE trigger,htmp; ITaskTrigger *pITaskTrigger; TASK_TRIGGER pTrigger; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } TriggerIndex = NUM2INT(index); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetTrigger /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetTrigger(TriggerIndex,&pITaskTrigger); if(FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } ZeroMemory(&pTrigger, sizeof(TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); hr = pITaskTrigger->GetTrigger(&pTrigger); if(FAILED(hr)) { strcpy(error,ErrorDescription(GetLastError())); pITaskTrigger->Release(); rb_raise(cTaskSchedulerError,error); } trigger = rb_hash_new(); rb_hash_aset(trigger, rb_str_new2("start_year"), INT2NUM(pTrigger.wBeginYear)); rb_hash_aset(trigger, rb_str_new2("start_month"), INT2NUM(pTrigger.wBeginMonth)); rb_hash_aset(trigger, rb_str_new2("start_day"), INT2NUM(pTrigger.wBeginDay)); rb_hash_aset(trigger, rb_str_new2("end_year"), INT2NUM(pTrigger.wEndYear)); rb_hash_aset(trigger, rb_str_new2("end_month"), INT2NUM(pTrigger.wEndMonth)); rb_hash_aset(trigger, rb_str_new2("end_day"), INT2NUM(pTrigger.wEndDay)); rb_hash_aset(trigger, rb_str_new2("start_hour"), INT2NUM(pTrigger.wStartHour)); rb_hash_aset(trigger, rb_str_new2("start_minute"), INT2NUM(pTrigger.wStartMinute)); rb_hash_aset(trigger, rb_str_new2("minutes_duration"), INT2NUM(pTrigger.MinutesDuration)); rb_hash_aset(trigger, rb_str_new2("minutes_interval"), INT2NUM(pTrigger.MinutesInterval)); rb_hash_aset(trigger, rb_str_new2("trigger_type"), INT2NUM(pTrigger.TriggerType)); rb_hash_aset(trigger, rb_str_new2("random_minutes_interval"), INT2NUM(pTrigger.wRandomMinutesInterval)); rb_hash_aset(trigger, rb_str_new2("flags"), INT2NUM(pTrigger.rgFlags)); switch(pTrigger.TriggerType) { case TASK_TIME_TRIGGER_DAILY : htmp=rb_hash_new(); rb_hash_aset(htmp, rb_str_new2("days_interval"), INT2NUM(pTrigger.Type.Daily.DaysInterval)); rb_hash_aset(trigger, rb_str_new2("type"), htmp); break; case TASK_TIME_TRIGGER_WEEKLY : htmp=rb_hash_new(); rb_hash_aset(htmp, rb_str_new2("weeks_interval"), INT2NUM(pTrigger.Type.Weekly.WeeksInterval)); rb_hash_aset(htmp, rb_str_new2("days_of_week"), INT2NUM(pTrigger.Type.Weekly.rgfDaysOfTheWeek)); rb_hash_aset(trigger, rb_str_new2("type"), htmp); break; case TASK_TIME_TRIGGER_MONTHLYDATE : htmp=rb_hash_new(); rb_hash_aset(htmp, rb_str_new2("days"), INT2NUM(bitFieldToHumanDays(pTrigger.Type.MonthlyDate.rgfDays))); rb_hash_aset(htmp, rb_str_new2("months"), INT2NUM(pTrigger.Type.MonthlyDate.rgfMonths)); rb_hash_aset(trigger, rb_str_new2("type"), htmp); break; case TASK_TIME_TRIGGER_MONTHLYDOW : htmp=rb_hash_new(); rb_hash_aset(htmp, rb_str_new2("weeks"), INT2NUM(bitFieldToHumanDays(pTrigger.Type.MonthlyDOW.wWhichWeek))); rb_hash_aset(htmp, rb_str_new2("days_of_week"), INT2NUM(pTrigger.Type.MonthlyDOW.rgfDaysOfTheWeek)); rb_hash_aset(htmp, rb_str_new2("months"), INT2NUM(pTrigger.Type.MonthlyDOW.rgfMonths)); rb_hash_aset(trigger, rb_str_new2("type"), htmp); break; } pITaskTrigger->Release(); return trigger; } static VALUE ts_set_trigger(VALUE self,VALUE index,VALUE trigger) { TSStruct* ptr; HRESULT hr; WORD TriggerIndex; ITaskTrigger *pITaskTrigger; TASK_TRIGGER pTrigger; VALUE i; VALUE htmp; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } TriggerIndex = NUM2INT(index); hr=ptr->pITask->GetTrigger(TriggerIndex,&pITaskTrigger); if(FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } ZeroMemory(&pTrigger, sizeof(TASK_TRIGGER)); if(TYPE(trigger)==T_HASH) { ////////////////////////////////////////////////////// // Define TASK_TRIGGER structure. Note that wBeginDay, // wBeginMonth, and wBeginYear must be set to a valid // day, month, and year respectively. ////////////////////////////////////////////////////// ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); if((i=rb_hash_aref(trigger, rb_str_new2("start_year")))!=Qnil) pTrigger.wBeginYear = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_month")))!=Qnil) pTrigger.wBeginMonth = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_day")))!=Qnil) pTrigger.wBeginDay = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_year")))!=Qnil) pTrigger.wEndYear = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_month")))!=Qnil) pTrigger.wEndMonth = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_day")))!=Qnil) pTrigger.wEndDay = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_hour")))!=Qnil) pTrigger.wStartHour = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_minute")))!=Qnil) pTrigger.wStartMinute = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("minutes_duration")))!=Qnil) pTrigger.MinutesDuration = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("minutes_interval")))!=Qnil) pTrigger.MinutesInterval = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("random_minutes_interval")))!=Qnil) pTrigger.wRandomMinutesInterval = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("flags")))!=Qnil) pTrigger.rgFlags = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("trigger_type")))!=Qnil) pTrigger.TriggerType = (TASK_TRIGGER_TYPE)NUM2INT(i); htmp =rb_hash_aref(trigger, rb_str_new2("type")); if(TYPE(htmp)!=T_HASH) htmp = Qnil; switch(pTrigger.TriggerType) { case TASK_TIME_TRIGGER_DAILY: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("days_interval")))!=Qnil) pTrigger.Type.Daily.DaysInterval = NUM2INT(i); } break; case TASK_TIME_TRIGGER_WEEKLY: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("weeks_interval")))!=Qnil) pTrigger.Type.Weekly.WeeksInterval = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days_of_week")))!=Qnil) pTrigger.Type.Weekly.rgfDaysOfTheWeek = NUM2INT(i); } break; case TASK_TIME_TRIGGER_MONTHLYDATE: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("months")))!=Qnil) pTrigger.Type.MonthlyDate.rgfMonths = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days")))!=Qnil) pTrigger.Type.MonthlyDate.rgfDays = humanDaysToBitField(NUM2INT(i)); } break; case TASK_TIME_TRIGGER_MONTHLYDOW: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("weeks")))!=Qnil) pTrigger.Type.MonthlyDOW.wWhichWeek = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days_of_week")))!=Qnil) pTrigger.Type.MonthlyDOW.rgfDaysOfTheWeek = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("months")))!=Qnil) pTrigger.Type.MonthlyDOW.rgfMonths = NUM2INT(i); } break; } /////////////////////////////////////////////////////////////////// // Call ITaskTrigger::SetTrigger to set trigger criteria. /////////////////////////////////////////////////////////////////// hr = pITaskTrigger->SetTrigger (&pTrigger); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } pITaskTrigger->Release(); return Qtrue; } return Qtrue; } static VALUE ts_create_trigger(VALUE self,VALUE trigger) { TSStruct* ptr; HRESULT hr; WORD TriggerIndex; ITaskTrigger *pITaskTrigger; TASK_TRIGGER pTrigger; VALUE i; VALUE htmp; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } hr=ptr->pITask->CreateTrigger(&TriggerIndex,&pITaskTrigger); if(FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } ZeroMemory(&pTrigger, sizeof(TASK_TRIGGER)); if(TYPE(trigger)==T_HASH) { ////////////////////////////////////////////////////// // Define TASK_TRIGGER structure. Note that wBeginDay, // wBeginMonth, and wBeginYear must be set to a valid // day, month, and year respectively. ////////////////////////////////////////////////////// ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); if((i=rb_hash_aref(trigger, rb_str_new2("start_year")))!=Qnil) pTrigger.wBeginYear = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_month")))!=Qnil) pTrigger.wBeginMonth = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_day")))!=Qnil) pTrigger.wBeginDay = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_year")))!=Qnil) pTrigger.wEndYear = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_month")))!=Qnil) pTrigger.wEndMonth = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("end_day")))!=Qnil) pTrigger.wEndDay = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_hour")))!=Qnil) pTrigger.wStartHour = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("start_minute")))!=Qnil) pTrigger.wStartMinute = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("minutes_duration")))!=Qnil) pTrigger.MinutesDuration = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("minutes_interval")))!=Qnil) pTrigger.MinutesInterval = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("random_minutes_interval")))!=Qnil) pTrigger.wRandomMinutesInterval = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("flags")))!=Qnil) pTrigger.rgFlags = NUM2INT(i); if((i=rb_hash_aref(trigger, rb_str_new2("trigger_type")))!=Qnil) pTrigger.TriggerType = (TASK_TRIGGER_TYPE)NUM2INT(i); htmp =rb_hash_aref(trigger, rb_str_new2("type")); if(TYPE(htmp)!=T_HASH) htmp = Qnil; switch(pTrigger.TriggerType) { case TASK_TIME_TRIGGER_DAILY: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("days_interval")))!=Qnil) pTrigger.Type.Daily.DaysInterval = NUM2INT(i); } break; case TASK_TIME_TRIGGER_WEEKLY: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("weeks_interval")))!=Qnil) pTrigger.Type.Weekly.WeeksInterval = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days_of_week")))!=Qnil) pTrigger.Type.Weekly.rgfDaysOfTheWeek = NUM2INT(i); } break; case TASK_TIME_TRIGGER_MONTHLYDATE: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("months")))!=Qnil) pTrigger.Type.MonthlyDate.rgfMonths = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days")))!=Qnil) pTrigger.Type.MonthlyDate.rgfDays = humanDaysToBitField(NUM2INT(i)); } break; case TASK_TIME_TRIGGER_MONTHLYDOW: if(htmp!=Qnil) { if((i=rb_hash_aref(htmp, rb_str_new2("weeks")))!=Qnil) pTrigger.Type.MonthlyDOW.wWhichWeek = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("days_of_week")))!=Qnil) pTrigger.Type.MonthlyDOW.rgfDaysOfTheWeek = NUM2INT(i); if((i=rb_hash_aref(htmp, rb_str_new2("months")))!=Qnil) pTrigger.Type.MonthlyDOW.rgfMonths = NUM2INT(i); } break; } /////////////////////////////////////////////////////////////////// // Call ITaskTrigger::SetTrigger to set trigger criteria. /////////////////////////////////////////////////////////////////// hr = pITaskTrigger->SetTrigger (&pTrigger); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } pITaskTrigger->Release(); return Qtrue; } return Qtrue; } static VALUE ts_set_flags(VALUE self,VALUE flags) { TSStruct* ptr; HRESULT hr; DWORD dwFlags; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } dwFlags = NUM2UINT(flags); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetFlags /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetFlags(dwFlags); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_flags(VALUE self) { TSStruct* ptr; HRESULT hr; DWORD dwFlags; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetFlags /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetFlags(&dwFlags); if(SUCCEEDED(hr)) { return UINT2NUM(dwFlags); } else { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_get_status(VALUE self) { TSStruct* ptr; HRESULT hr; HRESULT st; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetStatus /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetStatus(&st); if(SUCCEEDED(hr)){ switch((DWORD)st){ case SCHED_S_TASK_READY: return rb_str_new2("ready"); case SCHED_S_TASK_RUNNING: return rb_str_new2("running"); case SCHED_S_TASK_NOT_SCHEDULED: return rb_str_new2("not scheduled"); default: return rb_str_new2("unknown"); }; } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_get_exit_code(VALUE self) { TSStruct* ptr; HRESULT hr; DWORD dwCode; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetExitCode /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetExitCode(&dwCode); if(SUCCEEDED(hr)){ return UINT2NUM(dwCode); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_set_comment(VALUE self,VALUE com) { TSStruct* ptr; HRESULT hr; wchar_t cwszComment[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(com), RSTRING(com)->len+1, cwszComment, NAME_MAX ); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetComment /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetComment(cwszComment); if(FAILED(hr)){ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_comment(VALUE self) { TSStruct* ptr; HRESULT hr; LPWSTR lpcwszComment; char com[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetComment /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetComment(&lpcwszComment); if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP, 0, lpcwszComment, -1, com, NAME_MAX, NULL, NULL ); CoTaskMemFree(lpcwszComment); return rb_str_new2(com); } else { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_set_creator(VALUE self,VALUE crt){ TSStruct* ptr; HRESULT hr; wchar_t cwszCreator[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } MultiByteToWideChar( CP_ACP, 0, StringValuePtr(crt), RSTRING(crt)->len+1, cwszCreator, NAME_MAX ); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetCreator /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetCreator(cwszCreator); if (FAILED(hr)){ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_creator(VALUE self){ TSStruct* ptr; HRESULT hr; LPWSTR lpcwszCreator; char crt[NAME_MAX]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetCreator /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetCreator(&lpcwszCreator); if(SUCCEEDED(hr)){ WideCharToMultiByte(CP_ACP,0,lpcwszCreator,-1,crt, NAME_MAX, NULL, NULL); CoTaskMemFree(lpcwszCreator); return rb_str_new2(crt); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_get_next_run_time(VALUE self) { TSStruct* ptr; HRESULT hr; SYSTEMTIME nextRun; VALUE argv[7]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"null pointer error (next_run_time)"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetNextRunTime /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetNextRunTime(&nextRun); if(SUCCEEDED(hr)){ argv[0] = INT2NUM(nextRun.wYear); argv[1] = INT2NUM(nextRun.wMonth); argv[2] = INT2NUM(nextRun.wDay); argv[3] = INT2NUM(nextRun.wHour); argv[4] = INT2NUM(nextRun.wMinute); argv[5] = INT2NUM(nextRun.wSecond); argv[6] = INT2NUM(nextRun.wMilliseconds*1000); return rb_funcall2(rb_cTime, rb_intern("local"), 7, argv); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_get_most_recent_run_time(VALUE self) { TSStruct* ptr; HRESULT hr; SYSTEMTIME lastRun; VALUE argv[7]; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetMostRecentRunTime /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetMostRecentRunTime(&lastRun); if(SCHED_S_TASK_HAS_NOT_RUN == hr){ return Qnil; } if(SUCCEEDED(hr)){ argv[0] = INT2NUM(lastRun.wYear); argv[1] = INT2NUM(lastRun.wMonth); argv[2] = INT2NUM(lastRun.wDay); argv[3] = INT2NUM(lastRun.wHour); argv[4] = INT2NUM(lastRun.wMinute); argv[5] = INT2NUM(lastRun.wSecond); argv[6] = INT2NUM(lastRun.wMilliseconds*1000); return rb_funcall2(rb_cTime, rb_intern("local"), 7, argv); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } static VALUE ts_set_max_run_time(VALUE self,VALUE maxruntime) { TSStruct* ptr; HRESULT hr; DWORD maxRunTimeMilliSeconds; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"fatal error: null pointer"); } maxRunTimeMilliSeconds = NUM2UINT(maxruntime); /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::SetMaxRunTime /////////////////////////////////////////////////////////////////// hr = ptr->pITask->SetMaxRunTime(maxRunTimeMilliSeconds); if (FAILED(hr)) { rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } return Qtrue; } static VALUE ts_get_max_run_time(VALUE self) { TSStruct* ptr; HRESULT hr; DWORD maxRunTimeMilliSeconds; Data_Get_Struct(self,TSStruct,ptr); if(ptr->pITS==NULL || ptr->pITask==NULL) { rb_raise(cTaskSchedulerError,"null pointer error (max_run_time)"); } /////////////////////////////////////////////////////////////////// // Call ITaskScheduler::GetMaxRunTime /////////////////////////////////////////////////////////////////// hr = ptr->pITask->GetMaxRunTime(&maxRunTimeMilliSeconds); if(SUCCEEDED(hr)){ return UINT2NUM(maxRunTimeMilliSeconds); } else{ rb_raise(cTaskSchedulerError,ErrorDescription(GetLastError())); } } // The C++ code requires explicit function casting via ''VALUEFUNC'' void Init_taskscheduler() { VALUE mWin32, cTaskScheduler;; // Modules and classes mWin32 = rb_define_module("Win32"); cTaskScheduler = rb_define_class_under(mWin32, "TaskScheduler", rb_cObject); cTaskSchedulerError = rb_define_class_under(mWin32,"TaskSchedulerError", rb_eStandardError); // Taskscheduler class and instance methods rb_define_alloc_func(cTaskScheduler,ts_allocate); rb_define_method(cTaskScheduler,"initialize",VALUEFUNC(ts_init),0); rb_define_method(cTaskScheduler,"enum",VALUEFUNC(ts_enum),0); rb_define_method(cTaskScheduler,"activate",VALUEFUNC(ts_activate),1); rb_define_method(cTaskScheduler,"delete",VALUEFUNC(ts_delete),1); rb_define_method(cTaskScheduler,"run",VALUEFUNC(ts_run),0); rb_define_method(cTaskScheduler,"save",VALUEFUNC(ts_save),0); rb_define_method(cTaskScheduler,"terminate",VALUEFUNC(ts_terminate),0); rb_define_method(cTaskScheduler,"machine=", VALUEFUNC(ts_set_target_computer),1); rb_define_method(cTaskScheduler,"set_account_information", VALUEFUNC(ts_set_account_information),2); rb_define_method(cTaskScheduler,"account_information", VALUEFUNC(ts_get_account_information),0); rb_define_method(cTaskScheduler,"application_name", VALUEFUNC(ts_get_application_name),0); rb_define_method(cTaskScheduler,"application_name=", VALUEFUNC(ts_set_application_name),1); rb_define_method(cTaskScheduler,"parameters", VALUEFUNC(ts_get_parameters),0); rb_define_method(cTaskScheduler,"parameters=", VALUEFUNC(ts_set_parameters),1); rb_define_method(cTaskScheduler,"working_directory", VALUEFUNC(ts_get_working_directory),0); rb_define_method(cTaskScheduler,"working_directory=", VALUEFUNC(ts_set_working_directory),1); rb_define_method(cTaskScheduler,"priority", VALUEFUNC(ts_get_priority),0); rb_define_method(cTaskScheduler,"priority=", VALUEFUNC(ts_set_priority),1); rb_define_method(cTaskScheduler,"new_work_item", VALUEFUNC(ts_new_work_item),2); // Trigger related methods rb_define_method(cTaskScheduler,"trigger_count", VALUEFUNC(ts_get_trigger_count),0); rb_define_method(cTaskScheduler,"trigger_string", VALUEFUNC(ts_get_trigger_string),1); rb_define_method(cTaskScheduler,"delete_trigger", VALUEFUNC(ts_delete_trigger),1); rb_define_method(cTaskScheduler,"trigger", VALUEFUNC(ts_get_trigger),1); rb_define_method(cTaskScheduler,"trigger=", VALUEFUNC(ts_create_trigger),1); rb_define_method(cTaskScheduler,"create_trigger", VALUEFUNC(ts_create_trigger),1); rb_define_method(cTaskScheduler,"flags", VALUEFUNC(ts_get_flags),0); rb_define_method(cTaskScheduler,"flags=", VALUEFUNC(ts_set_flags),1); rb_define_method(cTaskScheduler,"status", VALUEFUNC(ts_get_status),0); rb_define_method(cTaskScheduler,"exit_code", VALUEFUNC(ts_get_exit_code),0); rb_define_method(cTaskScheduler,"comment", VALUEFUNC(ts_get_comment),0); rb_define_method(cTaskScheduler,"comment=", VALUEFUNC(ts_set_comment),1); rb_define_method(cTaskScheduler,"creator", VALUEFUNC(ts_get_creator),0); rb_define_method(cTaskScheduler,"creator=", VALUEFUNC(ts_set_creator),1); rb_define_method(cTaskScheduler,"next_run_time", VALUEFUNC(ts_get_next_run_time),0); rb_define_method(cTaskScheduler,"most_recent_run_time", VALUEFUNC(ts_get_most_recent_run_time),0); rb_define_method(cTaskScheduler,"max_run_time", VALUEFUNC(ts_get_max_run_time),0); rb_define_method(cTaskScheduler,"max_run_time=", VALUEFUNC(ts_set_max_run_time),1); // Constants rb_define_const(cTaskScheduler,"VERSION", rb_str_new2(WIN32_TASKSCHEDULER_VERSION)); set_constants(cTaskScheduler); }
win32utils-devel@rubyforge.org
2004-Aug-01 12:18 UTC
[Win32utils-devel] Re: Bug in new_work_item
Park, I tried your patch, but it now segfaults when I call TaskScheduler#save: # test.rb require "win32/taskscheduler" include Win32 p TaskScheduler::VERSION trigger = { "start_year" => 2009, "start_month" => 4, "start_day" => 11, "start_hour" => 7, "start_minute" => 14, "trigger_type" => TaskScheduler::DAILY, "type" => { "days_interval" => 1 } } ts = TaskScheduler.new ts.new_work_item("foo",trigger) ts.application_name = "notepad.exe" ts.save # Output C:\eclipse\workspace\win32-taskscheduler>ruby test.rb "0.1.0" test.rb:24: [BUG] Segmentation fault ruby 1.8.2 (2004-07-29) [i386-mswin32] abnormal program termination Where line 24 is "ts.save". Any ideas? Dan __________________________________ Do you Yahoo!? New and Improved Yahoo! Mail - Send 10MB messages! http://promotions.yahoo.com/new_mail
win32utils-devel@rubyforge.org
2004-Aug-02 09:12 UTC
[Win32utils-devel] Re: Bug in new_work_item
> Park, > > I tried your patch, but it now segfaults when I call > TaskScheduler#save: >...> > abnormal program termination > > Where line 24 is "ts.save". Any ideas? > > Dan >Hi, The bug was fixed in the latest CVS. Regards, Park Heesob