通过进程ID获取中望CAD窗体并向其发送命令

2023-11-06 19:40

本文主要是介绍通过进程ID获取中望CAD窗体并向其发送命令,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

需求:

        通过自启动多个CAD应用程序,对其进行管理,针对不同CAD程序发送不同命令。

核心功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace StartAndSendMessageCAD
{public class WindowsHandleAndProcess{//SendMessage参数private const int WM_KEYDOWN = 0X100;private const int WM_KEYUP = 0X101;private const int WM_SYSCHAR = 0X106;private const int WM_SYSKEYUP = 0X105;private const int WM_SYSKEYDOWN = 0X104;private const int WM_CHAR = 0X102;public int ProcessId = 0;public IntPtr WindowHandle = IntPtr.Zero;const int MW_CLOSE = 0x0010;[DllImport("User32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int processId);[DllImport("user32.dll")]public static extern int GetWindowTextLength(IntPtr hWnd);[DllImport("User32.dll", CharSet = CharSet.Auto)]public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int nMaxCount);[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);/// <summary>/// 获取所有指定进程下的应用程序窗口句柄/// </summary>/// <param name="processId">进程ID</param>/// <returns></returns>public Dictionary<string, IntPtr> GetWindowHandle(int processId){var windowHandles = new Dictionary<string, IntPtr>();EnumThreadWindowsCallback windowsCallback = new EnumThreadWindowsCallback(FindMainWindow2);EnumWindows(windowsCallback, IntPtr.Zero);//保持循环GC.KeepAlive(windowsCallback);// 遍历所有顶层窗体bool FindMainWindow2(IntPtr handle, IntPtr extraParameter){string windowName = GetWindowText(handle);int num;GetWindowThreadProcessId(handle, out num);if (num == processId){string windowText = windowName;if (!windowHandles.ContainsKey(windowText)){windowHandles.Add(windowText, handle);}}return true;}return windowHandles;}/// <summary>/// 通过窗体句柄获取窗体Text/// </summary>/// <param name="handle"></param>/// <returns></returns>public string GetWindowText(IntPtr handle){int length = GetWindowTextLength(handle);StringBuilder windowName = new StringBuilder(length + 1);GetWindowText(handle, windowName, windowName.Capacity);return windowName.ToString();}/// <summary>/// 获取应用程序窗口句柄/// </summary>/// <param name="processId">进程ID</param>/// <param name="keyWindowText">CAD窗体Text标识</param>/// <param name="keySecondWindowText">命令栏名称</param>/// <returns></returns>public IntPtr GetWindowHandle(int processId, string keyWindowText, string keySecondWindowText){var windowHandles = GetWindowHandle(processId);foreach (var windowHandle in windowHandles){var name = windowHandle.Key;var intPtr = windowHandle.Value;if (name.Contains(keyWindowText)){var allChildHandle = GetAllChildWindows(intPtr); //获得按钮的句柄foreach (var childWindowHandle in allChildHandle){if (childWindowHandle.Key.Contains(keySecondWindowText)){if (childWindowHandle.Value != IntPtr.Zero){return childWindowHandle.Value;}}}}}return IntPtr.Zero;}/// <summary>/// 通过某个窗体Handle获取其下所有子窗体名称及其handle/// </summary>/// <param name="handle"></param>/// <returns></returns>public Dictionary<string, IntPtr> GetAllChildWindows(IntPtr handle){var windowHandles = new Dictionary<string, IntPtr>();IntPtr childHwnd = FindWindowEx(handle, IntPtr.Zero, null, null);while (childHwnd != IntPtr.Zero){string windowsText = GetWindowText(childHwnd);if (!windowHandles.ContainsKey(windowsText)){windowHandles.Add(windowsText, childHwnd);}var windowHandlesTemp = GetAllChildWindows(childHwnd);foreach (var item in windowHandlesTemp){if (!windowHandles.ContainsKey(item.Key)){windowHandles.Add(item.Key, item.Value);}}childHwnd = FindWindowEx(handle, childHwnd, null, null);}return windowHandles;}/// <summary>/// 发送一个字符串/// </summary>/// <param name="myIntPtr">窗口句柄</param>/// <param name="Input">字符串</param>public void InputStr(IntPtr myIntPtr, string Input){byte[] ch = (ASCIIEncoding.ASCII.GetBytes(Input));for (int i = 0; i < ch.Length; i++){SendMessage(myIntPtr, WM_CHAR, ch[i], 0);}}}
}

如何调用:

 static void Main(string[] args){string exePath = @"C:\Program Files\ZWSOFT\ZWCAD 2023\ZWCAD.EXE";Process process = new Process();process.StartInfo.FileName = exePath;process.StartInfo.CreateNoWindow = true;process.Start();Console.WriteLine("CAD ProcessId is : " + process.Id);Thread.Sleep(10 * 1000);var handleAndProcess = new WindowsHandleAndProcess();var intPtr = handleAndProcess.GetWindowHandle(process.Id,"ZWCAD 20","CommandLine");if (intPtr != IntPtr.Zero){handleAndProcess.InputStr(intPtr, "some\n");}Console.ReadKey();}

示意图:

 

这篇关于通过进程ID获取中望CAD窗体并向其发送命令的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/358659

相关文章

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

PowerShell中15个提升运维效率关键命令实战指南

《PowerShell中15个提升运维效率关键命令实战指南》作为网络安全专业人员的必备技能,PowerShell在系统管理、日志分析、威胁检测和自动化响应方面展现出强大能力,下面我们就来看看15个提升... 目录一、PowerShell在网络安全中的战略价值二、网络安全关键场景命令实战1. 系统安全基线核查

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试