Self-contained .NET (#22217)

* dotnet sc

* MD preview - C# app

 - working self-contained

* Gcode preview - C# app

* DevFiles preview - C# app

* Fix passing path with spaces as cmd arg and monacocpp proj file

* Pdf preview - C# app

* Svg preview - C# app

* Fix comment

* Gcode thumbnail - C# app

TODO:
	- installer
	- why IThumbnailProvider and IIntializeWithFile doesn't work?

* Pdf thumbnail - C# app

TODO:
        - installer
        - why IThumbnailProvider and IIntializeWithFile doesn't work?

* Pdf thumbnail - C# app

TODO:
        - installer
        - why IThumbnailProvider and IIntializeWithFile doesn't work?

* Fix GcodeThumbnailProviderCpp.vcxproj

* Svg thumbnail - C# app

TODO:
        - installer
        - why IThumbnailProvider and IIntializeWithFile doesn't work?

* Fix Svg tests

* Thumbnail providers - installer

* Self-contained Hosts and FileLocksmith

* Fix hardcoded <RuntimeIdentifier>

* Remove unneeded files

* Try to fix Nuget in PR CI

* Prefix new dlls with PowerToys.
Sign new dlls and exes

* Add new .exe files to ProcessList

* ci: debug by listing all env vars

* ci: try setting variable in the right ci file

* Bring back hardcoded RuntimeIdentifier

* ci: Add comment and remove debug action

* Remove unneeded lib

* [WIP] Platform conditional dotnet files & hardlinks

* Cleanup

* Update expect.txt

* Test fix - ARM installer

* Fix uninstall bug

* Update docs

* Fix failing test

* Add dll details

* Minor cleanup

* Improve resizing

* Add some logs

* Test fix - release build

* Remove InvokeOnControlThread

* Test fix: logger initialization

* Fix arm64 installer

Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
This commit is contained in:
Stefan Markovic
2022-12-14 13:37:23 +01:00
committed by GitHub
parent a2c0febccc
commit 6ac508fb93
215 changed files with 9060 additions and 2328 deletions

View File

@@ -1,72 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.PreviewHandler.Monaco
{
using System;
using System.Runtime.InteropServices;
using Common;
/// <summary>
/// Implementation of preview handler for files with source code.
/// </summary>
[Guid("afbd5a44-2520-4ae0-9224-6cfce8fe4400")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class MonacoPreviewHandler : FileBasedPreviewHandler, IDisposable
{
private MonacoPreviewHandlerControl _monacoPreviewHandlerControl;
private bool _disposedValue;
/// <summary>
/// Initializes a new instance of the <see cref="MonacoPreviewHandler"/> class.
/// </summary>
public MonacoPreviewHandler()
{
this.Initialize();
}
/// <inheritdoc />
[STAThread]
public override void DoPreview()
{
_monacoPreviewHandlerControl.DoPreview(FilePath);
}
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
_monacoPreviewHandlerControl = new MonacoPreviewHandlerControl();
return _monacoPreviewHandlerControl;
}
/// <summary>
/// Disposes objects
/// </summary>
/// <param name="disposing">Is Disposing</param>
[STAThread]
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
_monacoPreviewHandlerControl.Dispose();
}
_disposedValue = true;
this.Unload();
}
}
/// <inheritdoc />
[STAThread]
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -1,5 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<AssemblyTitle>PowerToys.MonacoPreviewHandler</AssemblyTitle>
<AssemblyDescription>PowerToys MonacoPreviewHandler</AssemblyDescription>
<Description>PowerToys MonacoPreviewHandler</Description>
@@ -9,14 +11,22 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<RuntimeIdentifiers>win10-x64;win10-arm64</RuntimeIdentifiers>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Monaco</RootNamespace>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<EnableComHosting>true</EnableComHosting>
<AssemblyName>PowerToys.MonacoPreviewHandler</AssemblyName>
</PropertyGroup>
@@ -35,6 +45,7 @@
<PropertyGroup>
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
<NoWarn>$(NoWarn);1591</NoWarn>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>

View File

