mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-23 01:59:32 +08:00
277 lines
10 KiB
C#
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
|
|
}
|
|
} |