Skip to content

Commit

Permalink
#163 Chrome Extension 자동 설치 기능 추가
Browse files Browse the repository at this point in the history
- Edge 설정 다시 불러오기 관련 기능을 분리 적용함
  • Loading branch information
rkttu committed Jan 28, 2024
1 parent f2cf45c commit c7ceeb4
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 43 deletions.
95 changes: 61 additions & 34 deletions src/Hostess/Components/Implementations/StepsComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
var catalog = _resourceCacheManager.CatalogDocument;
var targets = parsedArgs.SelectedServices;

var packages = new List<InstallItemViewModel>
var steps = new List<InstallItemViewModel>
{
new InstallItemViewModel()
{
Expand Down Expand Up @@ -88,7 +88,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
if (parsedArgs.EnableInternetExplorerMode.HasValue &&
parsedArgs.EnableInternetExplorerMode.Value)
{
packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.CustomAction,
TargetSiteName = UIStringResources.Option_Prerequisites,
Expand All @@ -104,7 +104,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
if (targetService == null)
continue;

packages.AddRange(targetService.Packages.Select(eachPackage => new InstallItemViewModel()
steps.AddRange(targetService.Packages.Select(eachPackage => new InstallItemViewModel()
{
InstallItemType = InstallItemType.DownloadAndInstall,
TargetSiteName = targetService.DisplayName,
Expand All @@ -115,11 +115,21 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
Installed = null,
}));

steps.AddRange(targetService.EdgeExtensions.Select(eachEdgeExtension => new InstallItemViewModel()
{
InstallItemType = InstallItemType.EdgeExtensionInstall,
TargetSiteName = targetService.DisplayName,
TargetSiteUrl = targetService.Url,
PackageName = eachEdgeExtension.Name,
EdgeExtensionId = eachEdgeExtension.ExtensionId,
EdgeCrxUrl = eachEdgeExtension.CrxUrl,
}));

var bootstrapData = targetService.CustomBootstrap;

if (!string.IsNullOrWhiteSpace(bootstrapData))
{
packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.PowerShellScript,
TargetSiteName = targetService.DisplayName,
Expand All @@ -130,18 +140,26 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
}
}

packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.CustomAction,
TargetSiteName = UIStringResources.Option_Config,
PackageName = UIStringResources.Install_ConfigASTx,
CustomAwaitableAction = ConfigASTxAsync,
});

steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.CustomAction,
TargetSiteName = UIStringResources.Option_Config,
PackageName = UIStringResources.Install_ReloadMicrosoftEdge,
CustomAwaitableAction = ReloadEdgeAsync,
});

