Windows环境+C#实现显示接口测试

代码如下:

using Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tools;
using DisplayMode = Models.DisplayMode;namespace TestItem
{public partial class VideoTestManager : Form{private string originalDirectory = System.Environment.CurrentDirectory; // 保存当前目录private string programName = string.Empty;//程式名称public event Action<bool> CallExit = null;//回调函数private bool isPass = false;private string readValues = null; // 测试参数private string testArgs = null;//测试参数private List<string> testItem=null;//测试项目private string playFileName = string.Empty;//播放文件名称private List<DisplayEntity> displayEntity;//显示实体private int random_number = 0;//随机数private int input_number = 0;//输入数#region 构造函数//显示模式public VideoTestManager(){InitializeComponent();this.CallExit += (isPass) => { }; // 初始化事件this.Load += VideoTestManager_Load;this.FormClosing += VideoTestManager_FormClosing;this.KeyDown += VideoTestManager_KeyDown;this.KeyPreview = true; // Enable the form to receive key events}#endregion#region 窗体加载private const byte VK_LEFT = 0x25;private const byte VK_RIGHT = 0x27;private async void VideoTestManager_Load(object sender, EventArgs e){if (await this.GetTestArgs()){this.SetHeaderStyle(); // 设置表头信息样式this.displayEntity = new List<DisplayEntity>();//初始化显示实体timer_Test.Enabled = true;}}#endregion#region 切屏显示/// <summary>/// 切屏显示/// </summary>/// <param name="mode"></param>/// <exception cref="ArgumentOutOfRangeException"></exception>private void SwitchDisplayMode(DisplayMode mode){string argument;switch (mode){case DisplayMode.Internal:argument = "/internal";break;case DisplayMode.Clone:argument = "/clone";break;case DisplayMode.Extend:argument = "/extend";break;case DisplayMode.External:argument = "/external";break;default:throw new ArgumentOutOfRangeException();}Process.Start("DisplaySwitch.exe", argument);}#endregion#region 获取测试参数private async Task<bool> GetTestArgs(){try{//获取程式名称this.programName = AuxiliaryItemArray.GetProgramName(this.lbl_ShowResult) != null ? AuxiliaryItemArray.GetProgramName(this.lbl_ShowResult) + @".exe" : null;if (this.programName == null)return false;// 获取测试参数this.testArgs = AuxiliaryItemArray.GetTestParameter(this.originalDirectory, this.programName, this.lbl_ShowResult);if (this.testArgs == null)return false;//解析参数string[] args = this.testArgs.Split('|');this.playFileName = args[1].Split('=')[1];this.testItem = new List<string>();this.testItem = args[0].Split(',').ToList();this.lbl_TestArgs.BeginInvoke(new Action(() => { this.lbl_TestArgs.Text= args[0];}));return this.testItem.Count>0;}catch (Exception ex){this.Invoke(new Action(() =>{AuxiliaryItemArray.Loginfo($@"获取测试参数:{ex.Message}", false, lbl_ShowResult);}));return false;}}#endregion#region 播放视频/// <summary>/// 播放视频/// </summary>/// <param name="playFileName">播放文件</param>/// <returns></returns>private async Task<bool>Mp4Play(string playFileName){try{//设置播放器URL// 获取当前目录string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;// 拼接视频文件路径string videoPath = Path.Combine(currentDirectory, "Video", playFileName);if (File.Exists(videoPath)){// 设置播放器URLwmpPlayer.URL = videoPath;// 设置循环播放模式wmpPlayer.settings.setMode("loop", true);return true;}else{this.Invoke(new Action(() =>{AuxiliaryItemArray.Loginfo("视频文件未找到: " + videoPath, false, lbl_ShowResult);}));return false;}}catch(Exception ex){this.Invoke(new Action(() =>{AuxiliaryItemArray.Loginfo($@"播放MP4错误:{ex.Message}", false, lbl_ShowResult);}));return false;}}#endregion#region 设置表头信息样式private void SetHeaderStyle(){// 设置参数列宽度,使用百分比this.tabPanel_Args.ColumnStyles[0].SizeType = SizeType.Percent;this.tabPanel_Args.ColumnStyles[0].Width = 25;this.tabPanel_Args.ColumnStyles[1].SizeType = SizeType.Percent;this.tabPanel_Args.ColumnStyles[1].Width = 25;this.tabPanel_Args.ColumnStyles[2].SizeType = SizeType.Percent;this.tabPanel_Args.ColumnStyles[2].Width = 25;this.tabPanel_Args.ColumnStyles[3].SizeType = SizeType.Percent;this.tabPanel_Args.ColumnStyles[3].Width = 25;}#endregion#region 关闭窗体private void VideoTestManager_FormClosing(object sender, FormClosingEventArgs e){this.readValues = JsonConvert.SerializeObject(this.displayEntity, Formatting.Indented);//将实体类转换成json文件AuxiliaryItemArray.UpdateJsonInfo(this.programName, this.readValues, this.isPass, this.originalDirectory, this.lbl_ShowResult);this.ProcessExit(this.isPass);}#endregion#region 关闭进程private void ProcessExit(bool isPass){CallExit?.Invoke(isPass);}#endregion#region 定时触发器private async void timer_Test_Tick(object sender, EventArgs e){timer_Test.Enabled = false;bool testResult = true;string[] testArgsValues = this.testArgs.Split(',');foreach (var a in testArgsValues){if (!this.displayEntity.Any(d => d.ProtName == a)){testResult = false;break;}}if (testResult){this.readValues = JsonConvert.SerializeObject(this.displayEntity, Formatting.Indented);//将实体类转换成json文件AuxiliaryItemArray.UpdateJsonInfo(this.programName, this.readValues, true, this.originalDirectory, this.lbl_ShowResult);this.ProcessExit(this.isPass);}else{DisplayManager displayManager = new DisplayManager();DisplayEntity tempdata = new DisplayEntity();displayManager.DetectDisplays();if (displayManager.displayEntity.Count > 0){foreach (DisplayEntity ds in displayManager.displayEntity){this.currentTestPort = new DisplayEntity();if (!displayEntity.Any(d => d.ProtName == ds.ProtName) || displayEntity.Count == 0){this.currentTestPort = ds;tempdata = ds;TestDisplayPort();//测试显示接口if (ds.DeviceName.ToUpper().Contains("DISPLAY1")){this.SwitchDisplayMode(DisplayMode.Internal);//仅第一个屏显示this.currentTestPort.SwDisplayMode = DisplayMode.Internal;break;}else{this.SwitchDisplayMode(DisplayMode.External);//仅第二个屏显示this.currentTestPort.SwDisplayMode = DisplayMode.External;break;}}}}}}#endregion#region 显示接口测试/// <summary>/// 测试显示接口/// </summary>/// <param name="protName">接口名称</param>private async void TestDisplayPort(){this.input_number = 0;Random random = new Random();this.random_number = random.Next(1,9);this.lbl_ShowResult.BeginInvoke(new Action(() => {this.lbl_ShowResult.ForeColor = Color.SteelBlue;this.lbl_ShowResult.Text = $@"{this.currentTestPort.ProtName}接口测试中..";}));this.lbl_Random.BeginInvoke(new Action(() => {this.lbl_Random.Text = this.random_number.ToString();}));await this.Mp4Play(this.playFileName);//Mp4播放waitTime = 20;timer_random.Enabled = true;}#endregion#region 随机数检测private int waitTime = 0;//等待时间private DisplayEntity currentTestPort;//当前测试接口private async void timer_random_Tick(object sender, EventArgs e){if(waitTime==0){if(currentTestPort.ProtName=="VGA"){this.lbl_VGA_result.Text = "FAIL";this.lbl_VGA_result.ForeColor = Color.Red;}else if(currentTestPort.ProtName == "DVI"){this.lbl_DVI_result.Text = "FAIL";this.lbl_DVI_result.ForeColor = Color.Red;}else if (currentTestPort.ProtName == "DP"){this.lbl_DP_result.Text = "FAIL";this.lbl_DP_result.ForeColor = Color.Red;}else if (currentTestPort.ProtName == "HDMI"){this.lbl_HDMI_result.Text = "FAIL";this.lbl_HDMI_result.ForeColor = Color.Red;}this.lbl_ShowResult.BeginInvoke(new Action(() => {this.lbl_ShowResult.Text = $@"{this.currentTestPort.ProtName}接口测试Fail";this.lbl_ShowResult.ForeColor = Color.Red;}));this.SwitchDisplayMode(DisplayMode.Extend);//扩展屏显示await this.Mp4Play(this.playFileName);//Mp4播放timer_random.Enabled = false;this.timer_Test.Enabled = true;}else{if(this.input_number==0)waitTime--;else{if (currentTestPort.ProtName == "VGA"){this.lbl_VGA_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";this.lbl_VGA_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;}else if (currentTestPort.ProtName == "DVI"){this.lbl_DVI_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";this.lbl_DVI_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;}else if (currentTestPort.ProtName == "DP"){this.lbl_DP_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";this.lbl_DP_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;}else if (currentTestPort.ProtName == "HDMI"){this.lbl_HDMI_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";this.lbl_HDMI_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;}this.timer_random.Enabled = false;if (this.input_number == this.random_number){this.currentTestPort.TestResult = "PASS";this.displayEntity.Add(this.currentTestPort);}this.lbl_ShowResult.BeginInvoke(new Action(() => {this.lbl_ShowResult.Text = $@"{this.currentTestPort.ProtName}接口测试PASS";this.lbl_ShowResult.ForeColor = Color.Green;}));this.waitTime = 0;this.SwitchDisplayMode(DisplayMode.Extend);//扩展屏显示await this.Mp4Play(this.playFileName);//Mp4播放this.timer_Test.Enabled = true;}}}#endregion#region 键盘入事件/// <summary>/// 键盘键入事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void VideoTestManager_KeyDown(object sender, KeyEventArgs e){// Check if the pressed key is a number key (both top row and numpad)if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)){// Get the digit from the key codeint digit = (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) ? e.KeyCode - Keys.D0 : e.KeyCode - Keys.NumPad0;// Handle the digit input, for example:this.input_number = digit;}}#endregion}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using Models;namespace Tools
{public class DisplayManager{public List<DisplayEntity> displayEntity; // 显示实体[DllImport("user32.dll")]private static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);[StructLayout(LayoutKind.Sequential)]private struct DISPLAY_DEVICE{public int cb;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string DeviceName;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]public string DeviceString;public int StateFlags;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]public string DeviceID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]public string DeviceKey;}/// <summary>/// 检测接入的显示接口/// </summary>public void DetectDisplays(){displayEntity = new List<DisplayEntity>();// 使用WMI查询显示器连接类型ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\wmi", "SELECT * FROM WmiMonitorConnectionParams");foreach (ManagementObject queryObj in searcher.Get()){uint videoOutputTechnology = (uint)queryObj["VideoOutputTechnology"];string connectionType = GetConnectionType(videoOutputTechnology);displayEntity.Add(new DisplayEntity{DeviceIndex = displayEntity.Count,DeviceName = queryObj["InstanceName"]?.ToString(),//DeviceString = DeviceString = d.DeviceString,ProtName = connectionType});}DeviceString();}/// <summary>/// 检测接入的显示接口/// </summary>public void DeviceString(){DISPLAY_DEVICE d = new DISPLAY_DEVICE();d.cb = Marshal.SizeOf(d);int deviceIndex = 0;//this.displayEntity = new List<DisplayEntity>();while (EnumDisplayDevices(null, (uint)deviceIndex, ref d, 0)){if (deviceIndex < displayEntity.Count){displayEntity[deviceIndex].DeviceString = d.DeviceString;displayEntity[deviceIndex].DeviceName = d.DeviceName;}//Console.WriteLine($"Device {deviceIndex}: {d.DeviceName} - {d.DeviceString}");//this.displayEntity.Add(new DisplayEntity()//{//    DeviceIndex = deviceIndex,//    DeviceName = d.DeviceName,//    DeviceString = d.DeviceString//});deviceIndex++;}}/// <summary>/// 获取连接的显示类型/// </summary>/// <param name="videoOutputTechnology"></param>/// <returns></returns>private string GetConnectionType(uint videoOutputTechnology){// 根据WMI查询结果中的VideoOutputTechnology值返回连接类型switch (videoOutputTechnology){case 0x00000000: return "HD15 (VGA)";case 0x00000001: return "S-Video";case 0x00000002: return "Composite video";case 0x00000003: return "Component video (YPbPr)";case 0x00000004: return "DVI";case 0x00000005: return "HDMI";case 0x00000006: return "LVDS";case 0x00000007: return "DJPN";case 0x00000008: return "SDI";case 0x00000009: return "DP";//case 0x00000009: return "DisplayPort external";//case 0x0000000A: return "DisplayPort embedded";case 0x0000000A: return "VGA";case 0x0000000B: return "UDI external";case 0x0000000C: return "UDI embedded";case 0x0000000D: return "SDTVDongle";case 0x80000000: return "Miracast";case 0x80000001: return "Indirect Display";default: return "Unknown";}}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;namespace Models
{public class DisplayEntity{/// <summary>/// 硬件指针/// </summary>public int DeviceIndex { get; set; }/// <summary>/// 硬件名称/// </summary>public string DeviceName { get; set; }/// <summary>/// 硬件字符串/// </summary>public string DeviceString { get; set; }/// <summary>/// 接口名称/// </summary>public string ProtName { get; set; }/// <summary>/// 切换的显示模式/// </summary>public DisplayMode SwDisplayMode { get; set; } = DisplayMode.Internal;/// <summary>/// 测试结果/// </summary>public string TestResult { get; set; } = "Wait";}public enum DisplayMode{Internal,//仅电脑屏幕Clone,//复制Extend,//扩展External//仅第二屏幕}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3226108.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

WPF引入多个控件库使用

目的 设计开发时有的控件库的一部分符合我们想要的UI样式&#xff0c;另一部分来自另一个控件库&#xff0c;想把两种库的样式做一个整合在同一个控件资源上。单纯通过引用的方式会导致原有样式被覆盖。这里通过设置全局样式的方式来实现。 1.安装控件库nuget包&#xff1a;H…

重生奇迹mu自带四重箭加穿透的弓

1.烈风射手 烈风射手是自带四重箭加穿透的弓之一。该职业的技能树中有一个叫做“四箭连发”的技能&#xff0c;可以让玩家在一次攻击中发射四支箭矢&#xff0c;每支箭矢都带有穿透效果。 2.影魅猎人 影魅猎人也是自带四重箭加穿透的弓之一。该职业的技能树中有一个叫做“穿…

开源项目有哪些机遇与挑战

目录 1.概述 2.开源项目的发展趋势 2.1. 开源项目的发展现状 2.2. 开源社区的活跃度 2.3. 开源项目在技术创新中的作用 3.参与开源的经验分享 3.1. 选择开源项目 3.2. 理解项目结构和文档 3.3. 贡献代码 3.4. 与开源社区的合作 3.5. 学习和成长 4.开源项目的挑战 …

跑GCN收敛实验时遇到的Python环境问题

错误1&#xff1a; 报错提示&#xff1a;No module named sklearn.utils.linear_assignment_ 原因&#xff1a;linear_assignment 函数从0.21开始被弃用了&#xff0c;并且将在0.23版本中移除。 解决方法&#xff1a;降低scikit-learn版本&#xff08;本人通过该方法解决&#…

Kimi携手思维链,点亮论文写作之路!

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 在学术的海洋中&#xff0c;思想的火花常常在静谧的图书馆角落或深夜的电脑屏幕前迸发。今天分享的内容是一种高阶的论文写作方法&#xff1a;Kimi思维链。 Kimi&#xff0c;一个由月之…

Spark-RDD和共享变量

概览 每个Spark应用程序都由一个driver program 组成&#xff0c;该驱动程序运行我们编写的main函数&#xff0c;并在集群上执行各种 并行 操作。Spark提供的主要抽象是一个 弹性分布式数据集&#xff08;RDD&#xff09;&#xff0c;它是一个跨集群节点分区的元素集合&#x…

Linux 一键部署Mysql 8.4.1 LTS

mysql 前言 MySQL 是一个基于 SQL(Structured Query Language)的数据库系统,SQL 是一种用于访问和管理数据库的标准语言。MySQL 以其高性能、稳定性和易用性而闻名,它被广泛应用于各种场景,包括: Web 应用程序:许多动态网站和内容管理系统(如 WordPress)使用 MySQL 存…

性价比高的照明品牌有哪些?揭秘五款性价比高的照明灯

我国整体近视率呈低龄高发态势。为什么会这样呢?原因不外乎就是用眼时间长、不良坐姿、不合适的用眼环境。国内的学习压力一直就没有降低过&#xff0c;这也就导致学生课业多&#xff0c;晚上挑灯读写成常态。高强度的用眼自然会对眼睛伤害大。护眼台灯就是一个不错的选择&…

【Git基本操作】添加文件 | 修改文件 | 及其各场景下.git目录树的变化

目录 1. 添加文件&add操作和commit操作 2. .git树状目录的变化 3. git其他操作 4. 修改文件 4.1 git status 4.2 git diff 1. 添加文件&add操作和commit操作 add操作&#xff1a;将工作区中所有文件的修改内容 添加进版本库的暂存区中。commit操作&#xff1a;…

《mysql篇》--索引事务

索引 索引的介绍 索引是帮助MySQL高效获取数据的数据结构&#xff0c;是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针&#xff0c;因为索引本身也比较大&#xff0c;所以索引一般是存储在磁盘上的&#xff0c;索引的种类有很多&#xff0c;不过如果没有特殊…

Anaconda+Pycharm 项目运行保姆级教程(附带视频)

最近很多小白在问如何用anacondapycharm运行一个深度学习项目&#xff0c;进行代码复现呢&#xff1f;于是写下这篇文章希望能浅浅起到一个指导作用。 附视频讲解地址&#xff1a;AnacondaPycharm项目运行实例_哔哩哔哩_bilibili 一、项目运行前的准备&#xff08;软件安装&…

突破AI性能瓶颈 揭秘LLaMA-MoE模型的高效分配策略

获取本文论文原文PDF&#xff0c;请在公众号【AI论文解读】留言&#xff1a;论文解读 本文介绍了一种名为“LLaMA-MoE”的方法&#xff0c;通过将现有的大型语言模型&#xff08;LLMs&#xff09;转化为混合专家网络&#xff08;MoE&#xff09;&#xff0c;从而解决了训练MoE…

【Linux】升级FastJSON版本-jar

摘要 在长期运行的应用服务器上&#xff0c;近期的安全漏洞扫描揭示了fastjson组件存在潜在的安全隐患&#xff08;FastJSON是一个Java 语言实现的 JSON 解析器和生成器。FastJSON存在远程代码执行漏洞&#xff0c;恶意攻击者可以通过此漏洞远程执行恶意代码来入侵服务器&…

医疗器械的售后与服务探讨

彩虹医械维修培训 8月长期班报名啦 学技术 考证书 技术支持 大型医疗设备的宕机不仅会造成医疗机构直接的巨额经济损失&#xff0c;宕机期间的损失甚至可以超过维修费用&#xff0c;而且还可能会耽误患者的病情检查&#xff0c;因此对医疗设备的定期保养已经成为各级医院的…

Kafka-02 @KafkaListener学习

一. 引入依赖 SpringBoot 和 Kafka 搭配使用的场景&#xff0c;引入 spring-kafka 即可&#xff1b; <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>2.8.11</version>…

vs2022报找不到.netframework,version=V4.8的引用程序集

最近在win7上面安装vs2022 17.6版本&#xff0c;打开.net项目编译的时候出现了这个提示。 解决方案就是安装.net4.8开发者工具包&#xff0c;不是运行工具包。 安装完成之后在项目的属性中修改&#xff1a; 点击下载&#xff1a;.net4.8开发者工具包

HTML+CSS+JS 实现3D风吹草动效果(B站视频)

效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>3D effect&…

CAD应用程序开发工具CST CAD Navigator 1.4.0.1 正式发布—— 带来了 G 代码生成功能

CST CAD Navigator是一款兼容Windows和Linux的CAD应用程序。在其简单的界面下&#xff0c;有一个可以快速查看2D图纸和3D模型的强大核心。软件可以轻松地导入和导出文件&#xff0c;获取尺寸&#xff0c;并创建截面视图。 下载最新版CST CAD Navigatorhttps://www.evget.com/p…

SpringIOC原理

SpringIOC原理 1.概念 Spring通过一个配置文件描述Bean及Bean之间的依赖关系&#xff0c;利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。Spring的IOC容器在完成这些底层工作的基础上&#xff0c;还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、…

台灯的种类有哪些?五款护眼台灯测评分析

随着时代的发展&#xff0c;现在市面上出现了更为护眼的选择——LED台灯。然而&#xff0c;面对琳琅满目的产品&#xff0c;挑选一款合适的台灯似乎成了一项挑战。那么&#xff0c;我们应该如何从众多选项中&#xff0c;找到那款既实用又护眼的台灯呢&#xff1f;以下内容将为您…