windows系統默認句柄數?小編工作的單位性質偏向于服務制造大家都知道,中國的高端裝備基本都依賴進口,而其自帶CAM軟件一般都是全封閉的,不開放API接口但是在工業互聯網時代,設備聯網,生産數據上雲已經是大勢所趨那麼,如何在國外技術封鎖的情況下實現第三方軟件的數據獲取呢?,下面我們就來說一說關于windows系統默認句柄數?我們一起去了解并探讨一下這個問題吧!
小編工作的單位性質偏向于服務制造。大家都知道,中國的高端裝備基本都依賴進口,而其自帶CAM軟件一般都是全封閉的,不開放API接口。但是在工業互聯網時代,設備聯網,生産數據上雲已經是大勢所趨。那麼,如何在國外技術封鎖的情況下實現第三方軟件的數據獲取呢?
在Windows系統下,有一個東西叫句柄,它是Windows編程的基礎,隻要是運行在Windows上的軟件都繞不開它。本文就帶大家學習如何利用底層句柄來實現第三方軟件的交互。
句柄及其作用關于句柄的官方解釋就不在此處過多提及,一般剛接觸這個概念的人也看不懂。掌握句柄隻需要理解這幾點:
1、句柄不是什麼玄乎的東西,它隻是一個4字節(64系統下為8字節,後續文章都以32位來展開文章)的數值。但是它是唯一的,系統在啟動時會建立一個句柄表,程序在Windows系統上運行時由系統自動分配給每一個對象,例如:窗體句柄、窗體控件句柄(輸入框、按鈕)、文件句柄等。
2、句柄單獨存在于一塊固定的區域,由于對象在内存中的地址可能會實時變化,但是系統會将這個變化的地址通過唯一不變的句柄綁定好,以不變應萬變。
3、你可以将其理解成類似指針,通過它你能找到程序中的每一個對象。
4、雖然句柄類似指針,可以通過句柄找到對應的對象,但是你卻不能像使用指針那樣使用句柄,必須通過系統封裝的API去使用。
如下圖,是通過spy 查看GifCam(一個第三方gif制作小軟件)各控件的句柄。圖中Handle:000A07F0就是Rec按鈕的句柄,獲得了它的句柄,就可以通過系統API控制按鈕的各項功能,比如單擊開始錄制。
spy 查看GifCam
類比理解如果上述表述大家還不能理解的話,請看類比理解:
大家都看過古裝電視劇吧?在古代,每個奴隸身上都會被烙上一個奴隸印記,并且每個印記的編号不同。奴隸主在管理奴隸時,都是通過印記來管理的。但是每個奴隸本身也都是有名字的。類比到句柄就可以這樣理解:奴隸這個實物就是對象,他的名字就是他在計算機中的地址(名字可以随意變,奴隸想更名改姓重新開始生活,但是奴隸主會願意嗎?),奴隸印記就是句柄(不管你怎麼更名改姓,隻要這個奴隸印記在,你就跑不掉)。
圖示理解:
句柄示意圖
句柄實際應用前文講了很多關于句柄理解的内容,此處開始回到實際項目中,一起探究句柄在實際項目中如何發揮作用。
需求:如下圖,需要實時獲取圖中振幅和相位的值。
需獲取數據的窗體
程序設計思路:
程序設計思路
利用CSharp實現上述功能需要引入using System.Runtime.InteropServices;和using System.Diagnostics;
System.Diagnostics:負責進程相關
System.Runtime.InteropServices:dllImport特性,負責調用系統API。
代碼實現:
class Program
{
//系統API
//通過窗體标題尋找窗體句柄
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(
string lpClassName,
string lpWindowName
);
//遍曆主窗體下的所有句柄(各控件對象)
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(
IntPtr hWnd1,
IntPtr hWnd2,
string lpsz1,
string lpsz2
);
//通過對象句柄獲取控件文字内容
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
//通過對象句柄獲取控件類名
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
//通過對象句柄給對象發系統消息(系統定義的消息标識:如單擊、輸入文字等)
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessages(IntPtr hWnd, // 信息發往的窗口的句柄
int msg, // 消息ID
int wParam, // 參數1
int lParam //參數2
);
//---------------------------
static void Main(string[] args)
{
bool find = false;
IntPtr hwnd = IntPtr.Zero;
while (!find)
{
string title = null;
Process[] process = Process.GetProcesses();
foreach (Process p in process)
{
title = p.MainWindowTitle.ToString();
if (title.Contains("iBalance"))
{
hwnd = p.Handle;
find = true;
break;
}
}
// Console.WriteLine(title);
if (find) hwnd = FindWindow(null, title);
else
{
ProcessStartInfo info = new ProcessStartInfo(@"C:\Program Files\ANCA\RN31.1-1\TG7\BIN\Vibe_Monitor.exe");
Process.Start(info);
Thread.Sleep(1000);
Console.WriteLine("open it");
}
}
find = false;
if (hwnd != IntPtr.Zero)
{
StringBuilder sb_text = new StringBuilder(1024);
StringBuilder sb_class= new StringBuilder(1024);
IntPtr child = IntPtr.Zero ;
do
{
child = FindWindowEx(hwnd, child, null, null);
GetWindowText(child,sb_text,sb_text.Capacity);
// Console.Write(sb_text.ToString() "::CLASS::");
GetClassName(child, sb_class, sb_class.Capacity);
//Console.WriteLine(sb_class.ToString());
if (sb_text.ToString().Contains(".") && sb_class.ToString() == "Static")
{
find = true;
break;
}
sb_text.Remove(0,sb_text.Length);
sb_class.Remove(0, sb_class.Length);
} while (child != IntPtr.Zero);
StringBuilder msg = new StringBuilder();
if (find)
{
int i = 0;
string msg_combine = string.Empty;
try
{
while (true)
{
Thread.Sleep(10);
sb_text.Remove(0, sb_text.Length);
GetWindowText(child, sb_text, sb_text.Capacity);
int index = sb_text.ToString().IndexOf("\n");
msg_combine = DateTime.Now.ToString() ":" "震幅:" sb_text.ToString().Substring(0, index) "相位:" sb_text.ToString().Substring(index 1, sb_text.ToString().Length - index - 1);
i ;
Console.WriteLine(msg_combine "::" i);
msg.AppendLine(msg_combine);
if (i == 1024)
{
i = 0;
StreamWriter sw = new StreamWriter("msg.txt", true, Encoding.UTF8);
sw.WriteLine(msg.ToString());
msg = new StringBuilder();
sw.Flush();
sw.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("程序被關閉");
}
}
}
Console.Read();
}
}
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!