fix(updater): invoke VSTOInstaller.exe directly so Chrome doesn't hijack the .vsto
v1.2.3 changed the updater to Process.Start the .vsto URL with UseShellExecute=true. On any browser-as-default-handler (Chrome / Edge) that downloads the file to disk instead of handing it to VSTOInstaller, and re-opening the local copy then fails with InvalidDeploymentException "לפריסה וליישום אין אזורי אבטחה תואמים" — the downloaded file lives in the Local Machine zone while the manifest declares the Internet zone. The reliable path is to invoke VSTOInstaller.exe directly with /I and the manifest URL. The URL is then processed in the Internet zone, matching what's declared in the manifest. FindVstoInstaller() looks at the canonical VSTO 4.0 path and falls back to the HKCR registration of the .vsto extension. If even that fails, we tell the user to close and reopen Outlook — the VSTO runtime picks up the new manifest on its own during startup, so the worst case is just an extra restart, not a stuck install. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -216,22 +216,39 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
|||||||
|
|
||||||
// VSTO add-ins cannot be updated programmatically from inside
|
// VSTO add-ins cannot be updated programmatically from inside
|
||||||
// a running Outlook — ApplicationDeployment.Update() throws.
|
// a running Outlook — ApplicationDeployment.Update() throws.
|
||||||
// Open the .vsto URL via the shell; Windows hands it to
|
// Don't shell-launch the .vsto URL either: Chrome / Edge will
|
||||||
// VSTOInstaller.exe which installs the update correctly.
|
// download it to disk, and the resulting file has a different
|
||||||
try
|
// security zone than the deployment manifest, which fails with
|
||||||
|
// InvalidDeploymentException ("no matching security zones").
|
||||||
|
// Call VSTOInstaller.exe directly so the URL is processed in
|
||||||
|
// the Internet zone, matching the manifest.
|
||||||
|
var installerPath = FindVstoInstaller();
|
||||||
|
if (installerPath != null)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(manifestUri.ToString())
|
try
|
||||||
{
|
{
|
||||||
UseShellExecute = true
|
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(
|
||||||
});
|
installerPath, "/I \"" + manifestUri + "\"")
|
||||||
UpdateStatusBrush = SuccessBrush;
|
{
|
||||||
UpdateStatus = $"זמינה גרסה {availableVersion} — אשר את ההתקנה בחלון שנפתח, ואז סגור ופתח את Outlook.";
|
UseShellExecute = false
|
||||||
|
});
|
||||||
|
UpdateStatusBrush = SuccessBrush;
|
||||||
|
UpdateStatus = $"זמינה גרסה {availableVersion} — אשר את ההתקנה בחלון שנפתח, ואז סגור ופתח את Outlook.";
|
||||||
|
}
|
||||||
|
catch (Exception launchEx)
|
||||||
|
{
|
||||||
|
_logger.Warning(launchEx, "CheckForUpdate: VSTOInstaller launch failed");
|
||||||
|
UpdateStatusBrush = ErrorBrush;
|
||||||
|
UpdateStatus = $"זמינה גרסה {availableVersion} — סגור ופתח את Outlook כדי להתקין אוטומטית.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception launchEx)
|
else
|
||||||
{
|
{
|
||||||
_logger.Warning(launchEx, "CheckForUpdate: shell launch of installer URL failed");
|
// VSTOInstaller not at the canonical path — VSTO runtime
|
||||||
UpdateStatusBrush = ErrorBrush;
|
// still picks up new manifests on Outlook startup, so
|
||||||
UpdateStatus = $"זמינה גרסה {availableVersion} אבל לא הצלחנו לפתוח את חלון ההתקנה. גש ידנית ל-{manifestUri}";
|
// ask the user to restart instead of attempting a hack.
|
||||||
|
UpdateStatusBrush = SuccessBrush;
|
||||||
|
UpdateStatus = $"זמינה גרסה {availableVersion} — סגור ופתח את Outlook כדי להתקין אוטומטית.";
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -286,6 +303,50 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Locates VSTOInstaller.exe on the machine. The path is stable
|
||||||
|
/// for VSTO 4.0 (Office 2010+) — falls back to a registry lookup
|
||||||
|
/// if the default install location was customised.
|
||||||
|
/// </summary>
|
||||||
|
private static string? FindVstoInstaller()
|
||||||
|
{
|
||||||
|
string[] candidates =
|
||||||
|
{
|
||||||
|
@"C:\Program Files (x86)\Common Files\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe",
|
||||||
|
@"C:\Program Files\Common Files\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe"
|
||||||
|
};
|
||||||
|
foreach (var p in candidates)
|
||||||
|
{
|
||||||
|
if (System.IO.File.Exists(p)) return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registry fallback: HKCR\VstoFile\shell\Open\command stores
|
||||||
|
// the verb VSTOInstaller registers for the .vsto extension.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(@"VstoFile\shell\Open\command"))
|
||||||
|
{
|
||||||
|
var cmd = key?.GetValue(null) as string;
|
||||||
|
if (!string.IsNullOrEmpty(cmd))
|
||||||
|
{
|
||||||
|
// Value looks like: "C:\...\VSTOInstaller.exe" "%1"
|
||||||
|
var firstQuote = cmd!.IndexOf('"');
|
||||||
|
if (firstQuote == 0)
|
||||||
|
{
|
||||||
|
var endQuote = cmd.IndexOf('"', 1);
|
||||||
|
if (endQuote > 1)
|
||||||
|
{
|
||||||
|
var exe = cmd.Substring(1, endQuote - 1);
|
||||||
|
if (System.IO.File.Exists(exe)) return exe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { /* registry access denied or schema differs — fall through */ }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private bool CanCheckForUpdate() => !IsCheckingForUpdate;
|
private bool CanCheckForUpdate() => !IsCheckingForUpdate;
|
||||||
|
|
||||||
partial void OnIsCheckingForUpdateChanged(bool value)
|
partial void OnIsCheckingForUpdateChanged(bool value)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<PublishUrl>C:\Users\Chaim\source\repos\OutlookAddin\Publish\</PublishUrl>
|
<PublishUrl>C:\Users\Chaim\source\repos\OutlookAddin\Publish\</PublishUrl>
|
||||||
<InstallUrl>https://gitea.dev.marcus-law.co.il/espocrm-extensions/OutlookAddin/raw/branch/main/Publish/</InstallUrl>
|
<InstallUrl>https://gitea.dev.marcus-law.co.il/espocrm-extensions/OutlookAddin/raw/branch/main/Publish/</InstallUrl>
|
||||||
<TargetCulture>en</TargetCulture>
|
<TargetCulture>en</TargetCulture>
|
||||||
<ApplicationVersion>1.2.4.0</ApplicationVersion>
|
<ApplicationVersion>1.2.5.0</ApplicationVersion>
|
||||||
<AutoIncrementApplicationRevision>false</AutoIncrementApplicationRevision>
|
<AutoIncrementApplicationRevision>false</AutoIncrementApplicationRevision>
|
||||||
<UpdateEnabled>true</UpdateEnabled>
|
<UpdateEnabled>true</UpdateEnabled>
|
||||||
<UpdateInterval>7</UpdateInterval>
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
|||||||
@@ -33,6 +33,6 @@ using System.Security;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.4.0")]
|
[assembly: AssemblyVersion("1.2.5.0")]
|
||||||
[assembly: AssemblyFileVersion("1.2.4.0")]
|
[assembly: AssemblyFileVersion("1.2.5.0")]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user