C# VB.NET多進程-管道通信,命名管道(Named Pipes)

要向已運行的進程發送特定命令(如/exit),而不是啟動新進程,需要使用進程間通信(IPC)機制。以下是幾種常見的實現方法:

一、使用命名管道(Named Pipes)

如果ABC.EXE支持通過命名管道接收命令,可以這樣實現:

1. 在 ABC.EXE 中添加管道服務器代碼
' ABC.EXE 中添加以下代碼(需在啟動時運行)
Imports System.IO.PipesPublic Sub StartPipeServer()Dim thread As New Threading.Thread(AddressOf PipeServerThread)thread.IsBackground = Truethread.Start()
End SubPrivate Sub PipeServerThread()TryWhile TrueUsing server As New NamedPipeServerStream("ABCControlPipe")Console.WriteLine("等待客戶端連接...")server.WaitForConnection()Using reader As New StreamReader(server)Dim command As String = reader.ReadLine()Console.WriteLine($"收到命令: {command}")' 處理命令If command = "/exit" Then' 執行退出邏輯Application.Exit()End IfEnd UsingEnd UsingEnd WhileCatch ex As ExceptionConsole.WriteLine($"管道服務器錯誤: {ex.Message}")End Try
End Sub
2. 在監控程序中發送命令

vb

Imports System.IO.PipesPublic Sub SendCommandToRunningProcess(command As String)TryUsing client As New NamedPipeClientStream(".", "ABCControlPipe", PipeDirection.Out)client.Connect(2000)  ' 等待2秒連接Using writer As New StreamWriter(client)writer.WriteLine(command)writer.Flush()Console.WriteLine($"命令已發送: {command}")End UsingEnd UsingCatch ex As ExceptionConsole.WriteLine($"發送命令失敗: {ex.Message}")End Try
End Sub' 使用示例
SendCommandToRunningProcess("/exit")

二、使用命令行參數 + 進程查找

如果ABC.EXE支持通過創建特定文件或命令行參數觸發行為,可以這樣實現:

1. 修改 ABC.EXE 定期檢查命令文件

vb

' 在ABC.EXE中添加定時檢查邏輯
Private Sub StartCommandChecker()Dim timer As New Timer(1000)  ' 每秒檢查一次AddHandler timer.Elapsed, AddressOf CheckForCommandstimer.Start()
End SubPrivate Sub CheckForCommands(sender As Object, e As ElapsedEventArgs)Dim commandFile As String = Path.Combine(Application.StartupPath, "command.txt")If File.Exists(commandFile) ThenTryDim command As String = File.ReadAllText(commandFile)File.Delete(commandFile)  ' 處理后刪除If command = "/exit" ThenApplication.Exit()End IfCatch ex As ExceptionConsole.WriteLine($"讀取命令文件失敗: {ex.Message}")End TryEnd If
End Sub
2. 在監控程序中創建命令文件

vb

Public Sub SendCommandToRunningProcess(command As String)Dim commandFile As String = Path.Combine(Path.GetDirectoryName(Process.GetProcessesByName("ABC").FirstOrDefault()?.MainModule.FileName),"command.txt")TryFile.WriteAllText(commandFile, command)Console.WriteLine($"命令已寫入文件: {command}")Catch ex As ExceptionConsole.WriteLine($"發送命令失敗: {ex.Message}")End Try
End Sub

三、使用 Windows 消息(適用于有窗口的進程)

如果ABC.EXE有隱藏窗口,可以發送自定義 Windows 消息:

1. 在 ABC.EXE 中注冊并處理自定義消息

vb

Imports System.Runtime.InteropServicesPublic Class MainForm' 注冊自定義消息Private Const WM_USER As Integer = &H400Private Const WM_EXIT_COMMAND As Integer = WM_USER + 100<DllImport("user32.dll", CharSet:=CharSet.Auto)>Private Shared Function RegisterWindowMessage(ByVal lpString As String) As IntegerEnd FunctionPrivate exitMessageId As Integer = RegisterWindowMessage("ABC_EXIT_COMMAND")Protected Overrides Sub WndProc(ByRef m As Message)If m.Msg = exitMessageId OrElse m.Msg = WM_EXIT_COMMAND Then' 處理退出命令Application.Exit()ReturnEnd IfMyBase.WndProc(m)End Sub
End Class
2. 在監控程序中發送消息

vb

Imports System.Runtime.InteropServicesPublic Sub SendExitMessageToProcess()Dim processes() As Process = Process.GetProcessesByName("ABC")If processes.Length > 0 ThenDim mainWindowHandle As IntPtr = processes(0).MainWindowHandleIf mainWindowHandle <> IntPtr.Zero Then' 注冊相同的消息IDDim exitMessageId As Integer = RegisterWindowMessage("ABC_EXIT_COMMAND")' 發送消息PostMessage(mainWindowHandle, exitMessageId, IntPtr.Zero, IntPtr.Zero)Console.WriteLine("退出消息已發送")ElseConsole.WriteLine("未找到主窗口句柄")End IfEnd If
End Sub<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function RegisterWindowMessage(ByVal lpString As String) As Integer
End Function<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Boolean
End Function

