Во время установки нашей надстройки PowerPoint с помощью установщика Inno Setup мне нужно получить текущую используемую версию PowerPoint, запросив сам объект Application.PowerPoint
— вместо того, чтобы полагаться на записи реестра , которые не могут гарантировать правильное значение .
Я успешно реализовал это для установщика MSI, написанного с помощью WIX , на основе этого ответа , используя этот код:
Imports Microsoft.Office.Interop.PowerPoint
Public Class Environment
Public Shared Function GetPowerPointVersion() As String
Dim CurVer As String
Dim thisPowerPoint As Object
thisPowerPoint = New Application()
CurVer = thisPowerPoint.Version
thisPowerPoint.Quit()
Return CurVer
End Function
End Class
Я не полностью верю, что это работает во всех ситуациях (возможно, параноидально), поэтому вставлю блоки try/catch и воспользуюсь методом реестра, если это не удастся.
Я не смог понять, как сделать то же самое с установщиком Inno Setup. Есть несколько примеров использования DLL — https://jrsoftware.org/ishelp/index.php?topic=scriptdll — но я не понимаю, как я мог бы создать из этого функцию, вызываемую из Inno Setup, которая возвращала бы номер версии.
Вы можете использовать CreateOleObject для вызова PowerPoint и возврата версии:
[Code]
function GetPowerPointVersion(): string;
var
MyPowerPoint: Variant;
begin
MyPowerPoint := CreateOleObject('PowerPoint.Application');
Result := MyPowerPoint.Version;
MyPowerPoint.Quit;
end;
Вы, вероятно, должны ловить исключения в этом коде (в случае, если объект не может быть создан).
CreateOleObject вызовет исключение, если не удастся. Итак, да, код должен быть помещен в раздел try...except или try...finally.
Для тех, кто читает, ответ ОП включает обработку исключений.
Для полноты это код Pascal Script, который я сейчас использую для получения версии PowerPoint, основанный на ответе Матея, с откатом к проверке реестра в случае сбоя:
function PowerPointVersion(): String;
var
key: String;
versionToUse: String;
installedPowerPoint: Variant;
begin
versionToUse := '';
try
installedPowerPoint := CreateOleObject('PowerPoint.Application');
versionToUse := installedPowerPoint.Version;
installedPowerPoint.Quit;
except
versionToUse := '';
end;
if versionToUse = '' then
begin
if RegQueryStringValue(GetHKLM, 'SOFTWARE\Microsoft\Office\ClickToRun\Configuration','VersionToReport', key) then
begin
versionToUse := key;
Delete(versionToUse, Pos('.', key), Length(key));
versionToUse := versionToUse + '.0';
end;
end;
if versionToUse = '' then
begin
if RegQueryStringValue(HKCR, 'PowerPoint.Application\CurVer\','', key) then
begin
StringChangeEx(key, 'PowerPoint.Application.', '', True);
versionToUse := key;
versionToUse := versionToUse + '.0';
end;
end;
try
// Check to see if versionToUse string can convert to a float:
StrToFloat(versionToUse);
Result := versionToUse;
except
Result := '';
end;
end;
Оказывается, использование Microsoft.Office.Interop.PowerPoint
, который является пакетом NuGet, не является хорошей идеей, поскольку он не поддерживается и может привести к сбою. Смотрите это обсуждение.
Этот внешний код C# будет работать, и его можно настроить для вызова из Inno Setup. Однако использование CreateOleObject
в коде Inno Setup Pascal, как описано в принятом ответе, намного проще.
[SupportedOSPlatform("windows")]
public class PowerPointEnvironment
{
public static string GetPowerPointVersion()
{
string CurVer = "";
Type? PowerPointType = Type.GetTypeFromProgID("PowerPoint.Application");
if (PowerPointType != null)
{
dynamic? thisPowerPoint = Activator.CreateInstance(PowerPointType);
if (thisPowerPoint != null)
{
CurVer = thisPowerPoint.version();
}
}
return CurVer;
}
}
Использование номера версии, возвращаемого приложением PowerPoint, может не дать вам всей необходимой информации; каждая версия, начиная с 2016 года, идентифицируется как 16.0 (включая версии Office 365). Если вы проверяете, поддерживается ли конкретная функция, номер версии может не помочь.
Я использую номер версии, чтобы найти в реестре нужное место для регистрации надстройки. Таким образом, мы надеемся, что для этого использования номер версии, возвращаемый приложением PowerPoint, по-прежнему будет правильным для этой цели?
Да, это будет работать, как вы хотите. В основном используется номер версии, чтобы интуитивно понять, какие функции поддерживаются/не поддерживаются, что может быть проблемой. Вы можете идти.
Поможет ли это? Как я могу вызвать .NET DLL из скрипта Inno Setup?