Compare commits

...

14 Commits

Author SHA1 Message Date
jiangqun.chen
3e617309f7 增加日志,完善逻辑 2026-07-06 16:05:44 +08:00
jiangqun.chen
5b8e9d1a19 修改中文提示 2026-07-03 09:49:53 +08:00
jiangqun.chen
49939dc14c 在增加校验进度 2026-07-02 16:53:17 +08:00
jiangqun.chen
b9e6db147c 去掉没必要的重复内容 2026-07-02 16:47:16 +08:00
chenjiangqun
718cec11a5 加载增加进度条 2026-07-02 15:17:21 +08:00
chenjiangqun
959b4232aa 优化代码 2026-07-02 11:52:53 +08:00
chenjiangqun
40dce42fd7 完善A卡读取不稳问题 2026-07-02 10:58:46 +08:00
chenjiangqun
65a3117d10 修复N卡DDC通道限制导致不能识别超过15字节,导致可能漏判问题 2026-07-01 18:58:36 +08:00
chenjiangqun
fc09f64873 增加日志 2026-07-01 14:12:23 +08:00
chenjiangqun
bb0706e7b7 修复AMD显卡正常时不能升级问题 2026-06-30 20:13:14 +08:00
chenjiangqun
370ab2ea7c 加强一部分逻辑 2026-06-30 18:59:22 +08:00
chenjiangqun
6042411a01 增加指令打印日志 2026-06-30 18:56:58 +08:00
chenjiangqun
32409ebe2b 加 GPU 信息快照日志 2026-06-29 10:55:05 +08:00
chenjiangqun
6d31ffc78d 增加日志 2026-06-29 10:50:43 +08:00
4 changed files with 1099 additions and 450 deletions

View File