四、總結

選擇哪種方法取決于ABC.EXE的實現:

  1. 優先使用命名管道:靈活且安全,需修改ABC.EXE代碼。
  2. 命令文件方式:簡單但有延遲(取決于檢查頻率)。
  3. Windows 消息:適用于有窗口的進程。

如果無法修改ABC.EXE,可考慮使用外部工具(如 AutoHotkey 發送模擬按鍵),但可靠性較低。

分享

如果多個進程,管道名稱是否要不一樣?

是的,如果需要同時管理多個進程實例,每個進程的管道名稱必須唯一。否則,不同進程會監聽同一個管道,導致命令混淆或無法正確識別目標進程。以下是幾種實現多進程管道通信的方案:

一、基于進程 ID(PID)的唯一管道名稱

最簡單的方法是將進程 ID(PID)作為管道名稱的一部分:

1. 在 ABC.EXE 中創建唯一管道

vb

Imports System.IO.PipesPublic Class ABCApplicationPrivate pipeServer As NamedPipeServerStreamPrivate pipeName As StringPublic Sub StartPipeServer()' 使用進程ID生成唯一管道名稱pipeName = $"ABCControlPipe_{Process.GetCurrentProcess().Id}"' 創建并啟動管道服務器pipeServer = New NamedPipeServerStream(pipeName, PipeDirection.InOut)Dim thread As New Threading.Thread(AddressOf HandleIncomingConnections)thread.IsBackground = Truethread.Start()End SubPrivate Sub HandleIncomingConnections()TryWhile TruepipeServer.WaitForConnection()' 處理命令...Using reader As New StreamReader(pipeServer)Dim command As String = reader.ReadLine()If command = "/exit" Then' 優雅退出邏輯Application.Exit()End IfEnd Using' 重置管道以接收下一個連接pipeServer.Disconnect()End WhileCatch ex As Exception' 錯誤處理End TryEnd Sub
End Class
2. 在監控程序中發送命令到特定進程
Imports System.IO.PipesPublic Sub SendCommandToProcess(pid As Integer, command As String)Dim pipeName As String = $"ABCControlPipe_{pid}"TryUsing client As New NamedPipeClientStream(".", pipeName, PipeDirection.Out)client.Connect(2000)  ' 2秒超時Using writer As New StreamWriter(client)writer.WriteLine(command)writer.Flush()End UsingEnd UsingCatch ex As ExceptionConsole.WriteLine($"發送命令到進程 {pid} 失敗: {ex.Message}")End Try
End Sub' 示例:向所有ABC進程發送退出命令
Public Sub SendExitToAllProcesses()Dim processes() As Process = Process.GetProcessesByName("ABC")For Each proc In processesSendCommandToProcess(proc.Id, "/exit")Next
End Sub

二、使用中央管道管理器(更高級的方案)

如果進程數量較多或需要更復雜的管理,可以實現一個中央管道管理器:

1. 中央管理器設計
Imports System.Collections.ConcurrentPublic Class PipeManagerPrivate Shared pipeMap As New ConcurrentDictionary(Of Integer, NamedPipeServerStream)' 注冊新進程的管道Public Shared Function RegisterProcess(pid As Integer) As StringDim pipeName As String = $"ABCControlPipe_{Guid.NewGuid()}"  ' 使用GUID確保唯一性Dim server As New NamedPipeServerStream(pipeName, PipeDirection.InOut)pipeMap.TryAdd(pid, server)' 啟動監聽線程Dim thread As New Threading.Thread(Sub() HandleConnections(pid, server))thread.IsBackground = Truethread.Start()Return pipeNameEnd Function' 處理管道連接Private Shared Sub HandleConnections(pid As Integer, server As NamedPipeServerStream)TryWhile pipeMap.ContainsKey(pid)server.WaitForConnection()' 處理命令...Using reader As New StreamReader(server)Dim command As String = reader.ReadLine()' 根據PID轉發命令到對應進程End Usingserver.Disconnect()End WhileCatch ex As Exception' 錯誤處理End TryEnd Sub' 向特定進程發送命令Public Shared Sub SendCommand(pid As Integer, command As String)If pipeMap.TryGetValue(pid, out Dim server) Then' 通過管道發送命令...End IfEnd Sub
End Class
2. 進程端注冊

vb

