3
votes

I have a peculiar problem with the Task Scheduler interfaces and I would be very happy if someone could help.

A part of my application reads the items from the Task Scheduler. Under XP I use the Task Scheduler v1.0 interfaces from a unit from JEDI Library. Under Vista and Win7 I used the TaskSchd.pas unit found in this article. It contains the definitions for the new 2.0 interfaces. I use Delphi XE2, Update 4.

The problem is that I get an Access Violation when I call the Connect method of the ITaskService interface. The error message is "First chance exception at $0055C73C. Exception class $C0000005 with message 'access violation at 0x0055c73c: read of address 0x0000000b'."

The code I use is:

procedure TSomeClass.TaskScheduler(...);
var
  TS : ITaskService;
  TaskFolder : ITaskFolder;
begin
  TS := CoTaskScheduler.Create();
  TS.Connect('', '', '', '');
  ......
end;

The code is in a separate unit in a class descendant from TObject. This is enough to cause AV, even without doing anything else with the interface. The AV happens when the function exits though, not at the Connect line, so it might be related to the releasing of the object.

I have ran some tests, but could not find where the problem is. Here is what is strange:

  • The AV happens only in Release builds, in Debug it works properly
  • If I turn off Optimization in Project Options > Compiling then again the code works. If I turn it on in Debug build, the code stops working.
  • If I place this in some method in the main form, it works again.
  • I have called CoInitialize, but it does not have any effect
  • I tried to duplicate it in a blank new app, but I could not, so it is somehow related to another unit or class in the application

It is probably something very simple that I am missing about interfaces, but I have not been able to find it. The code otherwise works, I can get and display the list of tasks. The problem comes when the Compiling > Optimizations option is turned on, which is the default for the Release build.

One solution would be to just turn off the Optimizations, but I would rather find the cause of the problem.

Edit: I have included additional info about the AV, CoInitialize, Delphi and the ITaskService header file.

3
When you say "I get an access violation" and provide no information about the access violation, you might as well say "It doesn't work", because they mean the same thing. When you type "an error" or "exception", the very next thing you should do is provide the exact error message, including any error codes or memory addresses. - Ken White
Have you tried using EmptyParam instead of blank strings? The parameters of ITaskService.Connect() are variant values, not strings. - Remy Lebeau
Hack the program around until you find which other piece of code is implicated - David Heffernan
Sorry for omitting some information in the rush. I added the AV info and Delphi (it is XE2) version in the main post. I have tried with and without CoInitialize, also with EmptyParam but it makes no difference. - VGeorgiev
Which update of XE2. They fixed a nasty COM bug in update 2: stackoverflow.com/questions/7886116/… but that's probably a long shot - David Heffernan

3 Answers

1
votes

I think the linked Taskschd.pas has a lot of bugs.

For example, ITaskFolder::CreateFolder has only two parameters, but in the Windows Task Scheduler 2.0 API there are tree parameters.

Back to your question about "Connect". I'm using the following code:

var
  TaskService: ITaskService;
begin
  if (Succeeded(CoInitialize(nil))) then
  begin
    if (Failed(CoCreateInstance(CLSID_TaskScheduler, nil, CLSCTX_INPROC_SERVER, IID_ITaskService, TaskService))
      or (Failed(TaskService.Connect(Null, Null, Null, Null)))) then
    begin
      CoUninitialize();
      TaskService := nil;
    end;
  end;
...
0
votes

i also have this problem. reason - wrong header TaskSchd.pas use following: https://searchcode.com/codesearch/view/27081108/

-1
votes

Just make this after all:

ts:= nil;