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://www.rhkb.cn/news/374671.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++入门到进阶(图文详解,持续更新中)

C入门到进阶&#xff08;图文详解&#xff0c;持续更新中&#xff09; 目录 C入门到进阶&#xff08;图文详解&#xff0c;持续更新中&#xff09; 数据 数据类型 基本数据类型/内置数据类型 C常用运算符 赋值运算符 关系运算符 逻辑运算符 杂项运算符 数据的本地化…

NFS服务器、autofs自动挂载综合实验

综合实验 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供 www.rhce.com 虚拟主机 4、该虚拟主机的documentroot目录在 /nfs/rhce 目录 5、该目录由 node02 主机…

jmeter-beanshell学习7-props获取全局变量和设置全局变量

继续写点不痛不痒的小东西。第一篇写了vars设置变量&#xff0c;但是vars只能作用在同一个线程组。跨线程组情况比较少&#xff0c;要是用到跨线程组&#xff0c;有个pros&#xff0c;用法和vars一样。 在setup线程组设置变量a&#xff0c;执行的时候&#xff0c;jmeter会先执行…

Windows 电脑查看 WiFi 密码的方法都有哪些?

从设置面板中查看 当你使用的是笔记本电脑并且连接 WiFi 之后可以在设置面板中查看 WiFi 密码&#xff0c;首先打开设置界面&#xff0c;然后点击网络和 Internet&#xff0c;找到 WiFi 之后点击进入&#xff0c;然后点击管理已知网络。 然后点击已经连接好的无线网络。 进入之…

国产化趋势下源代码数据防泄密的信创沙盒的方案分享

随着国产化的大力推进&#xff0c;越来越多的企事业单位在逐步替换Windows、Linux等操作系统的使用。那么什是国产化了&#xff1f;国产化是指在产品或服务中采用国内自主研发的技术和标注&#xff0c;替代过去依赖的他国的产品和服务&#xff0c;国产化又被称之为“信创”&…

215.Mit6.S081-实验三-page tables

在本实验室中&#xff0c;您将探索页表并对其进行修改&#xff0c;以简化将数据从用户空间复制到内核空间的函数。 一、实验准备 开始编码之前&#xff0c;请阅读xv6手册的第3章和相关文件&#xff1a; kernel/memlayout.h&#xff0c;它捕获了内存的布局。kernel/vm.c&…

macOS系统下载navicat安装包

链接: https://pan.baidu.com/s/1SqTIXNL-B8ZMJxIBu1DfIw?pwdc1z8 提取码: c1z8 安装后效果

虚幻引擎 快速的色度抠图 Chroma Key 算法

快就完了 ColorTolerance_PxRange为容差&#xff0c;这里是0-255的输入&#xff0c;也就是px单位&#xff0c;直接用0-1可以更快 Key为目标颜色

Kafka第四篇——生产数据总体概括,源码解析分区策略,数据收集器,Sender发送线程,key值

目录 流程图以及总体概述 拦截器 分区器以及分区计算策略 为啥进行分区计算&#xff1f; producer生产者怎么知道有哪些分区&#xff1f; 分区计算 如何自定义实现分区器&#xff1f; 想说的在图里啦&#xff01;宝宝&#xff01;&#x1f4a1; ​编辑 如果key值忘记传递了呢&a…

python+selenium-UI自动框架之[优化]元素查找和BasePage页面

痛点&#xff1a;在页面查找元素的时候会遇到找不到或者其他无法处理某个字段的情况&#xff0c;又或者想要在输出的log或者report里面显示这个字段名称&#xff0c;这时候加上字段名称就很重要&#xff01; [3]pythonselenium - UI自动框架之封装查找元素https://mp.csdn.net…

电脑的D盘E盘F盘突然消失了 电脑只剩下C盘了其他盘怎么恢复

现如今随着时代的发展&#xff0c;无纸化办公成为主流&#xff0c;这主要归功于电脑&#xff0c;能够通过电脑完成的工作绝不使用纸质文件&#xff0c;这不仅提高了工作效率&#xff0c;也让一些繁杂的工作变的更加简单。不过电脑毕竟是电子产品&#xff0c;不可避免的会出现一…

