Author Topic: [SOLVED] Lazarus and MSWord Automation on Win 11  (Read 8681 times)

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
[SOLVED] Lazarus and MSWord Automation on Win 11
« on: December 19, 2024, 08:22:42 am »
The error reported below only occurs on a Windows 11 x86_64 system.

The code has has been tested on the following systems:
Windows 7 x86 and x86-64
Windows 10 x86 and x86-64
Windows 11 x86-64

MSWord version 2007 (I know it's old, but....)

and 32-bit Lazarus versions 2.0.12, 2.2.6, 3.6 with default versions of FPC.

The following code fragment compiles on all systems without error in both release and debug modes.

The runtime error 219 - Invalid Typecast - only occurs at runtime on Windows 11 x86_64.

I'm reasonable sure that this is the case on Windows 11 21H2, 23H2 and definitely 24H2.

Code: Pascal  [Select][+][-]
  1. Function OleRunningApp( strOLEObject :String) :IUnknown;
  2. Var
  3.   ClassID :TGUID;
  4. Begin
  5. Result := Nil;
  6. CLSIDFromProgID(PWideChar(WideString(strOLEObject)), ClassID);
  7. GetActiveObject( ClassID, Nil, Result); //<< Runtime Error 219 - Invalid Typecast
  8. end;
  9.  
strOLEObject has the value 'Word.Application'.

GetActiveObject is defined in ActiveX.pp as:

   function GetActiveObject(const clsid: TCLSID; pvReserved: Pointer; out unk: IUnknown) : HResult; stdcall; external oleaut32dll name 'GetActiveObject';

I understand that MS is depreciating and / or removing some ActiveX functionality, but I don't know the details.

My questions are:

1. Has anyone else encountered this issue?

2. Does onyone know how to fix / work around this issue?

Regard,
John
« Last Edit: December 27, 2024, 05:51:21 am by mtrsoft »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12984
  • FPC developer.
Re: Lazarus and MSWord Automation on Win 11
« Reply #1 on: December 19, 2024, 01:42:43 pm »
I used 32-bit FPC 3.2.2 and post 3.2.2 fixes branch FPC 3.2.3 and Word 2021 with the code below on Win11 64-bit

The code always compiled, and ran without errors.

However it always said "word is NOT running" if I only included activex. It worked correctly if I also included comobj.

COMOBJ initializes COM (cointializeex and friends), maybe your problem is related to that ?


Code: [Select]

{$mode delphi}
uses activex,comobj;

Function OleRunningApp( strOLEObject :String) :IUnknown;
Var
  ClassID :TGUID;
Begin
Result := Nil;
  CLSIDFromProgID(PWideChar(WideString(strOLEObject)), ClassID);
  GetActiveObject( ClassID, Nil, Result); //<< Runtime Error 219 - Invalid Typecast
end;

begin
  if assigned(olerunningapp('Word.Application')) then
    writeln('Word is running')
  else
    writeln('Word is NOT running')
end.
 

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
Re: Lazarus and MSWord Automation on Win 11
« Reply #2 on: December 19, 2024, 07:55:27 pm »
@marcov thank you.

Yes, comobj was missing from the uses clause in a couple of my units.

We are one step closer to the real(?) problem

I now get the same error message at the RunningWdApp function.

By the way I'm using {$mode objfpc} rather than {$mode delphi}.
I don't think that should make any difference.
Just to be sure I used {$mode delphi} in several of the program's units.


function RunningWdApp :WordApplication;
begin
Result := OleRunningApp( 'Word.Application') as WordApplication;
end;

Call Stack:

#0 FPC_BREAK_ERROR at :0
#1 FPC_BREAK_ERROR+151 at :0
#2 FPC_INTF_AS+45 at :0
#3 RUNNINGWDAPP at C:\lazarus\mtrs\mtrsunits\source\mtrsword.pas:101
#4 WDAPPCONNECT(nil) at C:\lazarus\mtrs\mtrsunits\source\mtrsword.pas:117
#5 MSWORDVERSIONGET at C:\lazarus\mtrs\mtrsunits\source\mtrsword.pas:89
#6 DOFAINIT at D:\FitAll\Fa10Laz\Source\SrcFa\FaInit.pas:693
#7 TFAMAINFORM.FORMCREATE(TFAMAINFORM($01E8FF58), TOBJECT($01E8FF58)) at D:\FitAll\Fa10Laz\Source\SrcFa\FaMain.pas:3883
#8 FORMS$_$TCUSTOMFORM_$__$$_DOCREATE+73 at :0
#9 FORMS$_$TCUSTOMFORM_$__$$_AFTERCONSTRUCTION+68 at :0
#10  at :0
#11  at :0
#12  at :0
#13  at :0


The relavent Type definitions are:

Type
  _Application = interface;
  WordApplication = _Application;

I guess the question is "are interface and IUnknown type compatible?". If not how do I get around that?

It still puzzles me as to why this code has worked for years on Win 7 and 10, but not Win 11.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12984
  • FPC developer.
Re: Lazarus and MSWord Automation on Win 11
« Reply #3 on: December 19, 2024, 09:33:02 pm »
I guess the question is "are interface and IUnknown type compatible?". If not how do I get around that?

They are afaik in Mode Delphi, but not in mode objfpc.

The backstory is that Delphi always had the interface inheritance tree end at IUnknown, which was like a base COM interface with reference counting and identity.

Back then in the late nineties (and yes, shameful to say I was one of them, in my early *nix fervour/innocence), it was considered not totally portable, so a non reference counted type was created below IUnknown. A directive was used to select the base "interface" type ($interface corba vs $interface COM, corba's refcount being mostly manually managed back then, and thus a synonym for "no iunknown").

Quote
It still puzzles me as to why this code has worked for years on Win 7 and 10, but not Win 11.

My guess is different default dialectal modes in either global Lazarus configuration or the project/packages.

Make sure it is mode delphi.

korba812

  • Hero Member
  • *****
  • Posts: 501
Re: Lazarus and MSWord Automation on Win 11
« Reply #4 on: December 19, 2024, 09:55:37 pm »
The relavent Type definitions are:

Type
  _Application = interface;

It looks like a forward type declaration and I can't compile it. Maybe you meant IInterface instead of interface?

PascalDragon

  • Hero Member
  • *****
  • Posts: 6422
  • Compiler Developer
Re: Lazarus and MSWord Automation on Win 11
« Reply #5 on: December 21, 2024, 01:47:38 pm »
I guess the question is "are interface and IUnknown type compatible?". If not how do I get around that?

Assuming it set to {$Interfaces COM} (which is the default), yes, they are.

I guess the question is "are interface and IUnknown type compatible?". If not how do I get around that?

They are afaik in Mode Delphi, but not in mode objfpc.

It does not depend on the mode, only on $Interfaces. And $Mode does not modify $Interfaces.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12984
  • FPC developer.
Re: Lazarus and MSWord Automation on Win 11
« Reply #6 on: December 21, 2024, 02:18:13 pm »
Does my testcode work for you? If it does, it must be something in the code (like classes<->interface conversions).

If my code works for you, start working on a small program to post to show the problem. I'll be away from a machine with msoffice on it till the weekend after christmas though, so a reply might be a bit delayed.

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
Re: Lazarus and MSWord Automation on Win 11
« Reply #7 on: December 21, 2024, 09:07:59 pm »
@marccv

Yes, your program works on my system and indicates properly wheher MSWord 2007 is or isn't running.
Looks like I will have to create a smallish compilable program that reproduces the error.
This will take several days. Not least because I recently fractured my right (dominant) arm and am finding it really difficult to type using only my left hand. -- Some unsolicited advice - watch out for tripping hazards especially if you created it yourself! :-( .

@PascalDragon

I have not knowingly changed the {$interfaces COM} from its default setting.
« Last Edit: December 21, 2024, 09:11:26 pm by mtrsoft »

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
Re: Lazarus and MSWord Automation on Win 11
« Reply #8 on: December 23, 2024, 07:00:44 am »
Attached is a zipped,compilable projet, LTWord02.lpi, that demonstrates the error.
In all cases the project compiles sucessfully.
The resulting executable will run properly on Windows 7 and 10, but will error out when run on Windows 11.

It should be noted the the object of the code is to get a reference to a running copy of MS Word, not just to determine if Word is running.
This so that the running copy of Word can be used later in the full application.

rvk

  • Hero Member
  • *****
  • Posts: 7064
Re: Lazarus and MSWord Automation on Win 11
« Reply #9 on: December 23, 2024, 04:09:45 pm »
First of all... you might want to check the return value of OleRunningApp before casting it to WordApplication.
So something like this, at least then your invalid typecast should go away.

Code: Pascal  [Select][+][-]
  1. function RunningWdApp :WordApplication;
  2. var
  3.   X: IUnknown;
  4. begin
  5.   X := OleRunningApp( 'Word.Application');
  6.   if (X <> nil) then
  7.     Result := X as WordApplication;

Then... you should check why GetActiveObject gives you an unexpected result.
GetActiveObject should give you an HResult.
You didn't check that result.

Check that result and report back what it says on your Windows 11:
https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-getactiveobject

For example:

Name   Description   Value
S_OK   Operation successful   0x00000000
S_FALSE   Operation successful but returned no results   0x00000001
E_ABORT   Operation aborted   0x80004004
E_FAIL   Unspecified failure   0x80004005
E_NOINTERFACE   No such interface supported   0x80004002
E_NOTIMPL   Not implemented   0x80004001
E_POINTER   Pointer that is not valid   0x80004003
E_UNEXPECTED   Unexpected failure   0x8000FFFF

My guess is you get a E_NOINTERFACE in which case there is something wrong with the OLE interface of MS-Word.
« Last Edit: December 23, 2024, 04:13:47 pm by rvk »

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
Re: Lazarus and MSWord Automation on Win 11
« Reply #10 on: December 23, 2024, 10:06:25 pm »
@rvk  thank you for pointing out that I should be doing a bit more error checking.
I have added your suggestions to the test program and added several writeln statemets.
The modified project is attached and the results of four test runs are as follows:

Test1: Win 11 - Word is NOT running:
The GetActiveObject HResult is = -2147221021
OleRunningApp result IS Nil
Press Enter to continue.
Word is NOT running
Press Enter to continue.
(Program exits without error)

Test2: Win 11 - Word IS running:
The GetActiveObject HResult is = 0
OleRunningApp result is NOT Nil
Press Enter to continue.
 //<< Runtime Error 219 - Invalid Typecast
Call stack is:
#0 FPC_BREAK_ERROR at :0
#1 FPC_BREAK_ERROR+151 at :0
#2 FPC_INTF_AS+45 at :0
#3 RUNNINGWDAPP at D:\LazTest\LTWord03\LTWord03.lpr:41
#4 main at D:\LazTest\LTWord03\LTWord03.lpr:62
#5 SYSTEM_$$_EXE_ENTRY$TENTRYINFORMATION+71 at :0


Test3: Win 10 - Word is NOT running:
The GetActiveObject HResult is = -2147221021
OleRunningApp result IS Nil
Press Enter to continue.
Word is NOT running
Press Enter to continue.
(Program exits without error)

Test4: Win 10 - Word IS running:
The GetActiveObject HResult is = 0
OleRunningApp result is NOT Nil
Press Enter to continue.
Word IS running
Press Enter to continue.
(Program exits without error)

rvk

  • Hero Member
  • *****
  • Posts: 7064
Re: Lazarus and MSWord Automation on Win 11
« Reply #11 on: December 23, 2024, 10:18:34 pm »
That seems to be correct then.

So it seems that casting IUnknown to WordApplication is going wrong.

You say this is compiled as 64bit on W11.
Did you also test 64bit on W10 (and that worked)?

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
Re: Lazarus and MSWord Automation on Win 11
« Reply #12 on: December 23, 2024, 10:27:32 pm »
No, the program was compiled as 32-bit.

rvk

  • Hero Member
  • *****
  • Posts: 7064
Re: Lazarus and MSWord Automation on Win 11
« Reply #13 on: December 24, 2024, 11:43:09 am »
Works for me on Windows 11 64 bit in hyper-v with Office 2007 32 bit (had to dig deep there ;) ) and compiled with 32 bit Lazarus trunk. I also tried with Lazarus 3.6 32 bit and that also worked fine.

Note: I didn't run this testproject in the IDE but as a standalone program on all systems.

mtrsoft

  • Jr. Member
  • **
  • Posts: 64
Re: Lazarus and MSWord Automation on Win 11
« Reply #14 on: December 27, 2024, 05:50:41 am »
My sincerest apologies to everyone who wasted time on this issue.

The problem was solved by "Repairing" the MS Office installation.

[ Control Panel > Programs > Programs and Features >Right click MS Office xxxx > Change > Repair > Continue ]

 

TinyPortal © 2005-2018