' 在ABC.EXE啟動時
Public Sub Main()' 向管理器注冊自己并獲取唯一管道名稱Dim pipeName As String = PipeManager.RegisterProcess(Process.GetCurrentProcess().Id)' 保存管道名稱用于后續通信My.Settings.PipeName = pipeNameMy.Settings.Save()' 其他初始化邏輯...
End Sub

三、關鍵注意事項

  1. 管道名稱唯一性

    • 確保每個進程的管道名稱包含唯一標識符(如 PID、GUID)。
    • 避免使用硬編碼的固定名稱。
  2. 資源清理

    • 進程退出時,確保關閉并釋放管道資源。
    • 可以通過Process.Exited事件監聽進程退出,清理對應的管道。
  3. 安全性考慮

    • 對管道名稱進行權限控制,防止未授權訪問。
    • 考慮使用加密或身份驗證增強安全性(如使用PipeSecurity)。
  4. 錯誤處理

    • 處理管道連接超時、斷開等異常情況。
    • 實現重試機制,確保命令可靠發送。

四、總結

通過為每個進程分配唯一的管道名稱,可以有效管理多個進程實例。選擇哪種方案取決于具體需求:

  • PID 方案:簡單直接,適用于大多數場景。
  • 中央管理器:適合復雜系統,提供更靈活的控制和監控能力。

無論采用哪種方式,核心原則是確保管道名稱的唯一性和通信的可靠性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88755.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88755.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88755.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ 右值引用 (Rvalue References)

右值引用是C11引入的革命性特性&#xff0c;它徹底改變了C中資源管理和參數傳遞的方式。下面我將從多個維度深入講解右值引用。一、核心概念1. 值類別(Value Categories)lvalue (左值): 有標識符、可取地址的表達式int x 10; // x是左值 int* p &x; // 可以取地址rvalue…

反激變換器設計全流程(一)——電路拓撲及工作流程

一、電路拓撲原理 拓撲結構概述 開關反激電源采用反激式拓撲結構&#xff0c;主要由開關管&#xff08;通常為 MOSFET&#xff09;、變壓器、輸出整流二極管、輸出濾波電容以及控制電路等組成。其基本工作原理是通過開關管的周期性開關動作&#xff0c;將輸入直流電壓轉換為高…

uniapp語音播報天氣預報微信小程序

1.產品展示2.頁面功能(1)點擊上方按鈕實現語音播報4天天氣情況。3.uniapp代碼<template><view class"container"><view class"header"><text class"place">地址:{{city}}</text><text class"time"&g…

Pycharm 報錯 Environment location directory is not empty 如何解決

好長時間不看不寫代碼了&#xff0c;人也跟著犯糊涂。今天在Pycharm 導入虛擬環境時&#xff0c;一直報錯&#xff1a;“Environment location directory is not empty”&#xff0c;在網上百度很多很多方法都無法解決&#xff0c;直到我翻出我之前自己寫的導入虛擬環境的詳細過…

React強大且靈活hooks庫——ahooks入門實踐之場景類(scene)hook詳解

什么是 ahooks&#xff1f; ahooks 是一個 React Hooks 庫&#xff0c;提供了大量實用的自定義 hooks&#xff0c;幫助開發者更高效地構建 React 應用。其中場景類 hooks 是 ahooks 的一個重要分類&#xff0c;專門針對特定業務場景提供解決方案。 安裝 ahooks npm install …

大模型之Langchain篇(二)——RAG

寫在前面 跟著樓蘭老師學習【LangChain教程】2025吃透LangChain框架快速上手與深度實戰&#xff0c;全程干貨無廢話&#xff0c;三天學完&#xff0c;讓你少走百分之99彎路&#xff01;_嗶哩嗶哩_bilibili 計算相似度 一般用的余弦相似度&#xff0c;這里只是演示計算。 fr…

深入理解圖像二值化:從靜態圖像到視頻流實時處理

一、引言&#xff1a;圖像分析&#xff0c;從“黑與白”開始在計算機視覺任務中&#xff0c;**圖像二值化&#xff08;Image Binarization&#xff09;**是最基礎也是最關鍵的圖像預處理技術之一。它通過將灰度圖像中每個像素轉換為兩個離散值&#xff08;通常是0和255&#xf…

云蝠智能 VoiceAgent重構企業呼入場景服務范式

在數字化轉型浪潮中&#xff0c;企業呼入場景面臨客戶服務需求激增與人力成本攀升的雙重挑戰。傳統呼叫中心日均處理僅 300-500 通電話&#xff0c;人力成本占比超 60%&#xff0c;且服務質量受情緒波動影響顯著。云蝠智能推出的 VoiceAgent 語音智能體&#xff0c;通過全棧自研…

java進階(一)+學習筆記