通信协议_Modbus协议简介

概念介绍 Modbus协议&#xff1a;一种串行通信协议&#xff0c;是Modicon公司&#xff08;现在的施耐德电气Schneider Electric&#xff09;于1979年为使用可编程逻辑控制器&#xff08;PLC&#xff09;通信而发表。Modbus已经成为工业领域通信协议的业界标准&#xff08;De f…

Navicat导入sql文件

文章目录 Navicat导入SQL文件&#xff0c;使用默认导入&#xff0c;不做任何修改报错尝试一修改运行时的选择 尝试二修改my.ini的配置文件 Navicat导入SQL文件&#xff0c;使用默认导入&#xff0c;不做任何修改报错 尝试一 修改运行时的选择 取消勾选 ‘每个运行中运行多重查…

一键掌握天气动态 - 基于Vue和高德API的实时天气查询

前言 本文将学习如何使用Vue.js快速搭建天气预报界面,了解如何调用高德地图API获取所需的天气数据,并掌握如何将两者有机结合,实现一个功能丰富、体验出色的天气预报应用 无论您是前端新手还是有一定经验,相信这篇教程都能为您带来收获。让我们一起开始这段精彩的Vue.js 高德…

Mac的系统数据怎么删除 cleanmymac会乱删东西吗 cleanmymac有用吗

作为一款专业级的苹果电脑清理软件&#xff0c;CleanMyMac可以精准识别系统垃圾&#xff0c;有效防止Mac系统数据被误删。软件可以深入系统底层&#xff0c;清理无用的系统数据&#xff0c;优化苹果电脑设置&#xff0c;提升Mac系统性能。有关Mac的系统数据可以删吗&#xff0c…

拥抱 AGI:PieDataCS 引领云原生数据计算系统新范式

自2023年后&#xff0c;人工智能技术进入了一个更为成熟和广泛应用的阶段&#xff0c;人工通用智能&#xff08;AGI&#xff09;这一概念也成为了科技界和产业界热议的焦点。本文将结合 AGI 时代背景&#xff0c;从架构设计到落地实践&#xff0c;详细介绍拓数派云原生数据计算…

HTAP 数据库在国有大行反洗钱场景的应用

导读 在金融领域&#xff0c;随着数字化服务的深入和监管要求的提高&#xff0c;反洗钱工作变得尤为关键。洗钱活动不仅威胁金融安全&#xff0c;也对社会秩序构成挑战。本文深入探讨了国产 HTAP 分布式数据库 TiDB 在某国有大行反洗钱系统中的应用实践。 依托 TiDB 构建的新…

springboot大学校园二手书交易APP-计算机毕业设计源码25753

摘 要 在数字化与移动互联网迅猛发展的今天&#xff0c;人们对于图书的需求与消费方式也在悄然改变。为了满足广大读者对图书的热爱与追求&#xff0c;我们倾力打造了一款基于Android平台的图书交易APP。这款APP不仅汇聚了海量的图书资源&#xff0c;提供了便捷的交易平台&…

usbserver工程师手记(三)手工开通 OTP功能

1、设定密钥&#xff0c;用户自行选择一个密钥&#xff0c;以下以密钥为 EAZAYOKNGETBOPC5 为例说明 2、usb server 配置otp 密钥&#xff0c;目前还没有UI 界面开通&#xff0c;后续版本会支持从管理界面开通 curl -X POST -H Content-Type: application/json -H Accept: app…

【深度学习入门篇 ②】Pytorch完成线性回归!

&#x1f34a;嗨&#xff0c;大家好&#xff0c;我是小森( &#xfe61;ˆoˆ&#xfe61; )&#xff01; 易编橙终身成长社群创始团队嘉宾&#xff0c;橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官、CSDN人工智能领域优质创作者 。 易编橙&#xff1a;一个帮助编程小…