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

相关文章

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -

Java如何获取视频文件的视频时长

《Java如何获取视频文件的视频时长》文章介绍了如何使用Java获取视频文件的视频时长,包括导入maven依赖和代码案例,同时,也讨论了在运行过程中遇到的SLF4J加载问题,并给出了解决方案... 目录Java获取视频文件的视频时长1、导入maven依赖2、代码案例3、SLF4J: Failed to lo

使用Java实现获取客户端IP地址

《使用Java实现获取客户端IP地址》这篇文章主要为大家详细介绍了如何使用Java实现获取客户端IP地址,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 首先是获取 IP,直接上代码import org.springframework.web.context.request.Requ

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取