【修改】新增mysql进程,默认空密码
This commit is contained in:
@@ -2,24 +2,21 @@
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using Microsoft.Win32;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Security.Cryptography;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Xml.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
class Program
|
||||
{
|
||||
static ConcurrentDictionary<string, int> fileProcessMap = new(StringComparer.OrdinalIgnoreCase);
|
||||
//[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
HttpListener listener = new HttpListener();
|
||||
@@ -201,109 +198,177 @@ class Program
|
||||
{
|
||||
if (path == "navicat")
|
||||
{
|
||||
// 启动指定服务(MySQL 服务)//需要用管理员身份启动
|
||||
string serviceName = "wampmysqld"; // ← 请确认服务名
|
||||
try
|
||||
int port = 6033;
|
||||
|
||||
// 1. 自动搜索 MySQL bin 目录
|
||||
string[] possiblePaths = new string[]
|
||||
{
|
||||
using (var service = new ServiceController(serviceName))
|
||||
@"C:\Program Files\MySQL\MySQL Server 5.5\bin",
|
||||
@"C:\Program Files\MySQL\MySQL Server 5.6\bin",
|
||||
@"C:\Program Files\MySQL\MySQL Server 5.7\bin",
|
||||
@"C:\Program Files\MySQL\MySQL Server 8.0\bin",
|
||||
@"C:\Program Files\MySQL\MySQL Server 8.1\bin",
|
||||
@"C:\PROGRA~1\MySQL\MYSQLS~1.0\bin"
|
||||
};
|
||||
string mysqlBinDir = null;
|
||||
foreach (var patha in possiblePaths)
|
||||
{
|
||||
if (File.Exists(Path.Combine(patha, "mysqld.exe")))
|
||||
{
|
||||
if (service.Status != ServiceControllerStatus.Running && service.Status != ServiceControllerStatus.StartPending)
|
||||
{
|
||||
Console.WriteLine($"🟡 正在启动服务:{serviceName}...");
|
||||
service.Start();
|
||||
service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
|
||||
Console.WriteLine($"✅ 服务 {serviceName} 启动成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"✅ 服务 {serviceName} 已在运行中");
|
||||
}
|
||||
mysqlBinDir = patha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 启动服务失败:{ex.Message}");
|
||||
|
||||
if (mysqlBinDir == null) {
|
||||
mysqlBinDir = FindMySqlBin();
|
||||
if (mysqlBinDir == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 获取当前用户的 SID
|
||||
string userSid = WindowsIdentity.GetCurrent().User?.Value;
|
||||
if (userSid == null)
|
||||
|
||||
|
||||
// 2. 设置临时数据目录
|
||||
string tempData = @"C:\mysql_temp_data";
|
||||
string tempIni = @"C:\mysql_temp.ini";
|
||||
|
||||
int existingPid = GetProcessIdByPort(port);
|
||||
if (existingPid > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var conn = new MySqlConnection($"server=127.0.0.1;port={port};user=root;password=;Charset=utf8mb4;");
|
||||
conn.Open();
|
||||
Console.WriteLine("已有 MySQL 正在运行,直接使用它");
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Directory.Exists(tempData))
|
||||
Directory.Delete(tempData, true);
|
||||
Directory.CreateDirectory(tempData);
|
||||
// 3. 生成临时 my.ini
|
||||
using (StreamWriter writer = new StreamWriter(tempIni))
|
||||
{
|
||||
writer.WriteLine("[mysqld]");
|
||||
writer.WriteLine($"datadir={tempData}");
|
||||
writer.WriteLine($"port={port}");
|
||||
writer.WriteLine("skip-networking=0");
|
||||
writer.WriteLine("skip-grant-tables=0");
|
||||
writer.WriteLine($"log-error={tempData}\\mysql.err");
|
||||
}
|
||||
// 4. 初始化临时数据库
|
||||
if (!RunProcess(Path.Combine(mysqlBinDir, "mysqld.exe"), $"--defaults-file=\"{tempIni}\" --initialize-insecure"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("已有 MySQL 正在运行,直接使用它");
|
||||
// 5. 启动临时 MySQL(WinExe 不重定向输出)
|
||||
Process mysqlProcess = new Process();
|
||||
mysqlProcess.StartInfo.FileName = Path.Combine(mysqlBinDir, "mysqld.exe");
|
||||
mysqlProcess.StartInfo.Arguments = $"--defaults-file=\"{tempIni}\" --standalone --port={port}";
|
||||
mysqlProcess.StartInfo.UseShellExecute = false;
|
||||
mysqlProcess.StartInfo.CreateNoWindow = true;
|
||||
mysqlProcess.StartInfo.RedirectStandardOutput = true;
|
||||
mysqlProcess.StartInfo.RedirectStandardError = true;
|
||||
|
||||
mysqlProcess.Start();
|
||||
|
||||
mysqlProcess.BeginOutputReadLine();
|
||||
mysqlProcess.BeginErrorReadLine();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 6. 等待 MySQL 可连接(最长等待 30 秒)
|
||||
string connStr = $"server=127.0.0.1;port={port};user=root;password=;Charset=utf8mb4;";
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
bool started = false;
|
||||
while (sw.ElapsedMilliseconds < 30000)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var conn = new MySql.Data.MySqlClient.MySqlConnection(connStr);
|
||||
conn.Open();
|
||||
started = true;
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
if (!started)
|
||||
{
|
||||
Console.WriteLine("❌ 无法获取当前用户 SID");
|
||||
return;
|
||||
}
|
||||
string subKeyPath = $@"{userSid}\Software\PremiumSoft\Navicat\Servers\答题专用";
|
||||
Console.WriteLine("当前用户 subKeyPath" + subKeyPath);
|
||||
|
||||
|
||||
|
||||
|
||||
// 7 写入 Navicat 注册表
|
||||
try
|
||||
{
|
||||
// 打开HKEY_USERS根键
|
||||
using (RegistryKey baseKey = Registry.Users)
|
||||
string userSid = WindowsIdentity.GetCurrent().User?.Value;
|
||||
if (userSid != null)
|
||||
{
|
||||
// 创建或打开子项,写权限需要true
|
||||
using (RegistryKey key = baseKey.CreateSubKey(subKeyPath, true))
|
||||
string subKeyPath = $@"{userSid}\Software\PremiumSoft\Navicat\Servers\答题专用";
|
||||
using (var baseKey = Registry.Users)
|
||||
using (var key = baseKey.CreateSubKey(subKeyPath, true))
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
Console.WriteLine("❌ 无法创建或打开注册表项");
|
||||
return;
|
||||
}
|
||||
|
||||
// 写入键值示例
|
||||
key.SetValue("Host", "localhost");
|
||||
key.SetValue("Port", 6033, RegistryValueKind.DWord);
|
||||
key.SetValue("Host", "127.0.0.1");
|
||||
key.SetValue("Port", port, RegistryValueKind.DWord);
|
||||
key.SetValue("User", "root");
|
||||
key.SetValue("Password", ""); // 注意密码如果要存可能是加密的
|
||||
// 其他必要键值写入
|
||||
Console.WriteLine("✅ 注册表写入成功");
|
||||
key.SetValue("Password", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 写入注册表失败:{ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
// 执行数据库创建与初始化
|
||||
string connectionString = "server=localhost;port=6033;user=root;password=;charset=utf8mb4;";
|
||||
|
||||
// 8 创建数据库 + 执行 SQL
|
||||
try
|
||||
{
|
||||
using (var connection = new MySqlConnection(connectionString))
|
||||
using (var conn = new MySqlConnection(connStr))
|
||||
{
|
||||
connection.Open();
|
||||
var createDbCmd = connection.CreateCommand();
|
||||
createDbCmd.CommandText = $"CREATE DATABASE IF NOT EXISTS `{dbName}` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;";
|
||||
createDbCmd.ExecuteNonQuery();
|
||||
Console.WriteLine($"✅ 数据库 {dbName} 创建成功");
|
||||
conn.Open();
|
||||
var cmd = conn.CreateCommand();
|
||||
cmd.CommandText = $"CREATE DATABASE IF NOT EXISTS `{dbName}` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
string sqlScript = File.ReadAllText(filepath);
|
||||
|
||||
using (var dbConn = new MySqlConnection(connectionString + $"database={dbName};"))
|
||||
using (var dbConn = new MySqlConnection(connStr + $"database={dbName};"))
|
||||
{
|
||||
dbConn.Open();
|
||||
|
||||
var sqlStatements = SplitSqlStatements(sqlScript);
|
||||
|
||||
foreach (var statement in sqlStatements)
|
||||
foreach (var stmt in sqlStatements)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(statement)) continue;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(stmt)) continue;
|
||||
using var cmd = dbConn.CreateCommand();
|
||||
cmd.CommandText = statement.Trim();
|
||||
cmd.CommandText = stmt.Trim();
|
||||
cmd.ExecuteNonQuery();
|
||||
Console.WriteLine($"执行成功:{Truncate(statement, 80)}");
|
||||
}
|
||||
|
||||
Console.WriteLine("✅ 所有 SQL 语句执行完成,数据库初始化成功");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 出错了:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string? resolvedPath = ResolveAppPath(path);
|
||||
@@ -740,7 +805,8 @@ class Program
|
||||
if (filePath.Contains("zip"))
|
||||
{
|
||||
return true;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -765,7 +831,149 @@ class Program
|
||||
public T? data { get; set; } // 实际数据内容
|
||||
public string msg { get; set; } = ""; // 消息提示
|
||||
}
|
||||
// 等待 MySQL 可连接
|
||||
public static bool WaitForMySql(string connStr, int timeoutSeconds)
|
||||
{
|
||||
var start = DateTime.Now;
|
||||
while ((DateTime.Now - start).TotalSeconds < timeoutSeconds)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var conn = new MySqlConnection(connStr);
|
||||
conn.Open();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool RunProcess(string fileName, string arguments, string logFile = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process proc = new Process();
|
||||
proc.StartInfo.FileName = fileName;
|
||||
proc.StartInfo.Arguments = arguments;
|
||||
proc.StartInfo.UseShellExecute = false;
|
||||
proc.StartInfo.RedirectStandardOutput = true;
|
||||
proc.StartInfo.RedirectStandardError = true;
|
||||
|
||||
using (StreamWriter sw = logFile != null ? new StreamWriter(logFile, true) : null)
|
||||
{
|
||||
proc.OutputDataReceived += (s, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data) && sw != null)
|
||||
sw.WriteLine("[OUT] " + e.Data);
|
||||
};
|
||||
proc.ErrorDataReceived += (s, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data) && sw != null)
|
||||
sw.WriteLine("[ERR] " + e.Data);
|
||||
};
|
||||
|
||||
proc.Start();
|
||||
proc.BeginOutputReadLine();
|
||||
proc.BeginErrorReadLine();
|
||||
|
||||
proc.WaitForExit();
|
||||
return proc.ExitCode == 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (logFile != null)
|
||||
File.AppendAllText(logFile, "RunProcess Exception: " + ex + Environment.NewLine);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 以管理员身份结束进程
|
||||
static void KillProcessByPid(int pid)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = "cmd.exe";
|
||||
p.StartInfo.Arguments = $"/c taskkill /PID {pid} /F";
|
||||
p.StartInfo.Verb = "runas"; // 请求管理员权限
|
||||
p.StartInfo.UseShellExecute = true;
|
||||
p.Start();
|
||||
p.WaitForExit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static int GetProcessIdByPort(int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用 netstat 命令获取端口占用
|
||||
Process netstat = new Process();
|
||||
netstat.StartInfo.FileName = "netstat.exe";
|
||||
netstat.StartInfo.Arguments = "-aon";
|
||||
netstat.StartInfo.UseShellExecute = false;
|
||||
netstat.StartInfo.RedirectStandardOutput = true;
|
||||
netstat.StartInfo.CreateNoWindow = true;
|
||||
|
||||
netstat.Start();
|
||||
string output = netstat.StandardOutput.ReadToEnd();
|
||||
netstat.WaitForExit();
|
||||
|
||||
// 正则匹配端口对应 PID
|
||||
string pattern = $@"\s+TCP\s+\S+:{port}\s+\S+\s+LISTENING\s+(\d+)";
|
||||
var match = Regex.Match(output, pattern);
|
||||
if (match.Success && int.TryParse(match.Groups[1].Value, out int pid))
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 出错返回 0
|
||||
}
|
||||
return 0; // 未找到占用
|
||||
}
|
||||
static string FindMySqlBin()
|
||||
{
|
||||
string[] roots = new string[]
|
||||
{
|
||||
@"C:\Program Files\MySQL",
|
||||
@"C:\Program Files (x86)\MySQL",
|
||||
@"D:\Program Files\MySQL",
|
||||
@"D:\Program Files (x86)\MySQL",
|
||||
@"D:\MySQL"
|
||||
};
|
||||
|
||||
foreach (var root in roots)
|
||||
{
|
||||
if (!Directory.Exists(root)) continue;
|
||||
|
||||
try
|
||||
{
|
||||
var dirs = Directory.GetDirectories(root, "*", SearchOption.AllDirectories);
|
||||
foreach (var dir in dirs)
|
||||
{
|
||||
string mysqldPath = Path.Combine(dir, "mysqld.exe");
|
||||
if (File.Exists(mysqldPath))
|
||||
{
|
||||
return dir; // 找到 mysqld.exe 返回目录
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 访问被拒绝等异常直接忽略
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return null; // 没找到
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user