亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從 Windows 服務運行另一個可執行文件

如何從 Windows 服務運行另一個可執行文件

Go
犯罪嫌疑人X 2023-07-10 18:00:29
除了一些關于 Go 的教程之外,我沒有任何實際經驗。我正在嘗試將一個用 Go 編寫的項目并將其轉換為 Windows 服務。老實說,除了試圖找到可以閱讀的內容之外,我還沒有嘗試過任何其他事情。我找到了一些線程并選擇了我認為可以滿足我們所有需求的最佳庫https://github.com/golang/sys所以我花了一些時間仔細研究這段代碼。對其進行測試,看看它有什么作用。它按其應有的方式執行。我的問題是,我們目前有一個 Go 程序,它接受參數,并且對于我們的服務,我們在服務器中傳遞。這會在本地主機網頁上啟動我們的東西。我相信上面的代碼可能與此有關,但我不知道如何用正確的論點將它從我們的 exe 中分離出來。這是調用 main 的正確位置嗎?如果這含糊不清,我很抱歉。我不知道如何讓它與我們已經存在的 exe 交互。如果我知道需要更改什么,我可以對其進行修改。我感謝任何幫助。
查看完整描述

1 回答

?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

好的,現在清楚多了。好吧,理想情況下,您應該從一些有關 Windows 服務的構成的教程開始 - 我打賭這可能已經為您解決了問題。但無論如何我們還是要嘗試一下。

一些理論

Windows 服務有兩個方面:它執行一些有用的任務并與SCM 設施進行通信。當您使用命令或通過控制面板操作服務時sc,您可以使用該軟件代表您與 SCM 進行對話,而 SCM 則與該服務進行對話。

SCM 和服務使用的確切協議是低級且復雜的,您使用的 Go 包的目的是向您隱藏這種復雜性,并為這些東西提供一個合理的以 Go 為中心的接口。

正如您可能從自己的示例中了解到的那樣,Execute您創建的類型的方法在很大程度上與與 SCM 的通信有關:它運行一個無限for循環,在每次迭代時都會休眠從r通道讀取數據,并且該通道將 SCM 命令傳送到您的服務。

所以你基本上擁有了所謂的“SCM 命令處理循環”。

現在回想一下上面的兩個方面。您已經擁有其中之一:您的服務與 SCM 交互,因此您需要另一個 — 實際執行有用任務的代碼。

事實上,它已經部分存在:您獲取的示例代碼創建了一個時間行情指示器,它提供了一個通道,當另一個時間行情通過時,它在該通道上傳遞值。for該方法中的循環也Execute從該通道讀取數據,每次發出另一個刻度信號時都會“工作”。

好吧,這對于一個玩具示例來說很好,但對于真正的作品來說卻很糟糕。

接近解決方案

因此,讓我們暫停一下并考慮一下我們的需求。

  1. 我們需要一些代碼來運行并執行我們的實際任務。

  2. 我們需要現有的命令處理循環才能繼續工作。

  3. 我們需要這兩段代碼同時工作。

在這個玩具示例中,第三點是“免費”的,因為時間計時器自動執行等待下一個計時的任務,并且與其余代碼完全并發。

你真正的代碼很可能不會有那么奢侈,那么你該怎么辦?

在 Go 中,當你需要同時做某件事和其他事情時,一個明顯的答案是“使用 goroutine”。

因此,第一步是獲取現有代碼,將其轉換為可調用函數,然后在進入循環之前在單獨的 goroutine 中調用它for。這樣,您將同時運行兩個部分。

困難的部分

好吧,那并不難。

困難的部分是:

  • 如何配置執行任務的代碼。

  • 如何使單片機命令處理循環和執行任務的代碼進行通信。

配置

這實際上取決于您的 $dayjob 或 $current_project 的政策,但有一些提示:

  • Windows 服務可以接收命令行參數——無論是單次運行還是永久(在每次運行時傳遞給服務)。

    缺點是從 UI/UX 的角度來看使用它們并不方便。

  • 通常 Windows 服務用于讀取注冊表。

  • 如今(在 .NET 及其普遍的 xml-ity 出現之后)服務傾向于讀取配置文件。

  • 大多數時候,操作系統環境并不適合該任務。

  • 您可以合并其中幾個場地。

我想我會從配置文件開始,但話又說回來,我認為你應該選擇阻力最小的路徑。

需要記住的一件事是,配置的讀取和處理最好在服務向 SCM 發出它已啟動的信號之前完成:如果配置無效或無法加載,服務應廣泛記錄該情況并發出信號失敗,并且運行實際的任務處理代碼。

命令處理循環和攜帶代碼的任務之間的通信

在我看來,這是最難的部分。

在這里寫一整本書是可能的,但現在讓我們保持簡單。

為了使其盡可能簡單,我會執行以下操作:

  • 考慮暫停、停止和關閉幾乎相同:所有這些信號都必須告訴您的任務處理代碼退出,然后等待它實際執行此操作。

  • 將“繼續”信號視為與啟動任務處理函數相同:在新的 goroutine 中再次運行它。

  • 進行單向通信:從控制循環到任務處理代碼,而不是其他方式 - 這將大大簡化服務狀態管理。

這樣,您可以創建一個任務處理代碼偵聽或定期檢查的通道,當一個值來自該通道時,代碼停止運行,關閉通道并退出。

當 SCM 告訴控制循環暫停、停止或關閉時,控制循環會在該通道上發送任何內容,然后等待其關閉。當發生這種情況時,它知道任務處理代碼已完成。

在 Go 中,僅用于信令的通道的范例是具有類型struct{}(空struct)的通道。

如何在運行代碼的任務中監視此控制通道的問題是一個開放的問題,并且在很大程度上取決于它執行的任務的性質。

這里的任何進一步幫助都可以背誦 Go 書籍中有關并發的內容,因此您應該首先了解這一點。


還有一個有趣的問題是如何使控制循環和任務處理循環之間的通信能夠適應后者可能出現的處理停頓,但話又說回來,在我看來,現在討論這個問題還為時過早。


查看完整回答
反對 回復 2023-07-10
  • 1 回答
  • 0 關注
  • 205 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號