Why NetScheduleJobAdd and NetScheduleJobEnum Lib "netapi32.dll" will use "SYSTEM" and not a User account

I'm desperatly trying to enumerate sceduled tasks/jobs on a local computer.
But all aproaches i've tried will end up in only creating and enumerating jobs by an owner called "SYSTEM".
I cann't get them to use the User account as the shortcut "Add Job" in Windows\Tasks will.
The enumeration will only return jobs sceduled by "SYSTEM" and not by other user accounts.
I've tried different programming languages (Delphi, VB 6.0), searched at Microsoft.com, and questioned a lot of search engines.
I'v defined prototypes of NetScheduleJobEnum and NetScheduleJobAdd API using "netapi32.dll" running under Windows2000 or XP
This issue was already on ExpertsExchange, but no explanation nor solution is provided yet...
Please help...
HebelsAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
moduloConnect With a Mentor Commented:
PAQed with points refunded (500)

modulo
Community Support Moderator
0
 
jkrCommented:
'NetScheduleJobAdd ()' does not take any information about users or accounts. If you want to do that, you'll have to use COM interfaces. See e.g. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/taskschd/taskschd/c_c_code_example_setting_task_account_information.asp ("C/C++ Code Example: Setting Task Account Information"):

#include <windows.h>
#include <initguid.h>
#include <ole2.h>
#include <mstask.h>
#include <msterr.h>
#include <wchar.h>


int main(int argc, char **argv)
{
  HRESULT hr = S_OK;
 
  ///////////////////////////////////////////////////////////////////
  // Call CoInitialize to initialize the COM library and then
  // CoCreateInstance to get the Task Scheduler object.
  ///////////////////////////////////////////////////////////////////
  ITaskScheduler *pITS;
 
  hr = CoInitialize(NULL);
  if (SUCCEEDED(hr))
  {
    hr = CoCreateInstance(CLSID_CTaskScheduler,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ITaskScheduler,
                          (void **) &pITS);
    if (FAILED(hr))
    {
      CoUninitialize();
      return 1;
    }
  }
  else
  {
    return 1;
  }
 
 
  ///////////////////////////////////////////////////////////////////
  // Call ITaskScheduler::Activate to get the Task object.
  ///////////////////////////////////////////////////////////////////
 
  ITask *pITask;
  LPCWSTR lpcwszTaskName;
  lpcwszTaskName = L"Test Task";
  hr = pITS->Activate(lpcwszTaskName,
                      IID_ITask,
                      (IUnknown**) &pITask);
 
  // Release the ITaskScheduler interface.
  pITS->Release();  
 
  if (FAILED(hr))
  {
    wprintf(L"Failed calling ITaskScheduler::Activate: ");
    wprintf(L"error = 0x%x\n",hr);
    CoUninitialize();
    return 1;
  }
 
 
  ///////////////////////////////////////////////////////////////////
  // Call ITask::SetAccountInformation to specify the account name
  // and the account password for Test Task.
  ///////////////////////////////////////////////////////////////////
  LPCWSTR pwszAccountName = L"myAccount";
  LPCWSTR pwszPassword = L"myPassword";
  hr = pITask->SetAccountInformation(pwszAccountName,
                                     pwszPassword);
 
  if (FAILED(hr))
  {
    wprintf(L"Failed calling ITask::SetAccountInformation: ");
    wprintf(L"error = 0x%x\n",hr);
    CoUninitialize();
    return 1;
  }
 
 
  ///////////////////////////////////////////////////////////////////
  // Call IPersistFile::Save to save the modified task to disk.
  ///////////////////////////////////////////////////////////////////
  IPersistFile *pIPersistFile;
 
  hr = pITask->QueryInterface(IID_IPersistFile,
                              (void **)&pIPersistFile);
 
  // Release the ITask interface.
  pITask->Release();  
 
  hr = pIPersistFile->Save(NULL,
                           TRUE);
 
  // Release the IPersistFile interface.
  pIPersistFile->Release();
 
  wprintf(L"Set the account name to %s and ", pwszAccountName);
  wprintf(L"and the account password to %s.\n", pwszPassword);  
  CoUninitialize();
  return 0;
}
0
 
HebelsAuthor Commented:
Thanks jkr,
for your quick responce.
I've tried your approach, but it will not modify the creator as listed in <Explorer> C:\Windows\Tasks\ column "Creator" it will modify the user account under wich the task will be executed as listed under Properties when doubleclicking a scheduled Task instead!
Now my Problem was that i couldn't enumerate all Tasks listed by the Windows explorer in the folder Windows\Tasks\ .
I'm interested in enumeration of all tasks or only those tasks that were created by "User"
I can only enumerate tasks that are created using the API NetScheduleJobAdd. Those tasks show a creator named "SYSTEM" and not the name of the logged in user
I suspect that's the reason why i can not, but how can i enumerate tasks that are created under the normal user account?
Please advise...
0
Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

 
HebelsAuthor Commented:
While still looking for an answer i found that the following code will list all tasks of all users including "SYSTEM".
Now i'm not very familiar with C++ and from all languages i know this would be the last choise!
Can anyone help me do something like this in Delphi or VisualBasic?
Please advise how to implement this object class "CTaskScheduler" in another language than C++...

Working code fragment as console application:

// Schedule_Console.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <objbase.h>
#include <windows.h>
#include <initguid.h>

#include <ole2.h>
#include <mstask.h>
#include <msterr.h>
#include <wchar.h>


#define TASKS_TO_RETRIEVE          5


int main(int argc, char **argv)
{
      printf("Hallo Welt!\n");

  HRESULT hr = S_OK;
  ITaskScheduler *pITS;
 
 
  /////////////////////////////////////////////////////////////////
  // 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();
      return hr;
    }
  }
  else
  {
    return hr;
  }
 
  /////////////////////////////////////////////////////////////////
  // Call ITaskScheduler::Enum to get an enumeration object.
  /////////////////////////////////////////////////////////////////
  IEnumWorkItems *pIEnum;
  hr = pITS->Enum(&pIEnum);
  pITS->Release();
  if (FAILED(hr))
  {
    CoUninitialize();
    return hr;
  }
 
  /////////////////////////////////////////////////////////////////
  // Call IEnumWorkItems::Next to retrieve tasks. Note that
  // this example tries to retrieve five tasks for each call.
  /////////////////////////////////////////////////////////////////
  LPWSTR *lpwszNames;
  DWORD dwFetchedTasks = 0;
  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)
    {
       wprintf(L"%s\n", lpwszNames[--dwFetchedTasks]);
       CoTaskMemFree(lpwszNames[dwFetchedTasks]);
    }
    CoTaskMemFree(lpwszNames);
  }
 
  pIEnum->Release();
  CoUninitialize();
  return S_OK;
}
0
 
HebelsAuthor Commented:
I've found a solution myself at http://www.delphi-jedi.org/APILIBRARY#windows "Taskscheduler.ZIP" by Marcel van Brakel.
so it will close this question...
0
 
jkrCommented:
Just happened to come across http://msdn.microsoft.com/library/en-us/taskschd/taskschd/ischeduledworkitem_setcreator.asp ("IScheduledWorkItem::SetCreator") - maybe that's what you're looking for.
0
All Courses

From novice to tech pro — start learning today.