3

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.

Community
  • 1
  • 1
VGeorgiev
  • 491
  • 5
  • 16
  • 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 Sep 11 '12 at 19:58
  • Have you tried using `EmptyParam` instead of blank strings? The parameters of `ITaskService.Connect()` are variant values, not strings. – Remy Lebeau Sep 12 '12 at 00:17
  • Hack the program around until you find which other piece of code is implicated – David Heffernan Sep 12 '12 at 06:31
  • 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 Sep 12 '12 at 06:31
  • Which update of XE2. They fixed a nasty COM bug in update 2: http://stackoverflow.com/questions/7886116/is-com-broken-in-xe2-and-how-might-i-work-around-it but that's probably a long shot – David Heffernan Sep 12 '12 at 08:04
  • Update 4, so it's not that one unfortunately. I have been hacking :) the program and commenting/uncommenting, but without a specific result. I only found that if I declare the variable and call Connect in any unit or class, the error appears. The only thing that works is if I place the code in the main form class. – VGeorgiev Sep 12 '12 at 08:55
  • "The AV happens when the function exits though, not at the Connect line, so it might be related to the releasing of the object." Then pastebin the full function code. What is the parameter list ? And try to trace it step be step in View/Debug/CPU Window. At least you would see if exception is raised in the function of after its exit in calling code. Try to add *TS:=nil;TaskFodler:=nil;* before the function end - would then they cause an AV ? – Arioch 'The Sep 12 '12 at 12:43
  • There is no function code and no parameters. I have commented everything and the problem persists. What I have pasted above is enough to cause it. I moved the code in different units and functions and the result is always the same. – VGeorgiev Sep 16 '12 at 17:37
  • Well, it is not really an answer, but I gave up on this and solved the problem by just turning off optimizations for that function with {O-} directives. I'll search for the cause when I have more time available. – VGeorgiev Sep 16 '12 at 17:40

3 Answers3

1

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;
...
Tahtu
  • 11
  • 2
0

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

K10
  • 1
  • Please do explain your answer. – αƞjiβ Oct 16 '15 at 20:50
  • Thanks for the suggestion. That project I was working on got completed long time ago and is not in development any more. I can't test this unit now, but I will keep it in mind if I need to use the Task Scheduler again. – VGeorgiev Oct 17 '15 at 06:10
  • αƞjiβ, just dont use header TaskSchd.pas, specified in question. It have some errors. Use TaskSchd.pas from https://searchcode.com/codesearch/view/27081108/ – K10 Oct 18 '15 at 12:14
-1

Just make this after all:

ts:= nil;
vasya
  • 1