Unloading a Word add-in

Add-in Express™ Support Service
That's what is more important than anything else

Unloading a Word add-in
How to unload the add-in if conditions are not right for it 
Roger Middlebrook


Guest


I have a VCL add-in for Word. During the add-in initialization I want to check that the conditions are right for the add-in to run. If they are not OK I want to unload the add-in.

How is this done?
Posted 27 Jul, 2006 10:39:25 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Hi Roger,

I think you can use the OnAddinInitialize event handler and do one of the following:
1. find your add-in in the WordApplication.COMAddins collection and set the Connect property to false;
2. free all components (TadxCommandBar components ?) on your TAddinModule to prevent them to be added to MS Word command bars;
3. set a flag (e.g. IsEnabled) and check it in all event handlers;

Posted 27 Jul, 2006 11:16:47 Top
Roger Middlebrook


Guest


I like the first one best and I did try it. Unfortunately I couldn't find my COM add-in. I thought this was because it hadn't yet been added to the COMAddIns collection but I hope I'm wrong. Can you show me some code to find my COM add-in please?
Posted 27 Jul, 2006 11:20:57 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Hi Roger,

See the code below:


var
  IAddIn: COMAddIn;
  i: Integer;
  V: OleVariant;
  Guid: string;
begin
  IAddIn := nil;
  try
    Guid := GuidToString(CLASS_YOURADDID); // see the "YOUR_ADDIN_NAME"_TLB.pas
    for i := 1 to WordApp.COMAddIns.Count do begin
      V := i;
      if WordApp.COMAddIns.Item(V).Guid = Guid then begin
        IAddIn := WordApp.COMAddIns.Item(V);
        Break;
      end;
    end;
    if Assigned(IAddIn) then
      try
        IAddIn.Connect := False;
      finally
        IAddIn := nil;
      end;
  except
    // TODO
  end;
end;

Posted 27 Jul, 2006 13:17:04 Top
Roger Middlebrook


Guest


That almost does the trick. Unfortunately it leaves the add-in with a load behaviour in the registry set to 2. Is there a command to set it back to 3 or do I have to access the registry myself?
Posted 04 Aug, 2006 05:36:50 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Hi Roger,

Of course after setting the Connect property to false, your add-in will never be loaded and you need either a standalone application of some sort for changing the registry settings (LoadBehavior) or make the end-user turn your add-in on. I think #3 solution from the post above is better than #1.

Posted 04 Aug, 2006 09:06:57 Top
Roger Middlebrook


Guest


Oh, I thought you were all on holiday...

In the meantime, I have implemented the following procedure:

procedure TAddInModule.RegisterLoadBehavior(const Value: integer);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    if Self.RegisterForAllUsers then
      Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey(AddInRegistryKey, True) then begin
      Reg.WriteInteger('LoadBehavior', Value);
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

AddInRegistryKey needs to be a standard variable and needs to set before the AddInModule is disconnected.

I have successfully implemented the following at the end of your code:

    if Assigned(IAddIn) then 
      try 
        IAddIn.Connect := False; 
        RegisterLoadBehavior(3);
      finally 
        IAddIn := nil; 
      end; 
Posted 04 Aug, 2006 09:21:54 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Roger,

MS Word changes the LoadBehavior value after your add-in is completely unloaded.


procedure TAddInModule.RegisterLoadBehavior(const Value: integer);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    if Self.RegisterForAllUsers then
      Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey(Self.RegistryKey{AddInRegistryKey}, True) then begin
      Reg.WriteInteger('LoadBehavior', Value);
      Reg.WriteInteger('TEST', Value);
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

procedure TAddInModule.RegisterLoadBehavior(const Value: integer);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    if Self.RegisterForAllUsers then
      Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey(Self.RegistryKey{AddInRegistryKey}, True) then begin
      if Reg.ValueExists('LoadBehavior') then
        ShowMessage(IntToStr(Reg.ReadInteger('LoadBehavior')));
      Reg.WriteInteger('LoadBehavior', Value);
      Reg.WriteInteger('TEST', Value);
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

procedure TAddInModule.adxCOMAddInModuleAddInBeginShutdown(Sender: TObject);
begin
  if isNeedToSetLoadBehavior then
    RegisterLoadBehavior(3);
end;

procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
  if isNeedToSetLoadBehavior then
    RegisterLoadBehavior(3);
end;


Posted 04 Aug, 2006 12:54:12 Top
Roger Middlebrook


Guest


The funny thing is though, my code works! I did think it odd that I was effectively calling a method AFTER the add-in had been unloaded but it does work on the 3 PCs I have tried.
Posted 07 Aug, 2006 11:35:13 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Hi Roger,

I agree with you. Now I see what was wrong in my code snippet and understand why your code works ok.

Posted 14 Aug, 2006 05:11:58 Top