dragon-iso/src/TeamsISO.App/Services/TeamsLauncher.cs

91 lines
3.2 KiB
C#
Raw Normal View History

using System.Diagnostics;
using System.IO;
namespace TeamsISO.App.Services;
/// <summary>
/// Small Win32 wrapper that launches the Microsoft Teams desktop client as a
/// subprocess of TeamsISO. First step toward Phase E.1 of the embedded-Teams
/// roadmap (see docs/superpowers/specs/2026-05-08-embedded-teams-orchestration.md):
/// the operator can launch Teams from within TeamsISO so they don't have to
/// switch apps to start a meeting.
///
/// The launcher tries (in order):
/// 1. ms-teams: URI (works for both classic and new Teams)
/// 2. MSTeams.exe in %LOCALAPPDATA%\Microsoft\WindowsApps\
/// 3. Teams.exe in %LOCALAPPDATA%\Microsoft\Teams\Update.exe (legacy)
///
/// Group-routing automation (writing NDI Access Manager config so Teams
/// broadcasts on a private group) is deferred to a follow-up — for v1.0 we
/// document the manual steps in RELEASING.md and trust the operator to set
/// them once per machine.
/// </summary>
public static class TeamsLauncher
{
/// <summary>
/// Launches Teams. Returns true if a launch was started successfully (the
/// process may take a few seconds to actually appear). False if every
/// fallback path failed.
/// </summary>
public static bool TryLaunch(out string? errorMessage)
{
errorMessage = null;
// Path 1: URI scheme. The shell handler picks whichever Teams client
// is registered (new MSTeams.exe takes priority on modern Windows).
if (TryStart("ms-teams:", useShell: true)) return true;
// Path 2: new Teams' WindowsApps shim.
var newTeams = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft", "WindowsApps", "ms-teams.exe");
if (File.Exists(newTeams) && TryStart(newTeams, useShell: false)) return true;
// Path 3: classic Teams Update.exe with --processStart hands off to
// the actual Teams.exe via Squirrel.
var classicUpdater = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft", "Teams", "Update.exe");
if (File.Exists(classicUpdater))
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = classicUpdater,
Arguments = "--processStart \"Teams.exe\"",
UseShellExecute = false,
CreateNoWindow = true,
});
return true;
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
}
errorMessage ??= "No Microsoft Teams installation was found. Install Teams from https://www.microsoft.com/microsoft-teams and try again.";
return false;
}
private static bool TryStart(string target, bool useShell)
{
try
{
var info = new ProcessStartInfo
{
FileName = target,
UseShellExecute = useShell,
CreateNoWindow = true,
};
Process.Start(info);
return true;
}
catch
{
return false;
}
}
}