@@ -144,15 +144,165 @@ namespace WinISP.BaseClass
}
}
private readonly object _graphicsCardLock = new object();
private volatile bool _isDisposing = false;
private void FreeGraphicsCardCtrl()
{
// Free the GCHandle.
frmISP.WriteLog("Free the GCHandle.", "debug");
if (gch.IsAllocated)
gch.Free();
DisposeGraphicCardCtrl();
pGraphicCardCtrl = IntPtr.Zero;
_IsInit = false;
lock (_graphicsCardLock)
{
// 防止重复释放
if (_isDisposing)
{
frmISP.WriteLog("Graphics card control is already being disposed, skipping.", "warn");
return;
}
if (!_IsInit)
{
frmISP.WriteLog("Graphics card control is not initialized, nothing to free.", "debug");
return;
}
_isDisposing = true;
try
{
// 第一步:释放 GCHandle
FreeGCHandle();
// 第二步:释放图形卡控制资源
DisposeGraphicsCardControl();
// 第三步:清空指针
pGraphicCardCtrl = IntPtr.Zero;
// 第四步:更新状态
_IsInit = false;
frmISP.WriteLog("Graphics card control freed successfully.", "info");
}
catch (Exception ex)
{
frmISP.WriteLog($"Error freeing graphics card control: {ex.GetType().Name} - {ex.Message}", "error");
// 即使出错也要尝试清理状态
try
{
pGraphicCardCtrl = IntPtr.Zero;
_IsInit = false;
}
catch (Exception cleanupEx)
{
frmISP.WriteLog($"Error during cleanup after exception: {cleanupEx.Message}", "error");
}
}
finally
{
_isDisposing = false;
}
}
}
/// <summary>
/// 安全释放 GCHandle
/// </summary>
private void FreeGCHandle()
{
try
{
if (gch.IsAllocated)
{
frmISP.WriteLog("Freeing GCHandle...", "debug");
gch.Free();
frmISP.WriteLog("GCHandle freed successfully.", "debug");
}
else
{
frmISP.WriteLog("GCHandle is not allocated, skipping free operation.", "debug");
}
}
catch (InvalidOperationException ex)
{
frmISP.WriteLog($"InvalidOperationException when freeing GCHandle: {ex.Message}", "warn");
}
catch (Exception ex)
{
frmISP.WriteLog($"Unexpected exception when freeing GCHandle: {ex.GetType().Name} - {ex.Message}", "error");
}
}
/// <summary>
/// 安全释放图形卡控制资源
/// </summary>
private void DisposeGraphicsCardControl()
{
try
{
if (pGraphicCardCtrl != IntPtr.Zero)
{
frmISP.WriteLog("Disposing graphics card control...", "debug");
DisposeGraphicCardCtrl();
frmISP.WriteLog("Graphics card control disposed successfully.", "debug");
}
else
{
frmISP.WriteLog("Graphics card control pointer is null, skipping dispose.", "debug");
}
}
catch (AccessViolationException ex)
{
frmISP.WriteLog($"AccessViolationException when disposing graphics card control: {ex.Message}", "error");
}
catch (ObjectDisposedException ex)
{
frmISP.WriteLog($"ObjectDisposedException when disposing graphics card control: {ex.Message}", "warn");
}
catch (Exception ex)
{
frmISP.WriteLog($"Unexpected exception when disposing graphics card control: {ex.GetType().Name} - {ex.Message}", "error");
}
}
/// <summary>
/// 验证图形卡控制是否已正确释放
/// </summary>
public bool IsGraphicsCardControlFreed()
{
lock (_graphicsCardLock)
{
return !_IsInit && pGraphicCardCtrl == IntPtr.Zero && !gch.IsAllocated;
}
}
/// <summary>
/// 强制清理(用于异常恢复)
/// </summary>
public void ForceCleanupGraphicsCardCtrl()
{
lock (_graphicsCardLock)
{
try
{
frmISP.WriteLog("Performing force cleanup of graphics card control...", "warn");
// 强制释放 GCHandle
if (gch.IsAllocated)
{
try { gch.Free(); }
catch { }
}
// 强制清空指针
pGraphicCardCtrl = IntPtr.Zero;
_IsInit = false;
frmISP.WriteLog("Force cleanup completed.", "info");
}
catch (Exception ex)
{
frmISP.WriteLog($"Error during force cleanup: {ex.Message}", "error");
}
}
}
public GraphicCardI2CCtrl()
@@ -254,27 +404,24 @@ namespace WinISP.BaseClass
Byte slvAddr = data[0];
Byte[] wrBuf = new Byte[data.Length - 1];
Array.Copy(data, 1, wrBuf, 0, wrBuf.Length);
const Byte maxWrLen = 16;
int idx = 0;
unsafe
{
fixed (Byte* pArr = wrBuf)
{
return DDCWrite(pGraphicCardCtrl, slvAddr, (uint)(wrBuf.Length), wrBuf);
}
}
bool ret = DDCWrite(pGraphicCardCtrl, slvAddr, (uint)wrBuf.Length, wrBuf);
frmISP.WriteLog($"[DDCWrite] card={GraphicCardType} slv=0x{slvAddr:X2} len={wrBuf.Length} ret={ret}", ret ? "debug" : "error");
return ret;
}
public bool ReadData(byte[] data, byte[] wrCmds = null)
{
uint revlen = (uint)data.Length;
unsafe
if (wrCmds == null || wrCmds.Length == 0)
{
fixed (Byte* pArr = data)
{
return DDCRead(pGraphicCardCtrl, wrCmds[0], revlen, data);
}
frmISP.WriteLog($"[DDCRead] card={GraphicCardType} wrCmds is NULL/empty!", "error");
return false;
}
uint revlen = (uint)data.Length;
bool ret = DDCRead(pGraphicCardCtrl, wrCmds[0], revlen, data);
frmISP.WriteLog($"[DDCRead] card={GraphicCardType} slv=0x{wrCmds[0]:X2} rdLen={revlen} ret={ret} " +
$"first4={(data.Length >= 4 ? BitConverter.ToString(data, 0, 4) : "n/a")}", ret ? "debug" : "error");
return ret;
}
public bool Init()

