通过进程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

相关文章

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

使用Python的requests库来发送HTTP请求的操作指南

《使用Python的requests库来发送HTTP请求的操作指南》使用Python的requests库发送HTTP请求是非常简单和直观的,requests库提供了丰富的API,可以发送各种类型的HT... 目录前言1. 安装 requests 库2. 发送 GET 请求3. 发送 POST 请求4. 发送

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全