if (parsedArgs.InstallAdobeReader.HasValue &&
parsedArgs.InstallAdobeReader.Value)
{
packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.OpenWebSite,
TargetSiteName = UIStringResources.Option_Addin,
Expand All @@ -156,7 +174,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
if (parsedArgs.InstallEveryonesPrinter.HasValue &&
parsedArgs.InstallEveryonesPrinter.Value)
{
packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.OpenWebSite,
TargetSiteName = UIStringResources.Option_Addin,
Expand All @@ -168,7 +186,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
if (parsedArgs.InstallHancomOfficeViewer.HasValue &&
parsedArgs.InstallHancomOfficeViewer.Value)
{
packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.OpenWebSite,
TargetSiteName = UIStringResources.Option_Addin,
Expand All @@ -180,7 +198,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
if (parsedArgs.InstallRaiDrive.HasValue &&
parsedArgs.InstallRaiDrive.Value)
{
packages.Add(new InstallItemViewModel()
steps.Add(new InstallItemViewModel()
{
InstallItemType = InstallItemType.OpenWebSite,
TargetSiteName = UIStringResources.Option_Addin,
Expand All @@ -189,7 +207,7 @@ public IEnumerable<InstallItemViewModel> ComposeSteps()
});
}

return packages;
return steps;
}

private async Task PrepareDirectoriesAsync(InstallItemViewModel viewModel,
Expand All @@ -209,6 +227,36 @@ private async Task PrepareDirectoriesAsync(InstallItemViewModel viewModel,
Directory.CreateDirectory(downloadFolderPath);
}

private async Task ReloadEdgeAsync(InstallItemViewModel viewModel,
CancellationToken cancellationToken = default)
{
// msedge.exe 파일 경로를 유추하고, Policy를 반영하기 위해 잠시 실행했다가 종료하는 동작을 추가
if (!_sharedLocations.TryGetMicrosoftEdgeExecutableFilePath(out var msedgePath))
msedgePath = _sharedLocations.GetDefaultX86MicrosoftEdgeExecutableFilePath();

if (File.Exists(msedgePath))
{
var msedgePsi = new ProcessStartInfo(msedgePath, "about:blank")
{
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Minimized,
};

using (var msedgeProcess = Process.Start(msedgePsi))
{
var tcs = new TaskCompletionSource<int>();
msedgeProcess.EnableRaisingEvents = true;
msedgeProcess.Exited += (_sender, _e) =>
{
tcs.SetResult(msedgeProcess.ExitCode);
};
await Task.Delay(TimeSpan.FromSeconds(3d), cancellationToken).ConfigureAwait(false);
msedgeProcess.CloseMainWindow();
await tcs.Task.ConfigureAwait(false);
}
}
}

private async Task EnableIEModeAsync(InstallItemViewModel viewModel,
CancellationToken cancellationToken = default)
{
Expand All @@ -222,37 +270,16 @@ private async Task EnableIEModeAsync(InstallItemViewModel viewModel,

if (parsedArgs.EnableInternetExplorerMode ?? false)
{
// HKLM\SOFTWARE\Policies\Microsoft\Edge > InternetExplorerIntegrationLevel (REG_DWORD) with value 1, InternetExplorerIntegrationSiteList (REG_SZ)
using (var ieModeKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Policies\Microsoft\Edge", true))
{
ieModeKey.SetValue("InternetExplorerIntegrationLevel", 1, RegistryValueKind.DWord);
ieModeKey.SetValue("InternetExplorerIntegrationSiteList", ConstantStrings.IEModePolicyXmlUrl, RegistryValueKind.String);
}

// msedge.exe 파일 경로를 유추하고, Policy를 반영하기 위해 잠시 실행했다가 종료하는 동작을 추가
if (!_sharedLocations.TryGetMicrosoftEdgeExecutableFilePath(out var msedgePath))
msedgePath = _sharedLocations.GetDefaultX86MicrosoftEdgeExecutableFilePath();

if (File.Exists(msedgePath))
using (var ieModeKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Policies\Wow6432Node\Microsoft\Edge", true))
{
var msedgePsi = new ProcessStartInfo(msedgePath, "about:blank")
{
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Minimized,
};

using (var msedgeProcess = Process.Start(msedgePsi))
{
var tcs = new TaskCompletionSource<int>();
msedgeProcess.EnableRaisingEvents = true;
msedgeProcess.Exited += (_sender, _e) =>
{
tcs.SetResult(msedgeProcess.ExitCode);
};
await Task.Delay(TimeSpan.FromSeconds(1.5d), cancellationToken).ConfigureAwait(false);
msedgeProcess.CloseMainWindow();
await tcs.Task.ConfigureAwait(false);
}
ieModeKey.SetValue("InternetExplorerIntegrationLevel", 1, RegistryValueKind.DWord);
ieModeKey.SetValue("InternetExplorerIntegrationSiteList", ConstantStrings.IEModePolicyXmlUrl, RegistryValueKind.String);
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/Hostess/Components/Implementations/StepsPlayer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hostess.ViewModels;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand Down Expand Up @@ -53,6 +54,8 @@ public async Task<bool> PlayStepsAsync(
await ProcessPowerShellScriptAsync(eachItem, cancellationToken).ConfigureAwait(false);
else if (eachItem.InstallItemType == InstallItemType.OpenWebSite)
await OpenAddInWebSiteAsync(eachItem, cancellationToken).ConfigureAwait(false);
else if (eachItem.InstallItemType == InstallItemType.EdgeExtensionInstall)
ProcessEdgeExtensionInstall(eachItem);
else if (eachItem.InstallItemType == InstallItemType.CustomAction)
{
if (eachItem.UseNonAwaitableAction)
Expand Down Expand Up @@ -216,6 +219,24 @@ private async Task OpenAddInWebSiteAsync(InstallItemViewModel viewModel,
});
}

private void ProcessEdgeExtensionInstall(InstallItemViewModel viewModel)
{
// https://learn.microsoft.com/en-us/microsoft-edge/extensions-chromium/developer-guide/alternate-distribution-options
using (var regKey = Registry.LocalMachine.CreateSubKey(
@"Software\Microsoft\Edge\Extensions", true))
{
using (regKey.CreateSubKey(viewModel.EdgeExtensionId)) { }
regKey.SetValue("update_url", viewModel.EdgeCrxUrl);
}

using (var regKey = Registry.LocalMachine.CreateSubKey(
@"Software\Wow6432Node\Microsoft\Edge\Extensions", true))
{
using (regKey.CreateSubKey(viewModel.EdgeExtensionId)) { }
regKey.SetValue("update_url", viewModel.EdgeCrxUrl);
}
}

private async Task OpenRequestedWebSiteAsync(string targetUrl,
CancellationToken cancellationToken = default)
{
Expand Down
1 change: 1 addition & 0 deletions src/Hostess/ViewModels/InstallItemType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public enum InstallItemType : int
PowerShellScript,
OpenWebSite,
CustomAction,
EdgeExtensionInstall,
}
}
14 changes: 14 additions & 0 deletions src/Hostess/ViewModels/InstallItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class InstallItemViewModel : ViewModelBase
private string _packageUrl;
private string _arguments;
private string _scriptContent;
private string _edgeCrxUrl;
private string _edgeExtensionId;
private bool? _installed;
private string _statusMessage;
private string _errorMessage;
Expand Down Expand Up @@ -66,6 +68,18 @@ public string ScriptContent
set => SetProperty(ref _scriptContent, value);
}

public string EdgeCrxUrl
{
get => _edgeCrxUrl;
set => SetProperty(ref _edgeCrxUrl, value);
}

public string EdgeExtensionId
{
get => _edgeExtensionId;
set => SetProperty(ref _edgeExtensionId, value);
}

public bool? Installed
{
get => _installed;
Expand Down
9 changes: 9 additions & 0 deletions src/TableCloth.Resources/UIStringResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/TableCloth.Resources/UIStringResources.ko.resx
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@
<data name="Install_PrepareEnvironment" xml:space="preserve">
<value>환경 준비 중</value>
</data>
<data name="Install_ReloadMicrosoftEdge" xml:space="preserve">
<value>Microsoft Edge 설정 새로 고침</value>
</data>
<data name="Install_SetDesktopWallpaper" xml:space="preserve">
<value>바탕 화면 변경</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions src/TableCloth.Resources/UIStringResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@ We recommend that you do not use TableCloth for tasks that cannot be performed i
<data name="Install_PrepareEnvironment" xml:space="preserve">
<value>Preparing Environment</value>
</data>
<data name="Install_ReloadMicrosoftEdge" xml:space="preserve">
<value>Reload Microsoft Edge Settings</value>
</data>
<data name="Install_SetDesktopWallpaper" xml:space="preserve">
<value>Setting Desktop Wallpaper</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Xml.Serialization;

namespace TableCloth.Models.Catalog
{
[Serializable, XmlType]
public sealed class CatalogEdgeExtensionInformation
{
[XmlAttribute("Name")]
public string Name { get; set; } = string.Empty;

[XmlAttribute("CrxUrl")]
public string CrxUrl { get; set; } = string.Empty;

[XmlAttribute("ExtensionId")]
public string ExtensionId { get; set; } = string.Empty;
}
}
21 changes: 12 additions & 9 deletions src/TableCloth.Shared/Models/Catalog/CatalogInternetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public string
public List<CatalogPackageInformation> Packages { get; set; } = new List<CatalogPackageInformation>();
#pragma warning restore IDE0028 // Simplify collection initialization

[XmlArray, XmlArrayItem(typeof(CatalogEdgeExtensionInformation), ElementName = "EdgeExtension")]
public List<CatalogEdgeExtensionInformation> EdgeExtensions { get; set; } = new List<CatalogEdgeExtensionInformation>();

/// <summary>
/// 서비스를 이용하기 위해 실행해야 하는 부트스트랩 스크립트
/// </summary>
Expand Down Expand Up @@ -101,13 +104,13 @@ public string
SearchKeywords
{ get; set; }

/// <summary>
/// 서비스 분류 카테고리를 사용자에게 표시할 때 쓸 이름을 가져옵니다.
/// </summary>
/// <remarks>
/// 이 속성은 실제 XML 데이터를 이용하여 값을 만드는 계산된 속성입니다.
/// </remarks>
[XmlIgnore]
/// <summary>
/// 서비스 분류 카테고리를 사용자에게 표시할 때 쓸 이름을 가져옵니다.
/// </summary>
/// <remarks>
/// 이 속성은 실제 XML 데이터를 이용하여 값을 만드는 계산된 속성입니다.
/// </remarks>
[XmlIgnore]
public string CategoryDisplayName
{
get
Expand Down Expand Up @@ -140,7 +143,7 @@ public int PackageCountForDisplay
{
get
{
var actualPackageCount = Packages.Count;
var actualPackageCount = Packages.Count + EdgeExtensions.Count;
if (!string.IsNullOrWhiteSpace(CustomBootstrap))
actualPackageCount++;
return actualPackageCount;
Expand All @@ -162,7 +165,7 @@ public override string ToString()
defaultString = $"*{defaultString}";

if (pkgs != null && pkgs.Count > 0)
defaultString = $"{defaultString} ( {PackageCountForDisplay}개 프로그램 설치)";
defaultString = $"{defaultString} (Total {PackageCountForDisplay} package(s) required.)";

return defaultString;
}
Expand Down
1 change: 1 addition & 0 deletions src/TableCloth.Shared/TableCloth.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Models\ApplicationStartupResultModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Catalog\CatalogCompanion.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Catalog\CatalogDocument.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Catalog\CatalogEdgeExtensionInformation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Catalog\CatalogInternetService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Catalog\CatalogInternetServiceCategory.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Catalog\CatalogNamespaces.cs" />
Expand Down

0 comments on commit c7ceeb4

Please sign in to comment.