@@ -107,13 +107,10 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMonacoPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
{
// GPO is disabling this utility. Show an error message instead.
InvokeOnControlThread(() =>
{
_infoBarAdded = true;
AddTextBoxControl(Properties.Resources.GpoDisabledErrorText);
Resize += FormResized;
base.DoPreview(dataSource);
});
_infoBarAdded = true;
AddTextBoxControl(Properties.Resources.GpoDisabledErrorText);
Resize += FormResized;
base.DoPreview(dataSource);
return;
}
@@ -132,7 +129,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
// Checks if dataSource is a string
if (!(dataSource is string filePath))
{
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MonacoPreviewHandler)} must be a string but was a '{typeof(T)}'");
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MonacoPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
}
// Check if the file is too big.
@@ -145,103 +142,94 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
try
{
InvokeOnControlThread(() =>
Logger.LogInfo("Create WebView2 environment");
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
.CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
"\\AppData\\LocalLow\\Microsoft\\PowerToys\\MonacoPreview-Temp")
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(async () =>
{
Logger.LogInfo("Create WebView2 environment");
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
.CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
"\\AppData\\LocalLow\\Microsoft\\PowerToys\\MonacoPreview-Temp")
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(() =>
_loadingBar.Value = 60;
this.Update();
try
{
_loadingBar.Value = 60;
this.Update();
InvokeOnControlThread(async () =>
if (CoreWebView2Environment.GetAvailableBrowserVersionString() == null)
{
try
{
if (CoreWebView2Environment.GetAvailableBrowserVersionString() == null)
{
throw new WebView2RuntimeNotFoundException();
}
throw new WebView2RuntimeNotFoundException();
}
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
_loadingBar.Value = 70;
this.Update();
_loadingBar.Value = 70;
this.Update();
// Initialize WebView
try
{
await _webView.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
// Initialize WebView
try
{
await _webView.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
// Wait until html is loaded
initializeIndexFileAndSelectedFileTask.Wait();
// Wait until html is loaded
initializeIndexFileAndSelectedFileTask.Wait();
_webView.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, Settings.AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
_webView.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, Settings.AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
Logger.LogInfo("Navigates to string of HTML file");
Logger.LogInfo("Navigates to string of HTML file");
_webView.NavigateToString(_html);
_webView.NavigationCompleted += WebView2Init;
_webView.Height = this.Height;
_webView.Width = this.Width;
Controls.Add(_webView);
_webView.SendToBack();
_loadingBar.Value = 100;
this.Update();
}
catch (NullReferenceException e)
{
Logger.LogError("NullReferenceException catched. Skipping exception.", e);
}
}
catch (WebView2RuntimeNotFoundException e)
{
Logger.LogWarning("WebView2 was not found:");
Logger.LogWarning(e.Message);
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
_webView.NavigateToString(_html);
_webView.NavigationCompleted += WebView2Init;
_webView.Height = this.Height;
_webView.Width = this.Width;
Controls.Add(_webView);
_webView.SendToBack();
_loadingBar.Value = 100;
this.Update();
}
catch (NullReferenceException e)
{
Logger.LogError("NullReferenceException catched. Skipping exception.", e);
}
}
catch (WebView2RuntimeNotFoundException e)
{
Logger.LogWarning("WebView2 was not found:");
Logger.LogWarning(e.Message);
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
// WebView2 not installed message
Label errorMessage = new Label();
errorMessage.Text = Resources.WebView2_Not_Installed_Message;
errorMessage.Width = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Width + 10;
errorMessage.Height = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height;
Controls.Add(errorMessage);
// WebView2 not installed message
Label errorMessage = new Label();
errorMessage.Text = Resources.WebView2_Not_Installed_Message;
errorMessage.Width = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Width + 10;
errorMessage.Height = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height;
Controls.Add(errorMessage);
// Download Link
Label downloadLink = new LinkLabel();
downloadLink.Text = Resources.Download_WebView2;
downloadLink.Click += DownloadLink_Click;
downloadLink.Top = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height + 10;
downloadLink.Width = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Width + 10;
downloadLink.Height = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Height;
Controls.Add(downloadLink);
}
});
});
// Download Link
Label downloadLink = new LinkLabel();
downloadLink.Text = Resources.Download_WebView2;
downloadLink.Click += DownloadLink_Click;
downloadLink.Top = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height + 10;
downloadLink.Width = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Width + 10;
downloadLink.Height = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Height;
Controls.Add(downloadLink);
}
});
}
catch (Exception e)
{
InvokeOnControlThread(() =>
{
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label text = new Label();
text.Text = Resources.Exception_Occurred;
text.Text += e.Message;
text.Text += "\n" + e.Source;
text.Text += "\n" + e.StackTrace;
text.Width = 500;
text.Height = 10000;
Controls.Add(text);
Logger.LogError(e.Message);
});
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label text = new Label();
text.Text = Resources.Exception_Occurred;
text.Text += e.Message;
text.Text += "\n" + e.Source;
text.Text += "\n" + e.StackTrace;
text.Width = 500;
text.Height = 10000;
Controls.Add(text);
Logger.LogError(e.Message);
}
this.Resize += FormResize;
@@ -249,18 +237,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
else
{
Logger.LogInfo("File is too big to display. Showing error message");
InvokeOnControlThread(() =>
{
Controls.Remove(_loading);
_loadingBar.Dispose();
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label errorMessage = new Label();
errorMessage.Text = Resources.Max_File_Size_Error.Replace("%1", (_settings.MaxFileSize / 1000).ToString(CultureInfo.CurrentCulture), StringComparison.InvariantCulture);
errorMessage.Width = 500;
errorMessage.Height = 50;
Controls.Add(errorMessage);
});
Controls.Remove(_loading);
_loadingBar.Dispose();
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label errorMessage = new Label();
errorMessage.Text = Resources.Max_File_Size_Error.Replace("%1", (_settings.MaxFileSize / 1000).ToString(CultureInfo.CurrentCulture), StringComparison.InvariantCulture);
errorMessage.Width = 500;
errorMessage.Height = 50;
Controls.Add(errorMessage);
}
}
@@ -350,46 +336,41 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
private void SetBackground()
{
Logger.LogTrace();
InvokeOnControlThread(() =>
{
this.BackColor = Settings.BackgroundColor;
});
this.BackColor = Settings.BackgroundColor;
}
private void InitializeLoadingScreen()
{
Logger.LogTrace();
InvokeOnControlThread(() =>
{
_loadingBackground = new Label();
_loadingBackground.BackColor = Settings.BackgroundColor;
_loadingBackground.Width = this.Width;
_loadingBackground.Height = this.Height;
Controls.Add(_loadingBackground);
_loadingBackground.BringToFront();
_loadingBackground = new Label();
_loadingBackground.BackColor = Settings.BackgroundColor;
_loadingBackground.Width = this.Width;
_loadingBackground.Height = this.Height;
Controls.Add(_loadingBackground);
_loadingBackground.BringToFront();
_loadingBar = new ProgressBar();
_loadingBar.Width = this.Width - 10;
_loadingBar.Location = new Point(5, this.Height / 2);
_loadingBar.Maximum = 100;
_loadingBar.Value = 10;
Controls.Add(_loadingBar);
_loadingBar = new ProgressBar();
_loadingBar.Width = this.Width - 10;
_loadingBar.Location = new Point(5, this.Height / 2);
_loadingBar.Maximum = 100;
_loadingBar.Value = 10;
Controls.Add(_loadingBar);
_loading = new Label();
_loading.Text = Resources.Loading_Screen_Message;
_loading.Width = this.Width;
_loading.Height = 45;
_loading.Location = new Point(0, _loadingBar.Location.Y - _loading.Height);
_loading.TextAlign = ContentAlignment.TopCenter;
_loading.Font = new Font("MS Sans Serif", 16, FontStyle.Bold);
_loading.ForeColor = Settings.TextColor;
Controls.Add(_loading);
_loading = new Label();
_loading.Text = Resources.Loading_Screen_Message;
_loading.Width = this.Width;
_loading.Height = 45;
_loading.Location = new Point(0, _loadingBar.Location.Y - _loading.Height);
_loading.TextAlign = ContentAlignment.TopCenter;
_loading.Font = new Font("MS Sans Serif", 16, FontStyle.Bold);
_loading.ForeColor = Settings.TextColor;
Controls.Add(_loading);
_loading.BringToFront();
_loadingBar.BringToFront();
_loading.BringToFront();
_loadingBar.BringToFront();
this.Update();
this.Update();
});
Logger.LogInfo("Loading screen initialized");
}

View File

@@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.PreviewHandler.Monaco
{
using System.Globalization;
using System.Windows.Threading;
using Common.UI;
using interop;
internal static class Program
{
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
private static MonacoPreviewHandlerControl _previewHandlerControl;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
if (args != null)
{
if (args.Length == 6)
{
string filePath = args[0];
int hwnd = Convert.ToInt32(args[1], 16);
Rectangle s = default(Rectangle);
int left = Convert.ToInt32(args[2], 10);
int right = Convert.ToInt32(args[3], 10);
int top = Convert.ToInt32(args[4], 10);
int bottom = Convert.ToInt32(args[5], 10);
_previewHandlerControl = new MonacoPreviewHandlerControl();
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
_previewHandlerControl.DoPreview(filePath);
NativeEventWaiter.WaitForEventLoop(
Constants.DevFilesPreviewResizeEvent(),
() =>
{
Rectangle s = default(Rectangle);
_previewHandlerControl.SetRect(s);
},
Dispatcher.CurrentDispatcher,
_tokenSource.Token);
}
else
{
MessageBox.Show("Wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
}
}
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
Application.Run();
}
}
}

View File

@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview</PublishDir>
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>