Skip to content

Commit

Permalink
将启动相关的代码抽离拆分到 WPF 项目中
Browse files Browse the repository at this point in the history
  • Loading branch information
walterlv committed Oct 11, 2020
1 parent 1c0dd8a commit aab80cc
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/磁贴美化小工具.Wpf/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<!-- .NET Framework 版本在 .NET Framework 4.6.2 以下,
但操作系统在 Windows 10 及以上,开启多屏不同 DPI 缩放。
详见:https://blog.walterlv.com/post/windows-high-dpi-development-for-wpf.html -->
<AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false" />
</runtime>
</configuration>
73 changes: 73 additions & 0 deletions src/磁贴美化小工具.Wpf/App.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。n
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此
元素。
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素,
Windows 将自动选择最兼容的环境。 -->

<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->

<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->

<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->

<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

</application>
</compatibility>


<!-- 以下 DPI 配置包含两种效果:
1. 针对每个屏幕的 DPI 缩放(第二版),在 Windows 10 1607 及以上
2. 仅系统级缩放,在 Windows 10 1607 以下
详见:https://blog.walterlv.com/post/windows-high-dpi-development-for-wpf.html-->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>

<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>

</assembly>
11 changes: 11 additions & 0 deletions src/磁贴美化小工具.Wpf/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,16 @@ namespace Xiu2.TileTool
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

// 判断系统版本
if (Environment.OSVersion.Version.Major != 10)
{
_ = MessageBox.Show($"{AppInfo.Main.AppName}仅支持 Windows10 系统!", "错误", MessageBoxButton.OK);
Shutdown();
}
}
}
}
34 changes: 34 additions & 0 deletions src/磁贴美化小工具.Wpf/AppInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Xiu2.TileTool
{
/// <summary>
/// 包含应用程序的一般信息。
/// </summary>
internal class AppInfo
{
/// <summary>
/// 获取当前应用程序的一般信息。
/// </summary>
public static AppInfo Main { get; } = new AppInfo(Assembly.GetEntryAssembly()!);

public AppInfo(Assembly assembly)
{
AppName = assembly.GetCustomAttribute<AssemblyTitleAttribute>()!.Title;
Version = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!.InformationalVersion;
}

/// <summary>
/// 获取应用名称。
/// </summary>
public string AppName { get; }

/// <summary>
/// 获取版本号(可能带预览标签)。
/// </summary>
public string Version { get; }
}
}
2 changes: 1 addition & 1 deletion src/磁贴美化小工具.Wpf/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Xiu2.TileTool"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
Height="450" Width="800">
<Grid>

</Grid>
Expand Down
4 changes: 4 additions & 0 deletions src/磁贴美化小工具.Wpf/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
Expand All @@ -20,6 +21,9 @@ public partial class MainWindow : Window
public MainWindow()
{
InitializeComponent();

// 初始化动态的界面项。
Title = $"{AppInfo.Main.AppName} v{AppInfo.Main.Version}";
}
}
}
83 changes: 83 additions & 0 deletions src/磁贴美化小工具.Wpf/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace Xiu2.TileTool
{
internal static class Program
{
[STAThread]
static void Main(string[] args)
{
// 启动前一个进程实例。
Mutex? newMutex = null;
try
{
#pragma warning disable IDE0067 // 丢失范围之前释放对象
newMutex = new Mutex(true, "a8851f5e-cbb5-4466-bd72-d95c9bea4dea", out bool createdNew);
#pragma warning restore IDE0067 // 丢失范围之前释放对象
if (!createdNew)
{
if (args.Length > 0 && args[0] != "")
{
// 右键菜单启动:杀掉已存在的进程。
KillSameNameProcess();
}
else
{
// 用户双击启动,打开之前已打开的窗口。
var current = Process.GetCurrentProcess();
var process = Process.GetProcessesByName(current.ProcessName).FirstOrDefault(x => x.Id != current.Id);
if (process != null)
{
var hwnd = process.MainWindowHandle;
ShowWindow(hwnd, 9);
SetForegroundWindow(hwnd);
return;
}
}
}
}
catch (Exception)
{
// 忽略任何多实例处理相关的异常。
}

// 启动自己。
var app = new App();
app.InitializeComponent();
app.Run();
}

/// <summary>
/// 结束同名进程。
/// </summary>
private static void KillSameNameProcess()
{
// 获取当前进程信息。
Process currentProcess = Process.GetCurrentProcess();
// 获取同名进程信息。
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
// 判断该进程主窗口标题是否含有 XXX 字符串。
if (process.MainWindowTitle.Contains("磁贴美化小工具 v"))
{
// 如果不是当前进程,就结束它。
if (process.Id != currentProcess.Id)
{
process.Kill();
}
}
}
}

[DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr hwnd, uint nCmdShow);

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<RootNamespace>Xiu2.TileTool</RootNamespace>
<Version>4.2.0-alpha01</Version>
<StartupObject>Xiu2.TileTool.Program</StartupObject>
<AssemblyName>磁贴美化小工具</AssemblyName>
<ApplicationManifest>App.manifest</ApplicationManifest>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Walterlv.Themes.FluentDesign.Source" Version="5.9.0" PrivateAssets="all" />
</ItemGroup>

</Project>

0 comments on commit aab80cc

Please sign in to comment.