Thread: Scheduling tasks in Windows

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    1

    Lightbulb Scheduling tasks in Windows

    I have a script that I wrote in Linux that will read a line from a txt file containing email addresses, and send an email (the body comes from another txt file) to each address on the line that was read. I set up a cron-job so that the script runs on a weekly basis. I have since had numerous requests for the program, but the hitch is that it needs to run on Windows.

    I want to write this thing in C, and I am looking for a way to have the program itself set up a schedule and run automatically - this way I can hand the executable to someone (most of the people that are interested in this do not know much at all about using a computer) and they can run it. I will basically have the program be a wizzard that asks questions, and based on the answers set up a scheduled task(s) for Windows to run. Where should I start looking for functions that will let me do that? Thanks.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Settings->Control Panel->Scheduled Tasks
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Out of interest, aren't there any API calls to do this?
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  4. #4
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Quote Originally Posted by ahluka
    Out of interest, aren't there any API calls to do this?
    There's a WMI object that can do it

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Or even the 'at' command at the command line prompt
    say
    at /?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You can also use the Task Scheduler API. Here is a sample.
    Code:
    #include <windows.h>
    #include <initguid.h>
    #include <objbase.h>
    #include <mstask.h>
    #include <stdio.h>
    
    #if defined(_MSC_VER)
    #   pragma comment(lib, "ole32.lib")
    #   pragma comment(lib, "advapi32.lib")
    #endif
    
    int main(void)
    {
      HRESULT         hr            = 0;
      ITaskScheduler* pITS          = NULL;
      ITask*          pITask        = NULL;
      IPersistFile*   pIPersistFile = NULL;
      ITaskTrigger*   pITaskTrigger = NULL;
      TASK_TRIGGER    trigger       = { 0 };
      WORD            newTrigger    = 0;
      BOOL            fSuccess      = FALSE;
      SYSTEMTIME      st            = { 0 };
      WCHAR           szUser[500];
      DWORD           cchUser       = 500;
    
      CoInitialize(NULL);
    
      /* Create the task scheduler object. */
      hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER,
                            IID_ITaskScheduler, (void **) &pITS);
      if (FAILED(hr)) goto cleanup;
     
      /* Create a new work item. */  
      hr = pITS->NewWorkItem(L"Your Task Name",        // Name of task
                             CLSID_CTask,              // Class identifier 
                             IID_ITask,                // Interface identifier
                             (IUnknown**) &pITask);    // Address of task interface
      if (FAILED(hr)) goto cleanup;
    
      /* Set the application to run (usually should include a path). */
      hr = pITask->SetApplicationName(L"notepad.exe");
      if (FAILED(hr)) goto cleanup;
    
      /* Only run if the current account is logged on. */
      hr = pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
      if (FAILED(hr)) goto cleanup;
    
      /* Set the user account to use. */
      GetUserNameW(szUser, &cchUser);
      hr = pITask->SetAccountInformation(szUser, NULL);
      if (FAILED(hr)) goto cleanup;
    
      /* Create trigger (schedule when the task should be triggered). */
      hr = pITask->CreateTrigger(&newTrigger, &pITaskTrigger);
      if (FAILED(hr)) goto cleanup;
      
      /* Define TASK_TRIGGER structure. Note that wBeginDay,
       * wBeginMonth, and wBeginYear must be set to a valid 
       * day, month, and year respectively. */
      GetSystemTime(&st);
    
      trigger.cbTriggerSize = sizeof (TASK_TRIGGER); 
      trigger.wBeginDay     = st.wDay;          // Start day
      trigger.wBeginMonth   = st.wMonth;        // Start month
      trigger.wBeginYear    = st.wYear;         // Start year
      trigger.wStartHour    = 13;               // 1:00 pm
      trigger.TriggerType   = TASK_TIME_TRIGGER_DAILY;
      trigger.Type.Daily.DaysInterval = 7;      // Days between running
      
      hr = pITaskTrigger->SetTrigger(&trigger);
      if (FAILED(hr)) goto cleanup;
    
      /* Call IUnknown::QueryInterface to get a pointer to 
       * IPersistFile and IPersistFile::Save to save 
       * the new task to disk. */
      hr = pITask->QueryInterface(IID_IPersistFile, (void **) &pIPersistFile);
      if (FAILED(hr)) goto cleanup;
    
      hr = pIPersistFile->Save(NULL, TRUE);
      if (FAILED(hr)) goto cleanup;
    
      fSuccess = TRUE;
    
    cleanup:
      if (pITask)        pITask->Release();
      if (pIPersistFile) pIPersistFile->Release();
      if (pITaskTrigger) pITaskTrigger->Release();
      if (pITS)          pITS->Release();
    
      if (!fSuccess) fprintf(stderr, "Failed with error code %08x.\n", hr);
    
      CoUninitialize();
      return 0;
    }

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    2
    I tried this code.
    It does not not work for me.
    The call of "pITaskTrigger->SetTrigger (&pTrigger)" returns the error 'E_INVALIDARG'

    Any ideas ?

    I'm using Windows 2003 server, Visual C++ 6

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    OK, I split your bump here - http://cboard.cprogramming.com/showthread.php?t=97144
    and you still found your way back.
    Paying attention isn't your strong point is it?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Anyone using Windows 7?
    By Sharke in forum General Discussions
    Replies: 60
    Last Post: 07-12-2009, 08:05 AM
  2. Just starting Windows Programming, School me!
    By Shamino in forum Windows Programming
    Replies: 17
    Last Post: 02-22-2008, 08:14 AM
  3. Dialog Box Problems
    By Morgul in forum Windows Programming
    Replies: 21
    Last Post: 05-31-2005, 05:48 PM
  4. dual boot Win XP, win 2000
    By Micko in forum Tech Board
    Replies: 6
    Last Post: 05-30-2005, 02:55 PM
  5. SDL and Windows
    By nickname_changed in forum Windows Programming
    Replies: 14
    Last Post: 10-24-2003, 12:19 AM