Search code examples
excelinno-setuppascalscriptvba

Adding Excel Addin folder to Trusted locations with Inno Setup


I'm using the Inno Setup ExcelAddinInstaller which works great.

{
  Looks up the localized Addins folder in the registry.
  This function is used in the [Files] section of the
  script, where function calls always expect a parametrized
  function. This function does not require a parameter.
  Therefore, a dummy parameter is defined.
}
function GetDestDir(dummyparameter: string): string;
var
  Addins: string;
  s: string;
  CallName: string;
  i: integer;
begin
  if DestDir = '' then
  begin
    CallName := 'GetDestDir(' + dummyparameter + '): ';
    log(CallName+'Trying to find addins folder name');

    {
      Note the trailing backslash
    }
    DestDir := ExpandConstant('{userappdata}\Microsoft\');

    {
      Loop through possible version numbers of Excel and find out if
      any installed version uses an addin folder other than "addins".
      This can be the case with international versions (other than English).
      If an addin folder name that is different from "Addins" is found,
      the addin will be installed into a dedicated folder.
    }
    for i := 8 to 32 do
    begin
      s := '';
      if RegQueryStringValue(HKEY_CURRENT_USER, 'Software\Microsoft\Office\'
        +IntToStr(i)+'.0\Common\General', 'AddIns', s) then
      begin
        if Length(Addins) > 0 then
        begin
          {
            If the Addins variable has been set already and we encounter
            a different name, reset everything in order to use a dedicated
            name further on.
          }
          if s <> Addins then
          begin
            {
              Set the Addins variable to a zero-length string to force
              using a dedicated dir name later.
            }
            log(CallName+'Found alternative Addins key for version '+IntToStr(i)+': "'+s+'"');
            Addins := '';
            {
              Once a single dir name that is different from "Addins" was
              found, we can exit the loop.
            }
            break;
          end 
        end
        else
        begin
          {
            Addins variable has zero length: Set it to the current value of s
          }
          log(CallName+'Found first Addins key: version '+IntToStr(i)+', "'+s+'"');
          Addins := s;
        end
      end
    end;

    {
      Check if the Addins variable contains something now; if not, use
      a default value ('XL Toolbox')
    }
    if Addins = '' then
    begin
      DestDir := ExpandConstant('{userappdata}\Microsoft\Addins\');
      RegisterWithFullPath := true;
      log(CallName+'Using dedicated folder: "'+DestDir+'"');  
    end
    else
    begin
      DestDir := ExpandConstant('{userappdata}\Microsoft\' + Addins);
      RegisterWithFullPath := false;
      log(CallName+'Installing to default Addins folder: ' + DestDir);  
    end;
  end;
  result := DestDir; 
end;

But it happens that in Excel 2016 and 2013 the folder where the add-in is installed by default is not defined as a "trusted location" by Excel, making the add-in to install but not to be displayed in Excel.

I'm looking for adding the path returned by the GetDestDir be added to

HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Secur‌​‌​ity\Trusted Locations\MyLocation

Solution

  • The following code finds the first unused LocationX subkey under Trusted Locations and writes the Addins path there:

    const
      TrustedLocationsKey =
        'Software\Microsoft\Office\16.0\Excel\Security\Trusted Locations';
    
    procedure AddAddinsToExcelTrustedLocations;
    var
      LocationIndex: Integer;
      LocationKey: string;
      Path: string;
    begin
      if not RegKeyExists(HKEY_CURRENT_USER, TrustedLocationsKey) then
      begin
        MsgBox('Excel trusted locations registry key not found', mbError, MB_OK);
      end
        else
      begin
        { Find unused LocationX }
        LocationIndex := 0;
        repeat
          LocationKey := Format('%s\Location%d', [TrustedLocationsKey, LocationIndex]);
          Log(Format('Trying %s', [LocationKey]));
          Inc(LocationIndex);
        until (not RegKeyExists(HKEY_CURRENT_USER, LocationKey));
    
        Log(Format('Will use %s', [LocationKey]));
    
        { Addins is the variable from your question code }
        Path := GetDestDir('');
        if not RegWriteStringValue(HKEY_CURRENT_USER, LocationKey, 'Path', Path) then
        begin
          MsgBox(
            Format('Cannot add %s to Excel trusted locations', [Path]), mbError, MB_OK);
        end
          else
        begin
          Log(Format('Added %s to Excel trusted locations', [Path]));
        end;
      end;
    end;
    
    procedure CurStepChanged(CurStep: TSetupStep);
    begin
      if CurStep = ssPostInstall then
      begin
        AddAddinsToExcelTrustedLocations;
      end;
    end;