Files
SteamTools/System.Application.SteamTools.Tools.Win7Troubleshoot/Program.cs
T
2021-03-01 21:41:32 +08:00

277 lines
10 KiB
C#

/* 适用于 Windwos 7 OS 的 疑难解答助手
* 主要逻辑:if 安装了补丁 KB3063858
* 直接运行主程序
* else 本地化文本提示未安装补丁,引导用户进行下载
* 例如:输入 y 跳转微软官方下载中心下载补丁安装后再使用本应用程序,输入 n 退出
* Win7 自带 net35 可能魔改版删除了此功能,那就没办法了
* 可在 控制面板\程序\程序和功能 - 打开或关闭 Windows 功能 - Microsoft .NET Framework 3.5.1 根据左边的勾选框,非空心即代表已安装
* 对于本程序
* 在配置文件 exe.config supportedRuntime 项中可添加net4x的支持
*/
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Properties;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows.Forms;
[assembly: AssemblyTitle(ThisAssembly.AssemblyTrademark + " v" + ThisAssembly.Version)]
namespace System
{
static class Program
{
internal static Mutex? mutex;
static readonly Process currentProcess = Process.GetCurrentProcess();
static string thisFilePath = "";
static string appFilePath = "";
[STAThread]
static void Main(string[] args)
{
mutex = new Mutex(true, currentProcess.ProcessName, out var isNotRunning);
if (isNotRunning)
{
try
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
throw new PlatformNotSupportedException();
thisFilePath = currentProcess.MainModule.FileName;
appFilePath = thisFilePath.Replace(".win7", string.Empty, StringComparison.OrdinalIgnoreCase);
var isQuickStart = QuickStart(out var writeQuickStart);
if (!isQuickStart)
{
var r = IsWin7SP1OrNotSupportedPlatform(out var error);
if (r.HasValue)
{
if (r.Value) // Win7SP1
{
if (!CheckInstalled_KB3063858())
{
if (MessageBox.Show(
SR.Not_Installed_KB3063858,
SR.Error,
MessageBoxButtons.YesNo,
MessageBoxIcon.Error) == DialogResult.Yes)
{
Open_KB3063858_DownloadLink();
}
return;
}
}
else // NotSupportedPlatform - For example, WinXP/Win2000
{
MessageBox.Show(
error,
SR.Error,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
}
writeQuickStart?.Invoke();
}
AppRun();
}
catch (Exception e)
{
MessageBox.Show(
e.ToString(),
SR.Error,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
/// <summary>
/// 在浏览器中打开补丁KB3063858的下载地址
/// </summary>
static void Open_KB3063858_DownloadLink()
{
var downloadLink = EnvironmentEx.Is64BitOperatingSystem ?
DownloadLinks.KB3063858_x64 : DownloadLinks.KB3063858_x86;
downloadLink = string.Format(downloadLink, CultureInfo.CurrentCulture.Name);
Process.Start(downloadLink);
}
/// <summary>
/// 检查是否安装了补丁KB3063858
/// </summary>
/// <returns></returns>
static bool CheckInstalled_KB3063858()
{
const string KB3063858 = "KB3063858";
using var p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.WriteLine("wmic qfe&exit");
p.StandardInput.AutoFlush = true;
var str = p.StandardOutput.ReadToEnd();
p.WaitForExit();
return str.Contains(KB3063858);
}
/// <summary>
/// 启动主APP
/// </summary>
static void AppRun()
{
if (string.IsNullOrEmpty(appFilePath) || !File.Exists(appFilePath)) return;
Process.Start(appFilePath);
}
/// <summary>
/// 返回结果:
/// <para><see langword="true"/> 当前运行的操作系统为 Win7SP1</para>
/// <para><see langword="false"/> 当前运行的操作系统不支持 </para>
/// <para><see langword="null"/> 当前运行的操作系统为Win8或更高</para>
/// </summary>
/// <param name="error"></param>
/// <returns></returns>
static bool? IsWin7SP1OrNotSupportedPlatform([NotNullWhen(false)] out string? error)
{
error = null;
if (Environment.OSVersion.Version.Major == 6)
{
if (Environment.OSVersion.Version.Minor == 1) // NT 6.1 / Win7 / WinServer 2008 R2
{
return Environment.OSVersion.ServicePack == "Service Pack 1";
}
else if (Environment.OSVersion.Version.Minor == 2) // NT 6.2 / Win8 / WinServer 2012
{
error = SR.NotSupportedWin8PlatformError;
return false;
}
else if (Environment.OSVersion.Version.Minor == 3) // NT 6.3 / Win8.1 / WinServer 2012 R2
{
}
else
{
throw new PlatformNotSupportedException();
}
}
else if (Environment.OSVersion.Version.Major < 6)
{
error = SR.NotSupportedPlatformError;
return false;
}
return null;
}
#region QuickStart
/* 快速启动功能
* MSI安装包生成的桌面快捷方式指向当前程序
* 在Win7上进行KB补丁检查或其他环境检查需要一定耗时
* 预期仅第一次运行检查,检测通过后后续运行不在检查
* 使用[计算机名+用户名+系统版本号]进行哈希计算得到的值作为标识
* 这样就算整个程序文件夹Copy另一台PC中,也会在第一次运行时重新检查
*/
const string QuickStartMarkFileName = "quick_start_id.txt";
static bool QuickStart(out Action? write)
{
try
{
var userDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var allDesktopPath = GetAllUsersDesktopFolderPath();
var desktopPaths = new[] { userDesktopPath, allDesktopPath };
if (desktopPaths.All(x => !File.Exists(Path.Combine(x, Path.GetFileNameWithoutExtension(appFilePath) + ".lnk"))))
{
throw new Exception("Shortcut does not exist.");
}
var machineName = Environment.MachineName;
var userName = Environment.UserName;
var osVersion = Environment.OSVersion.VersionString;
var hashValue = Hashs.String.SHA1(machineName + userName + osVersion);
var path = Path.Combine(Path.GetDirectoryName(thisFilePath), QuickStartMarkFileName);
write = () =>
{
try
{
if (File.Exists(path))
{
try
{
File.Delete(path);
}
catch
{
}
}
if (!File.Exists(path))
{
File.WriteAllText(path, hashValue);
}
}
catch
{
}
};
if (File.Exists(path))
{
var hashValueByRead = File.ReadAllText(path);
if (hashValueByRead == hashValue)
{
return true;
}
else
{
try
{
File.Delete(path);
}
catch
{
}
}
}
}
catch
{
write = null;
}
return false;
}
[DllImport("shfolder.dll", CharSet = CharSet.Auto)]
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath);
const int MAX_PATH = 260;
const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019;
static string GetAllUsersDesktopFolderPath()
{
var @string = new StringBuilder(MAX_PATH);
SHGetFolderPath(IntPtr.Zero, CSIDL_COMMON_DESKTOPDIRECTORY, IntPtr.Zero, 0, @string);
return @string.ToString();
}
#endregion
}
}