sunhonglei 5 months ago
commit 41ea1c74f2
  1. 173
      Model/Services/AlgorithmServer.cs
  2. 4
      SparkClient.sln.DotSettings.user
  3. 16
      Views/Dialog/MessageBox.xaml.cs

@ -8,6 +8,9 @@ using Newtonsoft.Json.Linq;
using SparkClient.Model.Entity.ApiEntity;
using SparkClient.Model.Helper;
using System.Configuration;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using SparkClient.Model.Common;
namespace SparkClient.Model.Services
@ -24,7 +27,7 @@ namespace SparkClient.Model.Services
// 添加公共方法
public AlgorithmResultEntity CallParseJsonAndReturnActions(string shape, string shape_mode, string image_files)
{
{
try
{
//半圆
@ -33,18 +36,23 @@ namespace SparkClient.Model.Services
object halfCircleValue = circleTable.Rows[0][0];
bool.TryParse(halfCircleValue.ToString(), out bool boolResult);
bool half_circle = boolResult;
//算法配置参数
string sql = $"SELECT JSON FROM ALGORITHM_CONFIG ORDER BY JSON_ORDER ASC";
DataTable table = DataBaseHelper.ExecuteQuery(sql);
object lightLevelValue = table.Rows[0][0];
string algo_config = lightLevelValue.ToString() ?? throw new InvalidOperationException();
//图片根目录
string? image_file_base_path = ConfigurationManager.AppSettings["ImageFileBasePath"];
if (string.IsNullOrEmpty(image_file_base_path))
{
throw new InvalidOperationException("ImageFileBasePath is not configured in AppSettings.");
}
// 获取 log4net 日志文件所在的目录
string? log4NetLogDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string? log4NetLogDirectory =
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
// 构建C++ DLL 日志文件路径
string algorithm_log_path = Path.Combine(log4NetLogDirectory, "logs");
@ -55,51 +63,137 @@ namespace SparkClient.Model.Services
new JProperty("image_file_base_path", image_file_base_path),
new JProperty("image_files", JToken.Parse(image_files)),
new JProperty("half_circle", half_circle),
new JProperty("algorithm_log_path", algorithm_log_path),
new JProperty("algorithm_log_path", algorithm_log_path),
new JProperty("algo_config", JObject.Parse(algo_config))
);
string jsonDataString = jsonData.ToString();
// 调用 C++ DLL 函数解析 JSON
IntPtr resultPtr = DetectDiamond(jsonDataString);
string resultJson = Marshal.PtrToStringAnsi(resultPtr);
// 释放 DLL 分配的内存
FreeString(resultPtr);
// 检查返回的 JSON 字符串是否为空或无效
if (string.IsNullOrEmpty(resultJson))
string jsonDataString = jsonData.ToString().Replace("\"", "\\\"");
//string jsonDataString = jsonData.ToString();
// // 调用 C++ DLL 函数解析 JSON
// IntPtr resultPtr = DetectDiamond(jsonDataString);
// string resultJson = Marshal.PtrToStringAnsi(resultPtr);
// // 释放 DLL 分配的内存
// FreeString(resultPtr);
// // 检查返回的 JSON 字符串是否为空或无效
// if (string.IsNullOrEmpty(resultJson))
// {
// Logger.Error("Algorithm failed or no result returned.");
// // 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
// return new AlgorithmResultEntity
// {
// facets = new List<Facet>(),
// measurements = new Measurements()
// };
// }
// 启动隔离的控制台应用程序
var startInfo = new ProcessStartInfo
{
// 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
return new AlgorithmResultEntity
FileName = "AlgorithmDllIsolationConsoleApp.exe", // 控制台应用程序路径
Arguments = $"\"{jsonDataString}\"", // 将 JSON 数据作为参数传递给控制台应用程序
RedirectStandardOutput = true, // 获取控制台应用程序的输出
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = Process.Start(startInfo))
{
// 使用 StringBuilder 来捕获标准输出和标准错误
var outputBuilder = new StringBuilder();
var errorBuilder = new StringBuilder();
// 订阅标准输出事件
process.OutputDataReceived += (sender, e) =>
{
facets = new List<Facet>(),
measurements = new Measurements()
if (e.Data == null)
{
// 当 e.Data 为 null 时,表示读取完成
outputBuilder.AppendLine(e.Data);
Console.WriteLine($"Output: {e.Data}");
return;
}
// 将输出数据追加到 outputBuilder
outputBuilder.AppendLine(e.Data);
// 打印输出数据到控制台
Console.WriteLine($"Output: {e.Data}");
};
}
// 反序列化 JSON 字符串为 AlgorithmResultEntity 对象
var result = JsonConvert.DeserializeObject<AlgorithmResultEntity>(resultJson);
// 检查反序列化结果是否为 null
if (result == null)
{
// 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
return new AlgorithmResultEntity
// 订阅标准错误事件
process.ErrorDataReceived += (sender, e) =>
{
facets = new List<Facet>(),
measurements = new Measurements()
if (e.Data == null)
{
// 当 e.Data 为 null 时,表示读取完成
errorBuilder.AppendLine(e.Data);
Logger.Error($"Error Output: {e.Data}");
return;
}
// 将错误数据追加到 errorBuilder
errorBuilder.AppendLine(e.Data);
// 记录错误数据到日志
Logger.Error($"Error Output: {e.Data}");
};
// 开始异步读取
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// 等待控制台应用程序结束
process.WaitForExit();
// 等待异步读取完成
//Task.WaitAll(outputTcs.Task, errorTcs.Task);
// 获取结果
string resultJson = outputBuilder.ToString();
string errorOutput = errorBuilder.ToString();
// 如果控制台应用程序有错误输出
if (!string.IsNullOrEmpty(errorOutput))
{
Logger.Error($"Console App Error: {errorOutput}");
}
// 如果没有结果或失败
if (string.IsNullOrEmpty(resultJson))
{
Logger.Error("Algorithm failed or no result returned.");
return new AlgorithmResultEntity
{
facets = new List<Facet>(),
measurements = new Measurements()
};
}
// 反序列化 JSON 字符串为 AlgorithmResultEntity 对象
var result = JsonConvert.DeserializeObject<AlgorithmResultEntity>(resultJson);
// 检查反序列化结果是否为 null
if (result == null)
{
// 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
return new AlgorithmResultEntity
{
facets = new List<Facet>(),
measurements = new Measurements()
};
}
// 记录算法失败的状态
Logger.Info($"Algorithm failed with status: {result.status}");
// 记录算法失败的错误信息
Logger.Info($"Algorithm failed with errorMsg: {result.error_msg}");
// 处理 C++ DLL 日志文件
//ProcessDllLog();
// 算法调用失败时,保存图片到历史记录文件夹
// if (result.status == StatusCodes.AlgorithmFailed)
// {
// HandleAlgorithmFailure(image_files);
// }
return result;
}
// 记录算法失败的状态
Logger.Error($"Algorithm failed with status: {result.status}");
// 记录算法失败的错误信息
Logger.Error($"Algorithm failed with errorMsg: {result.error_msg}");
// 处理 C++ DLL 日志文件
//ProcessDllLog();
// 算法调用失败时,保存图片到历史记录文件夹
// if (result.status == StatusCodes.AlgorithmFailed)
// {
// HandleAlgorithmFailure(image_files);
// }
return result;
}
catch (Exception ex)
{
@ -112,6 +206,7 @@ namespace SparkClient.Model.Services
Logger.Error($"Inner Exception: {ex.InnerException.Message}");
Logger.Error($"Inner Stack Trace: {ex.InnerException.StackTrace}");
}
// 返回一个默认的 AlgorithmResultEntity 对象表示解析失败
return new AlgorithmResultEntity
{

@ -1,4 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAsyncStreamReader_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4a26a752ec6249c4a090905d31c0cdfa528a0_003F4d_003Fa3eda23d_003FAsyncStreamReader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAsyncStreamReader_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F5657934e169f1e03f1713934a999de82e80b02c892c78df9913e46e2e681e_003FAsyncStreamReader_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAsyncVoidMethodBuilder_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003F18_003Feb00c5a4_003FAsyncVoidMethodBuilder_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABaseUriHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbfd90ad81939493b96034353abcd1045825908_003Fdc_003Fff55e936_003FBaseUriHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABrushes_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F96a561fe76144633acef44f09d0dcb8a825920_003F7e_003F126cf976_003FBrushes_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@ -49,6 +51,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARuntimeType_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5147b10c5a8c4522b56fba0a889139cfc8f908_003F45_003F2a5f113e_003FRuntimeType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AScreenSpacedNode_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F68d37d16685244cf9996bf767117a771210200_003Ff9_003F61fd6f6c_003FScreenSpacedNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqliteCommand_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc7a59cb727594ed7a94648b2d66dbf702aa28_003F2f_003Fdc5f3094_003FSqliteCommand_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStaticResourceExtension_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6412d4331611499aab4eb63809a2a83bf60910_003F88_003Fef12a016_003FStaticResourceExtension_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATaskCompletionSource_00601_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5147b10c5a8c4522b56fba0a889139cfc8f908_003Ffc_003Fe9092391_003FTaskCompletionSource_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003F72_003F6381d5d3_003FTask_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextInfo_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F68d37d16685244cf9996bf767117a771210200_003F3a_003Ff14dd285_003FTextInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@ -59,6 +62,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUndoStack_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F85eb3e3af2ef415e8072243864dec55a97e00_003F18_003F3f9ef08f_003FUndoStack_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUnsafeNativeMethodsCLR_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2e8b8aa5d488ba9b46d9ca2a747d6895994b3519f2f231f4e3d1af87b86320_003FUnsafeNativeMethodsCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUnwrapPromise_00601_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003F9d_003F0ea6b8e2_003FUnwrapPromise_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindowChromeWorker_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6412d4331611499aab4eb63809a2a83bf60910_003Ff9_003F2f1adeba_003FWindowChromeWorker_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindow_002Ecs_002Fl_003AC_0021_003FUsers_003FAdministrator_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd0db11e55b76dc7f234163f6cee32b297b8ddb591fb0b5cbad1b46ed17343e18_003FWindow_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindow_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd0db11e55b76dc7f234163f6cee32b297b8ddb591fb0b5cbad1b46ed17343e18_003FWindow_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AXamlReader_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc82ad29b96d5485f88fa4f2ce6e6c019f60908_003F0b_003Fbba3a168_003FXamlReader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

@ -72,11 +72,17 @@ public partial class MessageBox : Window
return _result;
}
//
public MessageBoxResult ShowInput(String message, out String inputStr , String confirmButtonTitle = "", String cancelButtonTitle ="")
public MessageBoxResult ShowInput(String message, out String inputStr , String confirmButtonTitle = "", String cancelButtonTitle ="", bool EnterConfirm = true)
{
_showType = 2;
this.Height = 300;
TextBlockCenterBox.Text = message;
TextBoxInput.Focus();
if (EnterConfirm)
{
TextBoxInput.KeyDown += TextBoxInput_OnKeyDown;
}
if (!string.IsNullOrWhiteSpace(confirmButtonTitle) && !string.IsNullOrWhiteSpace(cancelButtonTitle))
{
ConfirmButtonText.Text = confirmButtonTitle;
@ -139,4 +145,12 @@ public partial class MessageBox : Window
}
}
private void TextBoxInput_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter) // 检测是否按下回车键
{
ConfirmButton_OnClick(sender, e); // 调用按钮的点击事件
}
}
}
Loading…
Cancel
Save