1.JAVA設計模式1.1 什么是設計模式設計模式是軟件開發過程中前輩們在長期實踐中針對重復出現的問題總結出來的最佳解決方案。這些模式不是具體的代碼實現&#xff0c;而是經過驗證的、可重用的設計思想&#xff0c;能夠幫助開發者更高效地解決特定類型的問題。設計模式的重要性…

Pandas-數據清洗與處理

Pandas-數據清洗與處理一、數據清洗的核心目標二、缺失值處理1. 缺失值檢測2. 缺失值處理策略&#xff08;1&#xff09;刪除法&#xff08;2&#xff09;填充法三、異常值識別與處理1. 異常值檢測方法&#xff08;1&#xff09;統計法&#xff08;2&#xff09;業務規則法2. 異…

在 MacOS 上安裝和配置 Kafka

消息代理是一種軟件&#xff0c;充當在不同應用程序之間發送消息的中介。它的功能類似于服務器&#xff0c;從一個應用程序&#xff08;稱為生產者&#xff09;接收消息&#xff0c;并將其路由到一個或多個其他應用程序&#xff08;稱為消費者&#xff09;。消息代理的主要目的…

基于Leaflet調用天地圖在線API的多層級地名檢索實戰

目錄 前言 一、天地圖在線檢索 1、在線檢索功能 2、再談后后接口 二、Leaflet多層級實現實例 1、層級調用實現原理 2、Leaflet中多層級調用 3、成果展示 三、總結 前言 “地圖是世界的索引&#xff0c;而地名則是索引中的索引。”當互聯網地圖進入 Web 2.0 時代&#x…

基于Prompt結構的語校解析:3H日本語學校信息建模實錄(4/500)

基于Prompt結構的語校解析&#xff1a;3H日本語學校信息建模實錄&#xff08;4/500&#xff09; 系列延續&#xff1a;500所日本語言學校結構數據工程 關鍵詞&#xff1a;招生結構、JLPTEJU、國籍比例、認定校、Prompt訓練集 一、我們在構建什么樣的語言學校語料&#xff1f; …

Leaflet面試題及答案(61-80)

查看本專欄目錄 文章目錄 ?? 面試問題及答案(61-80)61. 如何在地圖上顯示一個動態更新的圖層?62. 如何實現地圖上的熱力圖(Heatmap)?63. 如何自定義地圖控件的位置?64. 如何處理地圖加載失敗的情況?65. 如何實現地圖的離線功能?66. 如何將地圖導出為圖片?67. 如何實…

MIG_IP核的時鐘系統

MIG_IP核的時鐘系統時鐘的種類和配置時鐘的種類和配置 整體框圖 DDR_PHY_CLK&#xff1a;DDR3的工作頻率&#xff0c;用來得到想要的線速率。假設此時鐘為800M&#xff0c;那么DDR雙沿采樣&#xff0c;線速率為1600Mbit&#xff1b; UI_CLK&#xff1a;DDR_PHY_CLK的四分之一…

若依框架集成阿里云OSS實現文件上傳優化

背景介紹 在若依框架目前的實現中&#xff0c;是把圖片存儲到了服務器本地的目錄&#xff0c;通過服務進行訪問&#xff0c;這樣做存儲的是比較省事&#xff0c;但是缺點也有很多&#xff1a; 硬件與網絡要求&#xff1a;服務器通常需要高性能的硬件和穩定的網絡環境&#xff0…

Mac如何連接惠普M126a打印機(教程篇)

這里寫自定義目錄標題Mac如何連接惠普M126a打印機&#xff08;教程篇&#xff09;教程配置如下&#xff1a;Mac如何連接惠普M126a打印機&#xff08;教程篇&#xff09; 惠普M126a連接Mac&#xff08;教程篇&#xff09; 教程配置如下&#xff1a; 首先&#xff0c;先獲取與HP打…

感恩日記:記錄生活中的美好時刻

感恩日記的landing page登錄注冊填寫感恩事項私信可以體驗一下

一扇門鈴,萬向感應——用 eventfd 實現零延遲通信

&#x1f50d; 本篇概要 eventfd 是 Linux 提供的一種輕量級事件通知機制。你可以把它想象成一個“計數器盒子”。它里面維護的是一個64位的計數器。寫入&#xff1a;往盒子里放一些數字&#xff08;比如 1、5、10&#xff09;&#xff0c;表示有幾件事發生了。讀取&#xff1a…

基于Node.js的線上教學系統的設計與實現(源碼+論文+調試+安裝+售后)

感興趣的可以先收藏起來&#xff0c;還有大家在畢設選題&#xff0c;項目以及論文編寫等相關問題都可以給我留言咨詢&#xff0c;我會一一回復&#xff0c;希望幫助更多的人。系統背景近年來&#xff0c;全球數字化浪潮的推進與教育公平化需求的增長&#xff0c;促使線上教學迎…