View File

@@ -1,4 +1,6 @@
using System;
using System.Linq;
using WinISP;
namespace MTK
{
@@ -72,6 +74,12 @@ namespace MTK
strData = "";
if (_i2cCtrl.ReadData(recvBuf, wrCmds) == true)
{
frmISP.WriteLog(
$"[DDC_Read RAW] cmd=0x{data[1]:X2} recvLen={recvLen} " +
$"raw=[{string.Join(" ", recvBuf.Select(b => b.ToString("X2")))}]",
"debug");
// ────────
for (int i = 0; i < recvBuf.Length; ++i)
strData += recvBuf[i].ToString("X2") + " ";
@@ -102,6 +110,29 @@ namespace MTK
return null;
}
/// <summary>
/// 从 DDC 0x6F 继续读取数据(不重新发送命令)。
/// 用于 N卡 DP AUX 通道 16 字节限制导致截断时的分段续读。
/// 在 DDC_Read 成功返回后立即调用,尝试读取响应缓冲区中尚未消费的剩余字节。
/// </summary>
/// <param name="recvLen">要读取的字节数</param>
/// <returns>读取到的字节数组,失败返回 null</returns>
public static Byte[] DDC_ReadContinue(int recvLen)
{
const Byte dest = 0x6F;
Byte[] wrCmds = { dest };
Byte[] recvBuf = new Byte[recvLen];
if (_i2cCtrl.ReadData(recvBuf, wrCmds))
{
frmISP.WriteLog(
$"[DDC_ReadContinue] rdLen={recvLen} raw=[{string.Join(" ", recvBuf.Select(b => b.ToString("X2")))}]",
"debug");
return recvBuf;
}
frmISP.WriteLog($"[DDC_ReadContinue] rdLen={recvLen} read failed", "debug");
return null;
}
private static Byte CalCheckSum(Byte[] data, int startIdx = 0)
{
Byte chkSum = 0;

File diff suppressed because it is too large Load Diff

View File

@@ -1859,21 +1859,38 @@ namespace WinISP
private static string resultFolder = System.IO.Directory.GetCurrentDirectory() + "\\";
private static System.IO.StreamWriter _logWriter = null;
private static string _logPath = null;
private static readonly object _logLock = new object();
[Conditional("DEBUG")]
public static void WriteLog(string str, string fileName)
public static void WriteLog(string str, string level)
{
if (!System.IO.Directory.Exists(resultFolder))
System.IO.Directory.CreateDirectory(resultFolder);
string path = resultFolder + (fileName == "" ? "" : fileName + "_") + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
if (_logWriter == null || _logPath != path)
try
{
if (_logWriter != null) { _logWriter.Flush(); _logWriter.Close(); }
_logPath = path;
_logWriter = new System.IO.StreamWriter(path, append: true);
if (!System.IO.Directory.Exists(resultFolder))
System.IO.Directory.CreateDirectory(resultFolder);
string path = resultFolder + (level == "" ? "" : level + "_") + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
lock (_logLock) // >>> 新增:同进程内串行化,避免自家多线程争用
{
if (_logWriter == null || _logPath != path)
{
if (_logWriter != null)
{
try { _logWriter.Flush(); _logWriter.Close(); } catch { }
}
_logPath = path;
var stream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
_logWriter = new System.IO.StreamWriter(stream);
}
_logWriter.WriteLine(DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss.fff: ") + str);
_logWriter.Flush();
}
}
catch (Exception) // >>> 改动IOException → Exception吞掉一切日志异常
{
// 日志写入失败绝不能影响主流程。可选:降级写到 Debug 输出
try { System.Diagnostics.Debug.WriteLine("[LOG-FALLBACK] " + str); } catch { }
}
_logWriter.WriteLine(DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss.fff: ") + str);
_logWriter.Flush();
}
private void cboConnectedMonitor_SelectedIndexChanged(object sender, EventArgs e)