【修改】新增mysql进程,默认空密码

This commit is contained in:
huababa1
2025-08-21 09:39:22 +08:00
parent c1bbd46a32
commit 19ecdde64d

View File

@@ -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. 启动临时 MySQLWinExe 不重定向输出)
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; // 没找到
}
}