首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

組語程式防止多重啟動並傳遞命令列參數

     編輯:組合語言

前言

在開發 Windows 組語程式時,常需防止使用者重複啟動同一程式。若直接讓第二個實例退出,使用者拖曳檔案到程式圖示時會發現檔案無法開啟,體驗極差。本文介紹如何利用 WM_SETTEXT/WM_GETTEXT 訊息,在第二個實例退出前將命令列參數傳遞給第一個實例,實現單一實例且支援檔案關聯。

核心原理:記憶體映射檔傳遞字串

Windows 在進程結束時會回收該進程擁有的所有資源(動態載入的 DLL 除外)。若第二個實例直接將自身記憶體中的字串指標傳給第一個實例,隨著第二個實例退出,該指標即失效。解決之道是使用 SendMessage 發送 WM_SETTEXT 訊息:系統偵測到此訊息時,會自動建立一個可跨進程共享的記憶體映射檔,將字串內容複製進去,並將映射檔位址作為參數傳遞。接收端收到訊息後,透過 WM_GETTEXT 即可安全讀取字串。

實作範例(MASM 語法)

.DATA
szClassName db "WinASM_Class",0
.data?
lpCommandLine DD ?
.CODE
START:
    ; 取得命令列
    invoke GetCommandLine
    mov lpCommandLine, eax

    ; 尋找同類別視窗
    invoke FindWindow, offset szClassName, NULL
    cmp eax, 0
    jnz @F          ; 找到則跳轉至傳遞參數

    ; 第一個實例:正常執行
    invoke WinMain, ...
    invoke ExitProcess, 0

@@: ; 第二個實例:傳遞參數給第一個實例
    invoke SendMessage, eax, WM_SETTEXT, 0, lpCommandLine
    invoke ExitProcess, 1   ; 非零返回值表示非正常啟動

第一個實例處理 WM_SETTEXT

.elseif uMsg == WM_SETTEXT
    ; lParam 指向共享記憶體中的字串
    invoke MessageBox, 0, lParam, 0, 0   ; 示範:彈出訊息框顯示參數
    ; 實際應用可解析 lParam 並呼叫開啟檔案流程

測試與驗證

編譯後執行第一個實例,再以命令列參數啟動第二個實例(例如 MyApp.exe "C:\test.txt"),即可見第一個實例彈出訊息框顯示 C:\test.txt。此技巧廣泛應用於編輯器、檢視器等需支援檔案拖曳開啟的工具程式。

總結

  • 利用 WM_SETTEXT/WM_GETTEXT 實現跨進程字串傳遞,避免指標失效。
  • 僅需少量程式碼即可實現單一實例且保留命令列參數功能。
  • 適用於 MASM、FASM 等 Windows 組語開發環境。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved