diff --git a/AksWebBrowser.sln b/AksWebBrowser.sln
new file mode 100644
index 0000000..2d69e9e
--- /dev/null
+++ b/AksWebBrowser.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34622.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AKS.EnterpriseLibrary.WebBrowser", "CPF_Cef\AKS.EnterpriseLibrary.WebBrowser.csproj", "{76142658-6E83-4A1C-8CC9-C2574865CA7D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x64.ActiveCfg = Debug|x64
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x64.Build.0 = Debug|x64
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x86.ActiveCfg = Debug|x86
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x86.Build.0 = Debug|x86
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x64.ActiveCfg = Release|x64
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x64.Build.0 = Release|x64
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x86.ActiveCfg = Release|x86
+ {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {BDDA2FFD-1C83-470F-82EE-DE0E448EEB6D}
+ EndGlobalSection
+EndGlobal
diff --git a/CPF_Cef/AKS.EnterpriseLibrary.WebBrowser.csproj b/CPF_Cef/AKS.EnterpriseLibrary.WebBrowser.csproj
new file mode 100644
index 0000000..9e4a5de
--- /dev/null
+++ b/CPF_Cef/AKS.EnterpriseLibrary.WebBrowser.csproj
@@ -0,0 +1,51 @@
+
+
+
+ WinExe
+ net6.0
+ Recent.ico
+
+ AksWebBrowser
+ AksWebBrowser
+ AnyCPU;x64;x86
+
+
+
+ true
+
+ AnyCPU
+
+
+
+ true
+
+ AnyCPU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CPF_Cef/AssistEntity.cs b/CPF_Cef/AssistEntity.cs
new file mode 100644
index 0000000..bc200c8
--- /dev/null
+++ b/CPF_Cef/AssistEntity.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AksWebBrowser
+{
+ public enum LightTypeModel
+ {
+ FingerLight,
+ IDCardLight,
+ BottomLight,
+ BurnLight
+ }
+}
diff --git a/CPF_Cef/Common/COMUtils.cs b/CPF_Cef/Common/COMUtils.cs
new file mode 100644
index 0000000..708e29a
--- /dev/null
+++ b/CPF_Cef/Common/COMUtils.cs
@@ -0,0 +1,321 @@
+using AKS.EnterpriseLibrary.WebBrowser;
+using AksWebBrowser;
+using AKSWebBrowser.Commen;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.IO.Ports;
+using System.Text;
+using System.Threading.Tasks;
+using System.Timers;
+using Timer = System.Timers.Timer;
+namespace AKSWebBrowser.Common
+{
+ public class COMUtils
+ {
+ private static SerialPort serialPort = new SerialPort();
+ public string jsonstr = string.Empty;
+ public string jsontemp = string.Empty;
+ public int maxCHunkSize = 1024;
+ public string callback = string.Empty;
+ public string ml = "COM4";
+ public COMUtils()
+ {
+ OpenCOM();
+ }
+
+ //打开COM口
+ public void OpenCOM()
+ {
+
+ try
+ {
+ //要执行的Linux命令
+ string[] cmd = LinuxCmdArea("ls /dev");
+ if (cmd.Length > 0)
+ {
+ string parm = string.Empty;
+ foreach (string line in cmd)
+ {
+ if (line.Contains("ttyCH341USB"))
+ {
+ parm = line;
+ break;
+ }
+ }
+ if (!string.IsNullOrEmpty(parm))
+ {
+ ml = "/dev/" + parm;
+ Log.Info("输出结果:" + ml);
+ //给管理权限
+ LinuxCmd(ml);
+ //打开串口
+ // 设置COM口,波特率,奇偶校验,数据位,停止位
+ serialPort.PortName = ml; // 请替换为你的串口名称
+ serialPort.BaudRate = 115200; // 设置波特率
+ serialPort.Parity = Parity.None;
+ serialPort.DataBits = 8;
+ serialPort.StopBits = StopBits.One;
+ serialPort.Handshake = Handshake.None;
+ serialPort.DtrEnable = true; //启用控制终端就续信号
+ //serialPort.ReadTimeout = 18000;
+ //serialPort.RtsEnable = true; //启用请求发送信号
+ serialPort.NewLine = "\n";
+ serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
+ if (!serialPort.IsOpen)
+ {
+ serialPort.Open();
+ }
+ Timer timer = new Timer(3000);//1秒钟的时间间隔
+ timer.Elapsed += OnTimedEvent;
+ timer.AutoReset = true;//重复执行
+ timer.Enabled = true;//启动定时器
+ Log.Info("浏览器COM服务启动成功");
+ }
+ else
+ {
+ Log.Info("串口类型不匹配");
+ }
+ }
+ else
+ {
+ Log.Info("当前设备没有串口设备");
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Info("服务启动异常ex: " + ex.Message + "");
+ }
+
+ }
+
+ //接受数据
+ public static string bsid = string.Empty;
+ public static string bsext = string.Empty;
+ public static string bspath = string.Empty;
+ public static bool sfjswc = false;
+ private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
+ {
+ try
+ {
+ SerialPort sp = (SerialPort)sender;
+ string _jsonstr = sp.ReadExisting();
+ if (!string.IsNullOrEmpty(_jsonstr))
+ {
+ if (_jsonstr.Contains("\n"))
+ {
+ jsonstr = jsontemp + _jsonstr;
+ //向js发送数据
+ //CShaseBJavaScript(jsonstr);
+ //jsontemp = string.Empty;
+ //jsonstr = string.Empty;
+ }
+ else
+ {
+ jsontemp = jsontemp + _jsonstr;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Info("接受数据数据异常: " + ex.Message + "");
+ jsonstr = MainModel.str2Base64("{\"callback\":\"" + this.callback + "\",\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "接受数据数据超时:" + ex.Message + "\"}");
+ // CShaseBJavaScript(jsonstr);
+ }
+ }
+
+ //打开串口
+ private void OnTimedEvent(Object source, ElapsedEventArgs e)
+ {
+ try
+ {
+ if (!serialPort.IsOpen)
+ {
+ serialPort.Open();
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Info("定时任务打开串口异常: " + ex.Message + "");
+ }
+ }
+
+ //发送数据
+ public string SendData(string data, string callback)
+ {
+ try
+ {
+ this.callback = callback;
+ if (serialPort.IsOpen)
+ {
+ jsontemp = string.Empty;
+ jsonstr = string.Empty;
+ //写入数据并以换行符结束
+ serialPort.WriteLine(data);
+ Log.Info("发送数据成功: " + data + "");
+ while (string.IsNullOrEmpty(jsonstr))
+ {
+ Task.Delay(10).Wait();
+ }
+ }
+ else
+ {
+ //重新打开串口
+ OpenCOM();
+ if (serialPort.IsOpen)
+ {
+ jsontemp = string.Empty;
+ jsonstr = string.Empty;
+ //写入数据并以换行符结束
+ serialPort.WriteLine(data);
+ Log.Info("发送数据成功: " + data + "");
+ while (string.IsNullOrEmpty(jsonstr))
+ {
+ Task.Delay(10).Wait();
+ }
+ }
+ else
+ {
+ jsontemp = string.Empty;
+ jsonstr = string.Empty;
+ Log.Info("发送数据失败");
+ jsonstr = MainModel.str2Base64("{\"callback\":\"" + this.callback + "\",\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "串口未打开" + "\"}");
+ //CShaseBJavaScript(jsonstr);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ jsontemp = string.Empty;
+ jsonstr = string.Empty;
+ Log.Info("发送数据异常3: " + ex.Message + "");
+ jsonstr = MainModel.str2Base64("{\"callback\":\"" + this.callback + "\",\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "发送数据异常:" + ex.Message + "\"}");
+ //CShaseBJavaScript(jsonstr);
+ }
+ return jsonstr;
+ }
+
+ //关闭
+ public void ClosePort()
+ {
+ try
+ {
+ if (serialPort.IsOpen)
+ {
+ serialPort.Close(); // 关闭串口
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("关闭异常: " + ex.Message + "");
+ }
+ }
+
+ ///
+ /// COM接收文件
+ ///
+ public void NewMethod1(SerialPort sp, string path)
+ {
+ byte[] buffer = new byte[sp.ReadBufferSize];
+ int bytesRead = sp.Read(buffer, 0, buffer.Length);
+ using (FileStream fileStream = new FileStream(path, FileMode.Append))
+ {
+ fileStream.Write(buffer, 0, bytesRead);
+ fileStream.Close();
+ fileStream.Dispose();
+ }
+ }
+
+
+ ///
+ /// COM口公共发送文件
+ ///
+ ///
+ public void NewMethod(string url, string id)
+ {
+ string ext = Path.GetExtension(url);
+ serialPort.WriteLine("Start_" + id + "_" + ext);
+ // 发送端
+ byte[] documentBytes = File.ReadAllBytes(url);
+ serialPort.Write(documentBytes, 0, documentBytes.Length);
+ serialPort.WriteLine("End");
+ }
+
+
+ //向js传输数据
+ public void CShaseBJavaScript(string param)
+ {
+ Task.Run(async () =>
+ {
+ param = MainModel.Base64str2(param);
+ Log.Info("返回数据:" + param);
+ JObject jo = (JObject)JsonConvert.DeserializeObject(param);
+ bool fieldExists = jo.ContainsKey("callback");
+ if (fieldExists)
+ {
+ string callback = jo["callback"].ToString();
+ Log.Info("回调js方法:" + callback);
+ string _parm = callback + "('" + param + "')";
+ await Parame.webBrowser.ExecuteJavaScript(_parm);
+ }
+ else
+ {
+ Log.Info("回调js方法为空");
+ }
+ });
+ }
+
+ //执行命令
+ public void LinuxCmd(string command)
+ {
+ command = $"echo 'aks@123456' sudo -S chmod 777 {command}";
+ Log.Info("执行命令:" + command);
+ // 启动进程
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "/bin/bash",
+ Arguments = $"-c \"{command}\"",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true
+ }
+ };
+ process.Start();
+ string output = process.StandardOutput.ReadToEnd();
+ string error = process.StandardError.ReadToEnd();
+ process.WaitForExit();
+ Log.Info("执行命令结果返回:" + output);
+ Log.Info("执行命令错误结果返回:" + error);
+ }
+
+ //执行命令返回数组
+ public string[] LinuxCmdArea(string command)
+ {
+ // 使用ProcessStartInfo设置启动参数
+ ProcessStartInfo startInfo = new ProcessStartInfo
+ {
+ FileName = "/bin/bash", // 指定bash shell
+ Arguments = $"-c \"{command}\"", // 要执行的命令
+ RedirectStandardOutput = true, // 重定向标准输出
+ UseShellExecute = false, // 不使用系统外壳程序启动
+ CreateNoWindow = true // 不创建新窗口
+ };
+
+ // 启动进程
+ using (Process process = Process.Start(startInfo))
+ {
+ using (System.IO.StreamReader reader = process.StandardOutput)
+ {
+ string result = reader.ReadToEnd(); // 读取全部输出
+ return result.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); // 转换为字符串数组
+ }
+ }
+ }
+ }
+}
diff --git a/CPF_Cef/Common/ChunkedUpload.cs b/CPF_Cef/Common/ChunkedUpload.cs
new file mode 100644
index 0000000..f6f9759
--- /dev/null
+++ b/CPF_Cef/Common/ChunkedUpload.cs
@@ -0,0 +1,58 @@
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using CPF.Controls;
+
+namespace AksWebBrowser.Common
+{
+ public class ChunkedUpload
+ {
+ private readonly HttpClient _httpClient;
+
+ public ChunkedUpload(HttpClient httpClient)
+ {
+ _httpClient = httpClient;
+ }
+
+ public async Task UploadFileAsync(string url, string filePath)
+ {
+ string ret = string.Empty;
+ using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+ {
+ FileInfo fileInfo = new FileInfo(filePath);
+ int totalParts = 1;
+ int chunkNumber = 1;
+ // 读取文件流其实位置
+ var fileStreamPos = 0;
+ var uploadUrl = $"{url}?partNumber={chunkNumber}&chunks={totalParts}&size={fileInfo.Length}&start={fileStreamPos}&end={fileInfo.Length}&total={fileInfo.Length}&FileName={Path.GetFileName(filePath)}";
+
+ using (var client = new HttpClient())
+ {
+
+ var formData = new MultipartFormDataContent();
+ formData.Add(new StreamContent(fileStream, (int)fileStream.Length), "file", Path.GetFileName(filePath) + ".partNumber-1");
+ var response = await client.PostAsync(uploadUrl, formData);
+ var responseString = await response.Content.ReadAsStringAsync();
+ fileStream.Close();
+ fileStream.Dispose();
+ ret = responseString;
+ JObject jo = (JObject)JsonConvert.DeserializeObject(ret);
+ if (Convert.ToBoolean(jo["IsSucceed"].ToString()) == true)
+ {
+ string result = jo["result"].ToString();
+ JObject jo1 = (JObject)JsonConvert.DeserializeObject(result);
+ ret = jo1["url"].ToString();
+ }
+ }
+ }
+ return ret;
+ }
+ }
+}
diff --git a/CPF_Cef/Common/Log.cs b/CPF_Cef/Common/Log.cs
new file mode 100644
index 0000000..adc6668
--- /dev/null
+++ b/CPF_Cef/Common/Log.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AKSWebBrowser.Commen
+{
+ public class Log
+ {
+ private static StreamWriter streamWriter; //写文件
+
+ public static void Error(string message)
+ {
+ try
+ {
+ //DateTime dt = new DateTime();
+ string directPath = AppDomain.CurrentDomain.BaseDirectory + @"/logs/error"; //在获得文件夹路径
+ if (!Directory.Exists(directPath)) //判断文件夹是否存在,如果不存在则创建
+ {
+ Directory.CreateDirectory(directPath);
+ }
+ directPath += string.Format(@"/{0}.log", DateTime.Now.ToString("yyyy-MM-dd"));
+ if (streamWriter == null)
+ {
+ streamWriter = !File.Exists(directPath) ? File.CreateText(directPath) : File.AppendText(directPath);
+ }
+ streamWriter.WriteLine("***********************************************************************");
+ streamWriter.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
+ streamWriter.WriteLine("输出信息:错误信息");
+ if (message != null)
+ {
+ streamWriter.WriteLine("异常信息:\r\n" + message);
+ }
+ }
+ finally
+ {
+ if (streamWriter != null)
+ {
+ streamWriter.Flush();
+ streamWriter.Dispose();
+ streamWriter = null;
+ }
+ }
+ }
+
+ public static void Info(string message)
+ {
+ try
+ {
+ //DateTime dt = new DateTime();
+ string directPath = AppDomain.CurrentDomain.BaseDirectory + @"/logs/Info"; //在获得文件夹路径
+ if (!Directory.Exists(directPath)) //判断文件夹是否存在,如果不存在则创建
+ {
+ Directory.CreateDirectory(directPath);
+ }
+ directPath += string.Format(@"/{0}.log", DateTime.Now.ToString("yyyy-MM-dd"));
+ if (streamWriter == null)
+ {
+ streamWriter = !File.Exists(directPath) ? File.CreateText(directPath) : File.AppendText(directPath);
+ }
+ streamWriter.WriteLine("***********************************************************************");
+ streamWriter.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
+ streamWriter.WriteLine("输出信息:信息");
+ if (message != null)
+ {
+ streamWriter.WriteLine("信息:\r\n" + message);
+ }
+ }
+ finally
+ {
+ if (streamWriter != null)
+ {
+ streamWriter.Flush();
+ streamWriter.Dispose();
+ streamWriter = null;
+ }
+ }
+ }
+ }
+}
diff --git a/CPF_Cef/Common/Utils.cs b/CPF_Cef/Common/Utils.cs
new file mode 100644
index 0000000..5616b15
--- /dev/null
+++ b/CPF_Cef/Common/Utils.cs
@@ -0,0 +1,21 @@
+using CPF.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AksWebBrowser.Common
+{
+ public class Utils
+ {
+ ///
+ /// 消息弹框
+ ///
+ ///
+ public static void MessagesBox(string mes) {
+ MessageBox.ShowSync(mes);
+
+ }
+ }
+}
diff --git a/CPF_Cef/CusWebBrowser.cs b/CPF_Cef/CusWebBrowser.cs
new file mode 100644
index 0000000..d51b8b7
--- /dev/null
+++ b/CPF_Cef/CusWebBrowser.cs
@@ -0,0 +1,77 @@
+using CPF;
+using CPF.Cef;
+using CPF.Cef.JSExtenstions;
+using CPF.Mac.CoreText;
+using CPF.Reflection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.ConstrainedExecution;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AKS.EnterpriseLibrary.WebBrowser
+{
+
+ public class CusWebBrowser : CPF.Cef.WebBrowser
+ {
+ public CusCefRequestHandler CusRequest = new CusCefRequestHandler();
+ public CusWebBrowser() { }
+
+ protected override CpfCefClient OnCreateWebBrowser(CefBrowserSettings settings)
+ {
+ CpfCefClient cefClient = base.OnCreateWebBrowser(settings);
+ cefClient.RequestHandler = CusRequest;
+ cefClient.ContextMenuHandler = new MenuHandler();
+ cefClient.DragHandler = new DragHandler();
+ return cefClient;
+ }
+ }
+
+ public class CusCefRequestHandler : CpfCefRequestHandler
+ {
+ public delegate void CusResquestDelegate(CefPostData postData, CefRequest request);
+ public event CusResquestDelegate CusResquestEvent;
+
+ public CusCefRequestHandler() { }
+
+ protected override CefResourceRequestHandler GetResourceRequestHandler(CefBrowser browser, CefFrame frame, CefRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
+ {
+ CusResquestEvent(request.PostData, request);
+ return null;
+ }
+ }
+
+ public class DragHandler : CpfCefDragHandler
+ {
+ protected override bool OnDragEnter(CefBrowser browser, CefDragData dragData, CefDragOperationsMask mask)
+ {
+ return true;
+ }
+ protected override void OnDraggableRegionsChanged(CefBrowser browser, CefFrame frame, CefDraggableRegion[] regions)
+ {
+
+ }
+ }
+
+ public class MenuHandler : CpfCefContextMenuHandler
+ {
+ protected override void OnBeforeContextMenu(CefBrowser browser, CefFrame frame, CefContextMenuParams state, CefMenuModel model)
+ {
+ model.Clear();
+ }
+ protected override bool OnContextMenuCommand(CefBrowser browser, CefFrame frame, CefContextMenuParams state, int commandId, CefEventFlags eventFlags)
+ {
+ return false;
+ }
+ protected override void OnContextMenuDismissed(CefBrowser browser, CefFrame frame)
+ {
+
+ }
+ protected override bool RunContextMenu(CefBrowser browser, CefFrame frame, CefContextMenuParams parameters, CefMenuModel model, CefRunContextMenuCallback callback)
+ {
+ return false;
+ }
+ }
+
+}
diff --git a/CPF_Cef/FrmMain.cs b/CPF_Cef/FrmMain.cs
new file mode 100644
index 0000000..cae73a7
--- /dev/null
+++ b/CPF_Cef/FrmMain.cs
@@ -0,0 +1,202 @@
+using AksWebBrowser;
+using CPF;
+using CPF.Cef;
+using CPF.Controls;
+using CPF.Platform;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
+using System.IO;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using AKSWebBrowser.Commen;
+using System.Collections.Generic;
+using System.Reflection.Metadata;
+using AksWebBrowser.Common;
+
+namespace AKS.EnterpriseLibrary.WebBrowser
+{
+ public class FrmMain : Window
+ {
+
+ protected override void InitializeComponent()
+ {
+ LoadStyleFile("res://AksWebBrowser/StyleSheet.css");
+ //加载样式文件,文件需要设置为内嵌资源
+ Title = "控申业务专用浏览器";
+ CanResize = false;
+ ShowInTaskbar = true;
+ WindowState = WindowState.Maximized;
+ Children.Add(
+ new Border
+ {
+ Width = "100%",
+ Height = "100%",
+ Child = new Panel
+ {
+ Size = SizeField.Fill,
+ Children =
+ {
+ new CusWebBrowser
+ {
+ PresenterFor = this,
+ Name = nameof(Parame.webBrowser),
+ Bindings =
+ {
+ {
+ nameof(CusWebBrowser.Title),
+ "Title",
+ this,
+ BindingMode.OneWayToSource
+ },
+ },
+ MarginTop=0,
+ MarginLeft=0,
+ MarginRight=0,
+ MarginBottom=0,
+ },
+ }
+ }
+ }
+ );
+ }
+ private TextBox textBox;
+ protected override async void OnInitialized()
+ {
+ //窗体大小
+ this.Width = 1080;
+ this.Height = 1920;
+ //SetTaskStatus.Hidetask();
+ base.OnInitialized();
+ Parame.webBrowser = FindPresenterByName(nameof(Parame.webBrowser));
+ textBox = FindPresenterByName(nameof(textBox));
+ Parame.webBrowser.CusRequest.CusResquestEvent += CusRequest_CusResquestEvent;
+ //浏览器大小
+ Parame.webBrowser.Width = 1080;
+ Parame.webBrowser.Height = 1920;
+ Parame.webBrowser.Url = "http://192.168.0.34:8078/#/main-out";
+ //Parame.webBrowser.Url = Application.StartupPath + @"\html\index.html";
+ //开发者工具暂时只能支持Windows
+ //webBrowser.ShowDev();
+ //SetTaskStatus.Showtask();
+ Parame.webBrowser.LoadEnd += WebBrowser_LoadEnd;
+ this.Closing += MainWindow_Closing;
+ }
+
+ //关闭事件
+ private void MainWindow_Closing(object sender, ClosingEventArgs e)
+ {
+ new MainModel().CLoseCOM();
+ MainModel.KillProcessByName("AksWebBrowser");
+ }
+ bool showDev = false;
+ private void WebBrowser_LoadEnd(object sender, LoadEndEventArgs e)
+ {
+ if (!showDev)
+ {
+ showDev = true;
+ Parame.webBrowser.ShowDev();
+ }
+ //获取授权
+ GetSQObject();
+ }
+
+ public void Writelog(string str, string dirName = @"logs")
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(str)) return;
+
+ var baseDir = AppDomain.CurrentDomain.BaseDirectory + dirName;
+ if (!Directory.Exists(baseDir))
+ {
+ Directory.CreateDirectory(baseDir);
+ }
+ string filePath = System.IO.Path.Combine(baseDir, DateTime.Now.ToString("yyyy-MM-dd") + "_log.txt");
+ using (StreamWriter sw = File.AppendText(filePath))
+ {
+ sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "[" + str + "]" + "\r\n");
+ sw.Flush();
+ }
+ }
+ catch { }
+ }
+ private void CusRequest_CusResquestEvent(CefPostData postData, CefRequest request)
+ {
+ string postParams = string.Empty;
+ if (postData != null)
+ {
+ //取提交的参数
+ CefPostData cefPostData = postData;
+ var elements = cefPostData.GetElements();
+ foreach (var element in elements)
+ {
+ if (element.ElementType == CefPostDataElementType.Bytes)
+ {
+ var bytes = element.GetBytes();
+ postParams = Encoding.UTF8.GetString(bytes);
+ Console.WriteLine("请求参数:" + postParams);
+ }
+ }
+ }
+
+ Console.WriteLine("请求地址:" + request.Url.ToString());
+ }
+
+ //调用JS内的JS方法
+ async void InvokeJS(CpfObject obj, RoutedEventArgs eventArgs)
+ {
+ var r = await Parame.webBrowser.ExecuteJavaScript("callback('调用绑定到JS里的C#方法')");
+ }
+
+ ///
+ /// 或者可以用授权接口
+ ///
+ public void GetSQObject()
+ {
+ Task.Run(async () =>
+ {
+ var client = new HttpClient();
+ var request = new HttpRequestMessage(HttpMethod.Get, $"{Parame.apiUrl}/api/Interface/Getlist?Ytjbm={Parame.key}");
+ var response = await client.SendAsync(request);
+ List list = new List();
+ if (response.StatusCode.ToString() == "200")
+ {
+ response.EnsureSuccessStatusCode();
+ var body = await response.Content.ReadAsStringAsync();
+ JObject jo = (JObject)JsonConvert.DeserializeObject(body);
+ if (jo["IsSucceed"].ToString() == "True")
+ {
+ string result = jo["result"].ToString();
+ if (!string.IsNullOrEmpty("result"))
+ {
+ JArray array = (JArray)JsonConvert.DeserializeObject(result);
+ foreach (JObject item in array)
+ {
+ Func func = new Func()
+ {
+ Id = item["Id"].ToString(),
+ Platform = item["Platform"].ToString(),
+ Interfaceaddress = item["Interfaceaddress"].ToString(),
+ };
+ list.Add(func);
+ }
+ }
+ else
+ {
+ Log.Info("未获取授权");
+ Utils.MessagesBox("未获取授权");
+ }
+ }
+ else
+ {
+ Log.Info("未获取授权");
+ Utils.MessagesBox("未获取授权");
+ }
+ }
+ Parame.FuncObject = list;
+ });
+ }
+ }
+}
diff --git a/CPF_Cef/MainModel.cs b/CPF_Cef/MainModel.cs
new file mode 100644
index 0000000..0dcd33e
--- /dev/null
+++ b/CPF_Cef/MainModel.cs
@@ -0,0 +1,1206 @@
+using AksWebBrowser;
+using AksWebBrowser.Common;
+using AKSWebBrowser.Commen;
+using AKSWebBrowser.Common;
+using CPF.Cef;
+using CPF.Mac.AppKit;
+using NAudio.Wave;
+using NAudio.Wave.SampleProviders;
+using SkiaSharp;
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Web;
+using System.Xml.Linq;
+
+namespace AKS.EnterpriseLibrary.WebBrowser
+{
+ public class MainModel : CPF.CpfObject
+ {
+ public COMUtils com = new COMUtils();
+ public string callback = string.Empty;
+ public string PrinterName = "Lexmark-MS430-Series";
+ public static Process recordingProcess;
+ public static Process Typrocess;
+
+ ///
+ /// 读取身份证卡号
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string IDCardRead(string paramsString)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("IDCardRead"))
+ {
+ Utils.MessagesBox("读取身份证设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "读取身份证设备未授权使用" + "\"}";
+ }
+ else
+ {
+ paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"1\",\"param\":{\"data\":\"" + "" + "\"}}";
+ Log.Info("读取身份证卡号: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string result = Base64str2(str);
+ SubmitLogs(result, "IDCardRead");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("读取身份证卡号异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "IDCardRead");
+ return result;
+ }
+ }
+
+ ///
+ /// 打印排队票据
+ ///
+ /// 排号
+ /// 等待人数
+ /// 二维码
+ /// 办理业务名称
+ ///
+ [JSFunction]
+ public string SendByPrint(string ph, string ddrs, string qrcode, string ywmc)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("SendByPrint"))
+ {
+ Utils.MessagesBox("打印排队票据设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "打印排队票据设备未授权使用" + "\"}";
+ }
+ else
+ {
+ string paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"2\",\"param\":{\"ph\":\"" + ph + "\",\"ddrs\":\"" + ddrs + "\",\"qrcode\":\"" + qrcode + "\",\"ywmc\":\"" + ywmc + "\"}}";
+ Log.Info("打印排队票据: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string result = Base64str2(str);
+ SubmitLogs(result, "SendByPrint");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("打印排队票据异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "SendByPrint");
+ return result;
+ }
+ }
+
+ ///
+ /// 文字语音播报
+ /// apt install sox
+ /// apt install libsox-fmt-all
+ ///
+ ///
+ ///
+ ///
+ public WaveOutEvent playerTxt = null;
+ public static string tempWav = string.Empty;
+ [JSFunction]
+ public string payleText(string text, bool ispaye)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("payleText"))
+ {
+ Utils.MessagesBox("文字语音播报设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "文字语音播报设备未授权使用" + "\"}";
+ }
+ else
+ {
+ string paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"3\",\"param\":{\"text\":\"" + text + "\",\"ispaye\":\"" + ispaye + "\"}}";
+ Log.Info("文字语音播报: " + paramsString + "");
+ //string base64 = str2Base64(paramsString);
+ //if (base64.Length > 1024)
+ //{
+ // //形成临时文件
+ // DateTime dateTime = DateTime.Now;
+ // string time = DateTime.Now.ToString(
+ // "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ // var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "TempFile");
+ // if (!Directory.Exists(dirpath))
+ // {
+ // Directory.CreateDirectory(dirpath);
+ // }
+ // var filepath = System.IO.Path.Combine(dirpath, time);
+ // string path = dirpath + @"/" + time + ".txt";
+ // base64 = str2Base64(text);
+ // byte[] bytes = Convert.FromBase64String(base64);
+ // System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.CreateNew);
+ // System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream);
+ // writer.Write(bytes, 0, bytes.Length);
+ // writer.Close();
+ // Log.Info("文字语音播报临时文件: " + path + "");
+ // string id = Guid.NewGuid().ToString();
+ // //通过文件发送数据
+ // com.NewMethod(path, ".txt");
+
+ // //正式执行命令
+ // string url = "http://192.168.0.34:92/api/UploadFP/UploadFP";
+ // Regex re = new Regex(@"(((?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)");
+ // MatchCollection mc = re.Matches(url);//获取的是一个数组
+ // string pdfurl = mc[0].ToString() + "://" + mc[1].ToString() + urlpath;
+ // paramsString = "{\"callback\":\"" + callback + "\",\"bsid\":\"" + id + "\",\"type\":\"3\",\"param\":{\"text\":\"" + pdfurl + "\",\"ispaye\":\"" + ispaye + "\"}}";
+ // Log.Info("文字语音播报: " + paramsString + "");
+ // base64 = str2Base64(paramsString);
+ //}
+ //string str = com.SendData(base64, callback);
+ //return Base64str2(str);
+ if (ispaye)
+ {
+ Task.Run(() =>
+ {
+ if (Typrocess != null)
+ {
+ // 如果进程还在运行
+ if (!Typrocess.HasExited)
+ {
+ // 发送SIGTERM信号来停止进程
+ Typrocess.Kill();
+ // 等待进程真正停止
+ Typrocess.WaitForExit();
+ }
+ }
+ });
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":" + "停止播放成功" + "}";
+ SubmitLogs(result, "payleText");
+ return result;
+ }
+ else
+ {
+ Task.Run(() =>
+ {
+ //形成语音
+ tempWav = GenerateWavFromText(text);
+ //开始播放
+ string command = $"sox {tempWav} -d";
+ ShllCommad(command);
+ });
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":" + "开始播放" + "}";
+ SubmitLogs(result, "payleText");
+ return result;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("文字语音播报异常2: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "payleText");
+ return result;
+ }
+ }
+
+ ///
+ /// 发送短信
+ ///
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string SendSSM(string content, string phone)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("SendSSM"))
+ {
+ Utils.MessagesBox("发送短信设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "发送短信设备未授权使用" + "\"}";
+ }
+ else
+ {
+ string paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"4\",\"param\":{\"content\":\"" + content + "\",\"phone\":\"" + phone + "\"}}";
+ Log.Info("发送短信: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string result = Base64str2(str);
+ SubmitLogs(result, "SendSSM");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("发送短信异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "SendSSM");
+ return result;
+ }
+ }
+
+ ///
+ /// 打开高拍仪并且进行快速扫描文件
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string openCamera(string url)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("openCamera"))
+ {
+ Utils.MessagesBox("高拍仪设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "高拍仪设备未授权使用" + "\"}";
+ }
+ else
+ {
+ string paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"5\",\"param\":{\"url\":\"" + url + "\"}}";
+ Log.Info("打开高拍仪并且进行快速扫描文件: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string data = Base64str2(str);
+ if (data == "400")
+ {
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "获取签字失败" + "\"}";
+ SubmitLogs(result, "openCamera");
+ return result;
+ }
+ else
+ {
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"jpg\",\"data\":\"" + str + "\"}";
+ SubmitLogs(result, "openCamera");
+ return result;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("打开高拍仪并且进行快速扫描文件异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "openCamera");
+ return result;
+ }
+ }
+
+ ///
+ /// 打开签字版
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string OpenSign(string paramsString)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("OpenSign"))
+ {
+ Utils.MessagesBox("签字版设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "签字版设备未授权使用" + "\"}";
+ }
+ else
+ {
+ paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"6\",\"param\":{\"data\":\"" + "" + "\"}}";
+ Log.Info("打开签字版: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string result = Base64str2(str);
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("打开签字版异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ }
+
+ ///
+ /// 关闭签字版
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string CloseSign(string paramsString)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("OpenSign"))
+ {
+ Utils.MessagesBox("签字版设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "签字版设备未授权使用" + "\"}";
+ }
+ else
+ {
+ paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"7\",\"param\":{\"data\":\"" + "" + "\"}}";
+ Log.Info("关闭签字版: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string result = Base64str2(str);
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("关闭签字版异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ }
+
+ ///
+ /// 获取签字版数据
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string GetSignData(string url)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("OpenSign"))
+ {
+ Utils.MessagesBox("签字版设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "签字版设备未授权使用" + "\"}";
+ }
+ else
+ {
+ string paramsString = "{\"callback\":\"" + callback + "\",\"type\":\"8\",\"param\":{\"url\":\"" + url + "\"}}";
+ Log.Info("获取签字版数据: " + paramsString + "");
+ string base64 = str2Base64(paramsString);
+ string str = com.SendData(base64, callback);
+ string data = Base64str2(str);
+ if (data == "400")
+ {
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "获取签字失败" + "\"}";
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ else
+ {
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"png\",\"data\":\"" + str + "\"}";
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("获取签字版数据异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "OpenSign");
+ return result;
+ }
+ }
+
+ ///
+ /// 开始录音、取消录音、结束录音
+ /// sudo apt-get update
+ /// sudo apt-get install alsa-utils
+ ///
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string SoundRecording(bool isopen, string url)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("SoundRecording"))
+ {
+ Utils.MessagesBox("录音设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "录音设备未授权使用" + "\"}";
+ }
+ else
+ {
+ //结束录音上传文件
+ if (!string.IsNullOrEmpty(url) && !isopen)
+ {
+ if (StopRecording())
+ {
+ Task.Run(async () =>
+ {
+ UploadInfo(url, srpath);
+ });
+ @event2.WaitOne();
+ Regex re = new Regex(@"(((?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)");
+ MatchCollection mc = re.Matches(url);//获取的是一个数组
+ string reurl = mc[0].ToString() + "://" + mc[1].ToString() + urlpath;
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"wav\",\"data\":\"" + reurl + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+ else
+ {
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"suffix\":\"wav\",\"data\":\"" + "结束录音失败" + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+ }
+ else if (isopen)//开始录音
+ {
+ if (StartRecording())
+ {
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"wav\",\"data\":\"" + "开始录音" + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+ else
+ {
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"suffix\":\"wav\",\"data\":\"" + "录音失败" + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+ }
+ else //取消录音
+ {
+ if (StopRecording())
+ {
+ srpath = string.Empty;
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"wav\",\"data\":\"" + "取消录音" + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+ else
+ {
+ srpath = string.Empty;
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"suffix\":\"wav\",\"data\":\"" + "取消录音失败" + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("开始录音、取消录音、结束录音异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "SoundRecording");
+ return result;
+ }
+ }
+
+ ///
+ /// 根据文件地址在线打印
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string PrintFile(string url, string ext)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("PrintFile"))
+ {
+ Utils.MessagesBox("打印机设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "打印机设备未授权使用" + "\"}";
+ }
+ else
+ {
+ Task.Run(async () =>
+ {
+ DateTime dateTime = DateTime.Now;
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "PrintFile");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ var filepath = System.IO.Path.Combine(dirpath, time);
+ string path = dirpath + "\\" + time + "." + ext;
+ WebRequest request = WebRequest.Create(url);
+ WebResponse response = request.GetResponse();
+ using (Stream stream = response.GetResponseStream())
+ {
+ using (FileStream fileStream = new FileStream(path, FileMode.Create))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ response.Close();
+ Log.Info("根据文件base64打印: " + path + "");
+ string command = $"lp -d {PrinterName} {path}";
+ ShllCommad(command);
+ });
+
+ //string id = Guid.NewGuid().ToString();
+ ////通过文件发送数据
+ //com.NewMethod(path, id);
+ //string paramsString = "{\"callback\":\"" + callback + "\",\"bsid\":\"" + id + "\",\"type\":\"9\",\"param\":{\"url\":\"" + url + "\",\"ext\":\"" + ext + "\"}}";
+ //Log.Info("根据文件地址在线打印: " + paramsString + "");
+ //string base64_1 = str2Base64(paramsString);
+ //string str = com.SendData(base64_1, callback);
+ //return Base64str2(str);
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":\"" + "打印成功" + "\"}";
+ SubmitLogs(result, "PrintFile");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("根据文件地址在线打印异常: " + ex.Message + "");
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "PrintFile");
+ return result;
+ }
+
+ }
+
+ ///
+ /// 根据文件base64打印
+ ///
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string PrintBase64(string url, string base64, string ext)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("PrintBase64"))
+ {
+ Utils.MessagesBox("打印机设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "打印机设备未授权使用" + "\"}";
+ }
+ else
+ {
+ Task.Run(async () =>
+ {
+ DateTime dateTime = DateTime.Now;
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "PrintFile");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ var filepath = System.IO.Path.Combine(dirpath, time);
+ string path = dirpath + @"/" + time + "." + ext;
+ byte[] bytes = Convert.FromBase64String(base64);
+ System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.CreateNew);
+ System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream);
+ writer.Write(bytes, 0, bytes.Length);
+ writer.Close();
+ Log.Info("根据文件base64打印: " + path + "");
+ string command = $"lp -d {PrinterName} {path}";
+ ShllCommad(command);
+ });
+ //string id = Guid.NewGuid().ToString();
+ ////通过文件发送数据
+ //com.NewMethod(path, ext);
+ //Regex re = new Regex(@"(((?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)");
+ //MatchCollection mc = re.Matches(url);//获取的是一个数组
+ //string pdfurl = mc[0].ToString() + "://" + mc[1].ToString() + urlpath;
+ //Log.Info("根据文件base64打印: " + pdfurl + "");
+ //try
+ //{
+ // string paramsString = "{\"callback\":\"" + callback + "\",\"bsid\":\"" + id + "\",\"type\":\"9\",\"param\":{\"url\":\"" + pdfurl + "\",\"ext\":\"" + ext + "\"}}";
+ // Log.Info("根据文件base64打印: " + paramsString + "");
+ // string base64_1 = str2Base64(paramsString);
+ // string str = com.SendData(base64_1, callback);
+ // return Base64str2(str);
+ //}
+ //catch (Exception ex)
+ //{
+ // Log.Error("根据文件base64打印异常: " + ex.Message + "");
+ // return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ //}
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":\"" + "打印成功" + "\"}";
+ SubmitLogs(result, "PrintBase64");
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "PrintBase64");
+ return result;
+ }
+ }
+
+ ///
+ /// 播放音频文件
+ ///
+ ///
+ ///
+ public static WaveOutEvent player = null;
+ public static AudioFileReader audioFileReader = null;
+ public static string WaveOutPath = string.Empty;
+ [JSFunction]
+ public string PalyFile(string url, bool ispaly)
+ {
+ try
+ {
+ if (!isFuncisFuncObject("PalyFile"))
+ {
+ Utils.MessagesBox("音频设备未授权使用");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + "音频设备未授权使用" + "\"}";
+ }
+ else
+ {
+ if (ispaly)
+ {
+ Task.Run(() =>
+ {
+ Uri uri = new Uri(url);
+ //返回 123.xlsx
+ var filename = HttpUtility.UrlDecode(uri.Segments.Last());
+ //获取文件后缀
+ string ext = System.IO.Path.GetExtension(filename);
+ DateTime dateTime = DateTime.Now;
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "WaveOutFile");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ string path = dirpath + @"/" + time + "." + ext;
+ WebRequest request = WebRequest.Create(url);
+ WebResponse response = request.GetResponse();
+ using (Stream stream = response.GetResponseStream())
+ {
+ using (FileStream fileStream = new FileStream(WaveOutPath, FileMode.Create))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ response.Close();
+
+ //开始播放
+ string command = $"sox {path} -d";
+ ShllCommad(command);
+ });
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":" + "开始播放" + "}";
+ SubmitLogs(result, "PalyFile");
+ return result;
+ }
+ else
+ {
+ Task.Run(() =>
+ {
+ if (Typrocess != null)
+ {
+ // 如果进程还在运行
+ if (!Typrocess.HasExited)
+ {
+ // 发送SIGTERM信号来停止进程
+ Typrocess.Kill();
+ // 等待进程真正停止
+ Typrocess.WaitForExit();
+ }
+ }
+ });
+ string result = "{\"callback\":\"" + callback + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":" + "停止播放成功" + "}";
+ SubmitLogs(result, "PalyFile");
+ return result;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ string result = "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ SubmitLogs(result, "PalyFile");
+ return result;
+ }
+ }
+
+ ///
+ /// 播放音频公共方法
+ ///
+ ///
+ private void NewMethod(string url)
+ {
+ Uri uri = new Uri(url);
+ //返回 123.xlsx
+ var filename = HttpUtility.UrlDecode(uri.Segments.Last());
+ //获取文件后缀
+ string ext = System.IO.Path.GetExtension(filename);
+ DateTime dateTime = DateTime.Now;
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "WaveOutFile");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ string path = dirpath + @"/" + time + "." + ext;
+ WebRequest request = WebRequest.Create(url);
+ WebResponse response = request.GetResponse();
+ using (Stream stream = response.GetResponseStream())
+ {
+ using (FileStream fileStream = new FileStream(WaveOutPath, FileMode.Create))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ response.Close();
+
+
+ using (player = new WaveOutEvent())
+ {
+ player.PlaybackStopped += waveOut_PlaybackStopped;
+ using (audioFileReader = new AudioFileReader(WaveOutPath))
+ {
+ // 创建一个增益效果器对象
+ var volumeProvider = new VolumeSampleProvider(audioFileReader.ToSampleProvider());
+ // 将音频文件添加到WaveOutEvent对象中
+ player.Init(volumeProvider);
+ // 设置音量增益为2倍
+ volumeProvider.Volume = 2.0f;
+ // 开始播放音频
+ player.Play();
+ while (player.PlaybackState == PlaybackState.Playing)
+ {
+ Thread.Sleep(1000);
+ }
+ }
+ }
+ Log.Info("开始播放");
+ }
+
+ ///
+ /// 播放完成
+ ///
+ ///
+ ///
+ private void waveOut_PlaybackStopped(object sender, StoppedEventArgs e)
+ {
+ try
+ {
+ player.Stop();
+ // 释放资源
+ player.Dispose();
+ audioFileReader.Dispose();
+ player = null;
+ File.Delete(WaveOutPath);
+ Log.Info("播放完成");
+ }
+ catch (Exception ex)
+ {
+ Log.Info("播放完成,清除本地文件异常" + ex.Message);
+ }
+ }
+
+ ///
+ /// 唤醒键盘
+ ///
+ ///
+ ///
+ [JSFunction]
+ public string openKey(string paramsString)
+ {
+ try
+ {
+ Task.Run(() =>
+ {
+ Bash("/usr/bin/python3 /usr/bin/onboard");
+ });
+ return "{\"message\":\"seccse\",\"code\":\"200\",\"status\":true,\"data\":\"" + "唤醒键盘成功" + "\"}";
+ }
+ catch (Exception ex)
+ {
+ Log.Error("唤醒键盘异常: " + ex.Message + "");
+ return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}";
+ }
+ }
+
+ ///
+ /// 执行文件
+ ///
+ ///
+ ///
+ public static string Bash(string command)
+ {
+ var escapedArgs = command.Replace("\"", "\\\"");
+ var process = new Process()
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "/bin/bash",
+ Arguments = $"-c \"{escapedArgs}\"",
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ }
+ };
+ process.Start();
+ string result = process.StandardOutput.ReadToEnd();
+ process.WaitForExit();
+ process.Dispose();
+ return result;
+ }
+
+ ///
+ /// 初始文件上传
+ ///
+ private string urlpath = string.Empty;
+ private AutoResetEvent @event2 = new AutoResetEvent(false);
+ private async void UploadInfo(string url, string srpath)
+ {
+ var httpClient = new HttpClient();
+ var uploader = new ChunkedUpload(httpClient);
+ urlpath = await uploader.UploadFileAsync(url, srpath);
+ @event2.Set();
+ }
+
+
+ //上传本地文件中转
+ private string urlP = string.Empty;
+ private AutoResetEvent @event5 = new AutoResetEvent(false);
+ private async void UploadInfoByFile(string url, string strpath)
+ {
+ var httpClient = new HttpClient();
+ var uploader = new ChunkedUpload(httpClient);
+ urlP = await uploader.UploadFileAsync(url, strpath);
+ File.Delete(strpath);
+ @event5.Set();
+ }
+
+ ///
+ /// string 转换为 base64
+ ///
+ ///
+ public static string str2Base64(string str)
+ {
+ byte[] b = System.Text.Encoding.UTF8.GetBytes(str);
+ string result = Convert.ToBase64String(b);
+ return result;
+ }
+
+ ///
+ /// base64 转换为 string
+ ///
+ ///
+ public static string Base64str2(string data)
+ {
+ byte[] c = Convert.FromBase64String(data);
+ string result = System.Text.Encoding.UTF8.GetString(c);
+ Log.Info("接收返回数据:" + result);
+ return result;
+ }
+
+ //根据程序名称杀死进程
+ public static void KillProcessByName(string processName)
+ {
+ Process[] processes = Process.GetProcessesByName(processName);
+
+ foreach (Process process in processes)
+ {
+ try
+ {
+ process.Kill();
+ process.WaitForExit(); // 等待进程退出
+ }
+ catch (Exception ex) { }
+ }
+ }
+
+ //关闭串口
+ public void CLoseCOM()
+ {
+ com.ClosePort();
+ }
+
+ ///
+ /// 开始录音
+ ///
+ ///
+ public bool StartRecording()
+ {
+ try
+ {
+ if (recordingProcess != null)
+ {
+ // 如果进程还在运行
+ if (!recordingProcess.HasExited)
+ {
+ // 发送SIGTERM信号来停止arecord进程
+ recordingProcess.Kill();
+ recordingProcess.WaitForExit(); // 等待进程真正停止
+ }
+ }
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "Record");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ srpath = dirpath + "/" + time + ".wav";
+ string outputFile = srpath; // 输出文件名
+ string device = "default"; // 音频设备,可以通过arecord -l来列出所有设备
+ // 构建arecord命令
+ string command = $"arecord --device={device} --file-type=wav --duration=10 --quiet {outputFile}";
+ // 启动进程
+ recordingProcess = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "/bin/bash",
+ Arguments = $"-c \"{command}\"",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true
+ }
+ };
+ recordingProcess.Start();
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("开始录音异常:" + ex.Message);
+ return false;
+ }
+ }
+
+ ///
+ /// 结束录音
+ ///
+ public bool StopRecording()
+ {
+ try
+ {
+ // 如果进程还在运行
+ if (!recordingProcess.HasExited)
+ {
+ // 发送SIGTERM信号来停止arecord进程
+ recordingProcess.Kill();
+ recordingProcess.WaitForExit(); // 等待进程真正停止
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("结束录音异常:" + ex.Message);
+ return false;
+ }
+ }
+
+
+ public static WaveFileWriter writer;
+ public static StreamWriter mStreamWriter;
+ public static WaveInEvent waveIn = null;
+ private string srpath = string.Empty;
+ //开启录音
+ private bool StateSoundRecor()
+ {
+ if (waveIn != null)
+ {
+ waveIn.StopRecording();
+ waveIn.Dispose();
+ writer.Close();
+ mStreamWriter.Close();
+ waveIn = null;
+ }
+ // 录音对象
+ waveIn = new WaveInEvent();
+ int sampleRate = 48000; //采样率
+ int channels = 2; //录音通道数
+ int bitsPerSample = 16; //位深
+ WaveFormat waveFormat = new WaveFormat(sampleRate, bitsPerSample, channels);
+ waveIn.WaveFormat = waveFormat; //设置录音格式
+ DateTime dateTime = DateTime.Now;
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "Record");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ srpath = dirpath + "/" + time + ".wav";
+ string pathfile = dirpath + "/" + time + ".txt";
+ // 创建WaveFileWriter对象来保存录音数据 路径在bin文件下
+ writer = new WaveFileWriter(srpath, waveFormat);
+ //编写器
+ mStreamWriter = new StreamWriter(pathfile, false, new System.Text.UTF8Encoding(false));
+ // 设置录音回调函数
+ int bitIndex = bitsPerSample / 8;
+ waveIn.DataAvailable += (sender, e) =>
+ {
+ // 将录音数据写入文件
+ writer.Write(e.Buffer, 0, e.BytesRecorded);
+ for (int i = 0; i < e.BytesRecorded / bitIndex; i++)
+ {
+ //24bit,导出的数据
+ //int sample = (int)((e.Buffer[i * bitIndex + 2] << 16) | (e.Buffer[i * bitIndex + 1] << 8) | e.Buffer[i * bitIndex]);
+ //16bit 将两个byte数据组合成一个short数据
+ short sample = (short)((e.Buffer[i * bitIndex + 1] << 8) | e.Buffer[i * bitIndex]);
+ mStreamWriter.Write("{0},", sample);
+ }
+ };
+ try
+ {
+ //尝试打开录音设备,如果设备支持设置的WaveFormat,则能够成功打开
+ waveIn.StartRecording();
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Info("录音开启失败:" + ex.Message);
+ srpath = "";
+ return false;
+ }
+ }
+
+ ///
+ /// 停止录音、取消录音
+ ///
+ ///
+ private bool StopSoundRecor()
+ {
+
+ try
+ {
+ //停止录音
+ waveIn.StopRecording();
+ waveIn.Dispose();
+ writer.Close();
+ mStreamWriter.Close();
+ waveIn = null;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Info("停止录音、取消录音失败:" + ex.Message);
+ srpath = "";
+ return false;
+ }
+ }
+
+ ///
+ /// 执行命令
+ ///
+ public static void ShllCommad(string command)
+ {
+ Log.Info("执行命令:" + command);
+ // 启动进程
+ Typrocess = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "/bin/bash",
+ Arguments = $"-c \"{command}\"",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true
+ }
+ };
+ Typrocess.Start();
+ Typrocess.WaitForExit();
+ }
+
+ ///
+ /// 开源文字转语音
+ /// sudo apt-get install espeak
+ ///
+ ///
+ ///
+ static string GenerateWavFromText(string text)
+ {
+ string time = DateTime.Now.ToString(
+ "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
+ var dirpath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "WavFile");
+ if (!Directory.Exists(dirpath))
+ {
+ Directory.CreateDirectory(dirpath);
+ }
+ var tempFile = dirpath + "/" + time + ".wav";
+ text = text.Replace("(", "").Replace(")", "、");
+ ProcessStartInfo startInfo = new ProcessStartInfo
+ {
+ FileName = "espeak",
+ Arguments = $" -vzh -s 150 \"{text}\" -w {tempFile}", // 设置语速为150,输出为WAV文件
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ CreateNoWindow = true
+ };
+ using (Process process = Process.Start(startInfo))
+ {
+ process.WaitForExit(); // 等待进程结束
+ process.Close();
+ process.Dispose();
+ }
+ return tempFile;
+ }
+
+ ///
+ /// 是否已获取收取
+ ///
+ ///
+ ///
+ public bool isFuncisFuncObject(string funcName)
+ {
+ bool isFunc = false;
+ if (Parame.FuncObject.Count > 0)
+ {
+ foreach (Func func in Parame.FuncObject)
+ {
+ if (func.Interfaceaddress.Contains(funcName))
+ {
+ isFunc = true;
+ break;
+ }
+ }
+ }
+ return isFunc;
+ }
+
+ //提交设备操作日志
+ public static void SubmitLogs(string Describer, string funcName)
+ {
+ Task.Run(async () =>
+ {
+ string ApiId = string.Empty;
+ string Name = string.Empty;
+ string Interfaceaddress = string.Empty;
+ bool isFunc = false;
+ if (Parame.FuncObject.Count > 0)
+ {
+ foreach (Func func in Parame.FuncObject)
+ {
+ if (func.Interfaceaddress.Contains(funcName))
+ {
+ isFunc = true;
+ ApiId = func.Id;
+ Name = func.Platform;
+ Interfaceaddress = func.Interfaceaddress;
+ break;
+ }
+ }
+ }
+ if (isFunc)
+ {
+ var client = new HttpClient();
+ var request = new HttpRequestMessage(HttpMethod.Post, $"{Parame.apiUrl}/api/Interface/JournalAdd");
+ var content = new StringContent("{\"Name\": \"" + Name + "\",\"Describer\": \"" + str2Base64(Describer) + "\", \"Interfaceaddress\": \"" + Interfaceaddress + "\", \"ApiId\": \"" + ApiId + "\"}", null, "application/json");
+ request.Content = content;
+ var response = await client.SendAsync(request);
+ if (response.StatusCode.ToString() == "200")
+ {
+ response.EnsureSuccessStatusCode();
+ var body = await response.Content.ReadAsStringAsync();
+ Log.Info(body);
+ }
+ }
+ });
+ }
+
+
+ }
+}
diff --git a/CPF_Cef/Parame.cs b/CPF_Cef/Parame.cs
new file mode 100644
index 0000000..834aeb6
--- /dev/null
+++ b/CPF_Cef/Parame.cs
@@ -0,0 +1,25 @@
+using AKS.EnterpriseLibrary.WebBrowser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AksWebBrowser
+{
+ public class Parame
+ {
+ public static CusWebBrowser webBrowser { get; set; }
+ public static List FuncObject { get; set; }
+ //接口地址
+ public static string apiUrl = "http://192.168.0.34:92";
+ //授权key
+ public static string key = "1";
+ }
+ public struct Func
+ {
+ public string Id { get; set; }
+ public string Platform { get; set; }
+ public string Interfaceaddress { get; set; }
+ };
+}
diff --git a/CPF_Cef/Program.cs b/CPF_Cef/Program.cs
new file mode 100644
index 0000000..9f15228
--- /dev/null
+++ b/CPF_Cef/Program.cs
@@ -0,0 +1,38 @@
+using CPF.Cef;
+using CPF.Linux;//如果需要支持Linux才需要
+using CPF.Mac;//如果需要支持Mac才需要
+using CPF.Platform;
+using CPF.Skia;
+using CPF.Windows;
+using System;
+
+namespace AKS.EnterpriseLibrary.WebBrowser
+{
+ class Program
+ {
+ [STAThread]
+ static void Main(string[] args)
+ {
+ Application.Initialize(
+ (OperatingSystemType.Windows, new WindowsPlatform(), new SkiaDrawingFactory())
+ , (OperatingSystemType.OSX, new MacPlatform(), new SkiaDrawingFactory())//如果需要支持Mac才需要
+ , (OperatingSystemType.Linux, new LinuxPlatform(), new SkiaDrawingFactory())//如果需要支持Linux才需要
+ );
+
+ CefRuntime.Load();
+ var mainArgs = new CpfCefMainArgs(args);
+ var app = new CpfCefApp();
+ var exitCode = CefRuntime.ExecuteProcess(mainArgs, app, IntPtr.Zero);
+ if (exitCode != -1)
+ {
+ return;
+ }
+ CefRuntime.Initialize(mainArgs, new CefSettings{ }, app, IntPtr.Zero);
+
+ var model = new MainModel();
+ Application.Run(new FrmMain { DataContext = model, CommandContext = model });
+
+ CefRuntime.Shutdown();
+ }
+ }
+}
diff --git a/CPF_Cef/Recent.ico b/CPF_Cef/Recent.ico
new file mode 100644
index 0000000..a05686b
Binary files /dev/null and b/CPF_Cef/Recent.ico differ
diff --git a/CPF_Cef/SetTaskStatus.cs b/CPF_Cef/SetTaskStatus.cs
new file mode 100644
index 0000000..9d28f48
--- /dev/null
+++ b/CPF_Cef/SetTaskStatus.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AksWebBrowser
+{
+ public class SetTaskStatus
+ {
+ private const int SW_HIDE = 0; //隐藏任务栏
+ private const int SW_RESTORE = 9;//显示任务栏
+
+ [DllImport("user32.dll")]
+ private static extern int ShowWindow(int hwnd, int nCmdShow);
+ [DllImport("user32.dll")]
+ private static extern int FindWindow(string lpClassName, string lpWindowName);
+
+ ///
+ /// 显示任务栏
+ ///
+ public static void Showtask()
+ {
+ ShowWindow(FindWindow("Shell_TrayWnd", null), SW_RESTORE);
+ }
+ ///
+ /// 隐藏任务栏
+ ///
+ public static void Hidetask()
+ {
+ ShowWindow(FindWindow("Shell_TrayWnd", null), SW_HIDE);
+ }
+
+
+
+ // 设置窗体的显示状态
+ [DllImport("user32.dll", SetLastError = true)]
+ public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
+ int X, int Y, int cx, int cy, uint uFlags);
+
+ // 窗体的句柄
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetForegroundWindow();
+
+ public const uint SWP_SHOWWINDOW = 0x0040;
+ public const uint SWP_NOSIZE = 0x0001;
+ public const uint SWP_NOMOVE = 0x0002;
+ public const uint TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
+ }
+}
diff --git a/CPF_Cef/StyleSheet.css b/CPF_Cef/StyleSheet.css
new file mode 100644
index 0000000..db1d459
--- /dev/null
+++ b/CPF_Cef/StyleSheet.css
@@ -0,0 +1,473 @@
+
+@media windows {
+ * {
+ FontFamily: '微软雅黑'; /*不同系统的字体不同,自己根据情况改或者使用内嵌字体*/
+ }
+}
+
+@media osx {
+ * {
+ FontFamily: '苹方-简';
+ }
+}
+
+@media linux {
+ * {
+ FontFamily: '文泉驿正黑';
+ }
+}
+/*设置窗体标题栏背景颜色圆角*/
+/*#caption {
+ IsAntiAlias: true;
+ Background: #2c2c2c;
+ CornerRadius:5,5,0,0;
+}
+#frame {
+ CornerRadius: 5;
+ IsAntiAlias: true;
+}*/
+Button {
+ BorderFill: #DCDFE6;
+ IsAntiAlias: True;
+ CornerRadius: 4,4,4,4;
+ Background: #FFFFFF;
+}
+
+ Button[IsMouseOver=true] {
+ BorderFill: rgb(198,226,255);
+ Background: rgb(236,245,255);
+ Foreground: rgb(64,158,255);
+ }
+
+ Button[IsPressed=true] {
+ BorderFill: rgb(58,142,230);
+ }
+
+ Button.primary {
+ BorderFill: rgb(64,158,255);
+ CornerRadius: 4,4,4,4;
+ Background: rgb(64,158,255);
+ Foreground: #FFFFFF;
+ }
+
+ Button.primary[IsMouseOver=true] {
+ BorderFill: rgb(102,177,255);
+ Background: rgb(102,177,255);
+ Foreground: #FFFFFF;
+ }
+
+ Button.primary[IsPressed=true] {
+ BorderFill: rgb(58,142,230);
+ Background: rgb(58,142,230);
+ }
+
+ Button.success {
+ BorderFill: rgb(103,194,58);
+ CornerRadius: 4,4,4,4;
+ Background: rgb(103,194,58);
+ Foreground: #FFFFFF;
+ }
+
+ Button.success[IsMouseOver=true] {
+ BorderFill: rgb(133,206,97);
+ Background: rgb(133,206,97);
+ Foreground: #FFFFFF;
+ }
+
+ Button.success[IsPressed=true] {
+ BorderFill: rgb(93,175,52);
+ Background: rgb(93,175,52);
+ }
+
+ Button.danger {
+ BorderFill: rgb(245,108,108);
+ Background: rgb(245,108,108);
+ CornerRadius: 4,4,4,4;
+ Foreground: #FFFFFF;
+ }
+
+ Button.danger[IsMouseOver=true] {
+ BorderFill: rgb(247,137,137);
+ Background: rgb(247,137,137);
+ Foreground: #FFFFFF;
+ }
+
+ Button.danger[IsPressed=true] {
+ BorderFill: rgb(221,97,97);
+ Background: rgb(221,97,97);
+ }
+
+
+TextBox, .textBox, DatePicker {
+ Background: #fff;
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+ .groupPanel TextBox, DatePicker TextBox, .textBox TextBox {
+ BorderStroke: 0;
+ }
+
+ .textBox[IsKeyboardFocusWithin=true] {
+ BorderFill: #1E9FFF;
+ }
+
+.singleLine { /*单行文本框*/
+ AcceptsReturn: false;
+ HScrollBarVisibility: Hidden;
+ VScrollBarVisibility: Hidden;
+}
+
+ .singleLine #contentPresenter {
+ Padding: 3;
+ }
+
+.multiline { /*多行文本框*/
+}
+
+
+.slotLeft {
+ CornerRadius: 0,4,4,0;
+ BorderFill: #DCDFE6;
+ Background: #F5F7FA;
+ BorderThickness: 1,0,0,0;
+ BorderType: BorderThickness;
+ MarginTop: 0;
+ MarginBottom: 0;
+ MarginRight: 0;
+}
+
+RadioButton #radioButtonBorder {
+ StrokeFill: rgb(220,223,230);
+}
+
+RadioButton[IsChecked=true] #radioButtonBorder {
+ StrokeFill: #1E9FFF;
+ Fill: #1E9FFF;
+}
+
+RadioButton #optionMark {
+ StrokeFill: #1E9FFF;
+ Fill: #fff;
+}
+
+CheckBox #indeterminateMark {
+ Fill: #1E9FFF;
+}
+
+CheckBox #checkBoxBorder {
+ Background: #fff;
+ BorderFill: rgb(220,223,230);
+}
+
+CheckBox[IsChecked=true] #checkBoxBorder {
+ Background: #1E9FFF;
+ BorderFill: #1E9FFF;
+}
+
+CheckBox Polyline {
+ StrokeFill: #fff;
+}
+
+.radioGroup {
+ BorderType: BorderThickness;
+ BorderFill: rgb(220,223,230);
+ BorderThickness: 1,1,0,1;
+}
+
+ .radioGroup RadioButton {
+ BorderType: BorderThickness;
+ BorderFill: rgb(220,223,230);
+ BorderThickness: 0,0,1,0;
+ }
+
+ .radioGroup RadioButton #markPanel {
+ Visibility: Collapsed;
+ }
+
+ .radioGroup RadioButton TextBlock {
+ Margin: 5;
+ }
+
+ .radioGroup RadioButton[IsChecked=true] {
+ Background: rgb(64,158,255);
+ Foreground: #fff;
+ }
+
+.error {
+ Foreground: #f00;
+ Visibility: Collapsed;
+}
+
+ .error[DesignMode=true] {
+ Visibility: Visible;
+ }
+
+.twoLine[AttachedExtenstions.IsError=true] .error {
+ Visibility: Visible;
+}
+
+.twoLine[AttachedExtenstions.IsError=true] .textBox {
+ BorderFill: #f00;
+}
+
+ScrollBar {
+ Background: null;
+}
+
+ ScrollBar Thumb {
+ IsAntiAlias: true;
+ CornerRadius: 5;
+ }
+
+ ScrollBar[Orientation=Horizontal] {
+ Height: 12;
+ }
+
+ ScrollBar[Orientation=Vertical] {
+ Width: 12;
+ }
+
+ ScrollBar #PART_LineUpButton, ScrollBar #PART_LineDownButton {
+ Visibility: Collapsed;
+ }
+
+ComboBox {
+ Background: #fff;
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+ ComboBox[IsKeyboardFocusWithin=true] {
+ BorderFill: #1E9FFF;
+ }
+
+#DropDownPanel TextBlock {
+ MarginLeft: 5;
+ MarginTop: 2;
+ MarginBottom: 2;
+ font-size: 14;
+}
+
+#dropDownBorder {
+ ShadowBlur: 2;
+ ShadowColor: rgba(0, 0, 0, 0.4);
+ BorderStroke: 0;
+}
+
+#DropDownPanel[IsMouseOver=false] ScrollBar {
+ Visibility: Collapsed;
+}
+
+#DropDownPanel ScrollBar[Orientation=Horizontal] {
+ Height: 10;
+}
+
+#DropDownPanel ScrollBar[Orientation=Vertical] {
+ Width: 10;
+}
+
+Slider {
+ IsAntiAlias: true;
+}
+
+ Slider Thumb {
+ IsAntiAlias: true;
+ Width: 16;
+ Height: 16;
+ CornerRadius: 7;
+ BorderFill: rgb(64,158,255);
+ BorderStroke: 2;
+ Background: #fff;
+ ZIndex: 1;
+ }
+
+
+ Slider Thumb[IsMouseOver=true] {
+ animation-name: sliderMouseOver;
+ animation-duration: 0.1s;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+ }
+
+ Slider #TrackBackground {
+ CornerRadius: 2;
+ Background: rgb(228,231,237);
+ BorderStroke: 0;
+ }
+
+ Slider #decreaseRepeatButton {
+ Background: rgb(64,158,255);
+ CornerRadius: 2;
+ }
+
+ Slider[Orientation=Horizontal] #decreaseRepeatButton {
+ Height: 4;
+ MarginLeft: 5;
+ }
+
+ Slider[Orientation=Vertical] #decreaseRepeatButton {
+ Width: 4;
+ MarginBottom: 5;
+ }
+
+ProgressBar {
+ CornerRadius: 5;
+ IsAntiAlias: true;
+ BorderFill: null;
+ Background: rgb(235,238,245);
+}
+
+ ProgressBar #Indicator, ProgressBar #Animation {
+ CornerRadius: 5;
+ }
+
+NumericUpDown {
+ Background: #fff;
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+ NumericUpDown RepeatButton {
+ Width: 20;
+ Background: rgb(245,247,250);
+ }
+
+ NumericUpDown #decreaseBtn {
+ CornerRadius: 4,0,0,4;
+ }
+
+ NumericUpDown #increaseBtn {
+ CornerRadius: 0,4,4,0;
+ }
+
+ NumericUpDown #textBoxBorder {
+ BorderFill: #DCDFE6;
+ }
+
+ NumericUpDown TextBox {
+ BorderStroke: 0;
+ }
+
+.widget {
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+.widgetHead {
+ Background: linear-gradient(0 0,0 100%,#F7F7F7 0,#F0F0F0 1);
+ BorderType: BorderThickness;
+ BorderThickness: 0,0,0,1;
+ BorderFill: #DCDFE6;
+}
+
+DataGrid {
+ Foreground: #7a7a7a;
+}
+
+DataGridCellTemplate, DataGridRow, DataGrid, .DataGridCell {
+ BorderFill: rgb(235,238,245);
+}
+
+DataGridRow {
+ Height: 36;
+}
+
+ DataGridRow[IsMouseOver=true] {
+ Background: rgb(245,247,250);
+ }
+
+ DataGridRow[IsSelected=true] {
+ Background: rgb(245,247,250);
+ }
+
+DataGridColumnTemplate {
+ Height: 38;
+ FontSize: 15;
+ FontStyle: Bold;
+ Background: #fff;
+ BorderFill: rgb(235,238,245);
+}
+
+TabControl #headBorder {
+ Background: #fff;
+}
+
+TabItem > Border {
+ BorderThickness: 0,0,0,2;
+}
+
+TabItem[IsSelected=true] > Border {
+ BorderFill: #1E9FFF;
+}
+
+TabItem[IsSelected=true] {
+ Foreground: #1E9FFF;
+}
+
+TabControl[TabStripPlacement=Left] TabItem, TabControl[TabStripPlacement=Right] TabItem {
+ Width: 100%;
+ BorderType: BorderThickness;
+ BorderThickness: 0,0,0,1;
+ BorderFill: #e8e8e8;
+}
+
+ TabControl[TabStripPlacement=Left] TabItem TextBlock {
+ MarginRight: 0;
+ }
+
+ TabControl[TabStripPlacement=Left] TabItem > Border {
+ Width: 100%;
+ }
+
+TabControl[TabStripPlacement=Left] #headerPanel, TabControl[TabStripPlacement=Right] #headerPanel {
+ Width: 100;
+ Background: rgb(245,247,250);
+}
+
+.closeBtn[IsMouseOver=true] {
+ Fill: #171717;
+}
+
+.placeholder {
+ IsHitTestVisible: false;
+ Foreground: "192,196,204";
+ Visibility: Collapsed;
+}
+
+.textBox[AttachedExtenstions.IsEmpty=true] .placeholder {
+ Visibility: Visible;
+}
+
+.loginBox TextBox, .loginBox .placeholder {
+ FontSize: 16;
+}
+
+.loginBox CheckBox {
+ Foreground: #757575;
+}
+
+.searchBox Button {
+ CornerRadius: 0,4,4,0,
+}
+
+#MenuPop #menuPanel > Border, #MenuPop ContextMenu > Border {
+ Background: #fff;
+ ShadowColor: rgba(0, 0, 0, 0.4);
+}
+
+#MenuPop MenuItem[IsMouseOver=true] {
+ Background: #DCDFE6;
+}
+
+ListBoxItem {
+ Width: 100%;
+}
\ No newline at end of file