1

多くのスクリプトを取得しました。スクリプトで一括管理できるようにしたいです。私が望むのは、メイン スクリプトが特定のスクリプトをアクティブにし、セカンダリ スクリプトが完了すると、メイン スクリプトに値を返すことです。その後、メイン スクリプトは別のセカンダリ スクリプトを呼び出します。

これを行う適切な方法はありますか?

より正確な質問:

  • 別のスクリプト AHK から AHK スクリプトをアクティブにすることは可能ですか?

  • 現時点では、サブスクリプトが完了したことを検出するために、現在使用している方法は、サブスクリプトが終了する直前に、メインスクリプトが検出するキーの組み合わせを押すことです。検出されると、メイン スクリプト変数が 1 増加し、次のスクリプトのアクティブ化がトリガーされます。これを達成するためのより良い方法はありますか?

4

3 に答える 3

4

メイン スクリプトは、 を使用して他のスクリプトを呼び出すことができますRunWait。その後、スクリプトは自分自身を終了する前に通信を返すことができました。

通信に最適なオプションは、OnMessageを使用することです。

以下は、ドキュメントの実際の例です。

; Example: Send a string of any length from one script to another.  This is a working example.
; To use it, save and run both of the following scripts then press Win+Space to show an
; InputBox that will prompt you to type in a string.

; Save the following script as "Receiver.ahk" then launch it:
#SingleInstance
OnMessage(0x4a, "Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA
return

Receive_WM_COPYDATA(wParam, lParam)
{
    StringAddress := NumGet(lParam + 2*A_PtrSize)  ; Retrieves the CopyDataStruct's lpData member.
    CopyOfData := StrGet(StringAddress)  ; Copy the string out of the structure.
    ; Show it with ToolTip vs. MsgBox so we can return in a timely fashion:
    ToolTip %A_ScriptName%`nReceived the following string:`n%CopyOfData%
    return true  ; Returning 1 (true) is the traditional way to acknowledge this message.
}

; Save the following script as "Sender.ahk" then launch it.  After that, press the Win+Space hotkey.
TargetScriptTitle = Receiver.ahk ahk_class AutoHotkey

#space::  ; Win+Space hotkey. Press it to show an InputBox for entry of a message string.
InputBox, StringToSend, Send text via WM_COPYDATA, Enter some text to Send:
if ErrorLevel  ; User pressed the Cancel button.
    return
result := Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
if result = FAIL
    MsgBox SendMessage failed. Does the following WinTitle exist?:`n%TargetScriptTitle%
else if result = 0
    MsgBox Message sent but the target window responded with 0, which may mean it ignored it.
return

Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle)  ; ByRef saves a little memory in this case.
; This function sends the specified string to the specified window and returns the reply.
; The reply is 1 if the target window processed the message, or 0 if it ignored it.
{
    VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0)  ; Set up the structure's memory area.
    ; First set the structure's cbData member to the size of the string, including its zero terminator:
    SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)  ; OS requires that this be done.
    NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)  ; Set lpData to point to the string itself.
    Prev_DetectHiddenWindows := A_DetectHiddenWindows
    Prev_TitleMatchMode := A_TitleMatchMode
    DetectHiddenWindows On
    SetTitleMatchMode 2
    SendMessage, 0x4a, 0, &CopyDataStruct,, %TargetScriptTitle%  ; 0x4a is WM_COPYDATA. Must use Send not Post.
    DetectHiddenWindows %Prev_DetectHiddenWindows%  ; Restore original setting for the caller.
    SetTitleMatchMode %Prev_TitleMatchMode%         ; Same.
    return ErrorLevel  ; Return SendMessage's reply back to our caller.
}
于 2013-08-09T17:53:20.247 に答える
2

ええと、なぜあるスクリプトで別のスクリプトを実行したいのかわかりません...しかし、いくつかの他の方法があります:

スクリプトを別のスクリプトに含める

includeしかし、別のスクリプト内にスクリプトを作成できることはご存知ですよね? つまり、メイン スクリプトで別のスクリプト関数を使用できます。

特定のスクリプトがロードされていることを確認する

「私は多くのスクリプトを手に入れました」も。使用する前に特定のものが含まれていることを確認する必要がある場合があるため、これを一番上に置きます。

;make sure core.ahk is loaded since it is required
#include c:\ahk\core.ahk

また、(必要でない限り) 複数回含まれることを心配する必要はありません。理由は次のとおりです。

#Include は、FileName が複数の包含に遭遇した場合でも、FileName が 1 回だけ含まれることを保証します。対照的に、#IncludeAgain では同じファイルを複数回含めることができますが、他のすべての点では #Include と同じです。

にインクルードfile.ahkすると、file.ahk が必要とmain.ahkする関数を使用しても問題がないことが保証されます。また、再度core.ahkインクルードしても心配ありません (ただの関数ではなくサブルーチンが含まれている場合を除きます。その場合、サブルーチンはインクルードされた時点で実行されるため、サブルーチンを ahk ライブラリに配置しないことをお勧めします)。core.ahkmain.ahk

古き良き RUN on Scripts を使用する

それとは別に、いつでもrunコマンドを使用してahkスクリプトを起動できることを知っています. 面倒な WM_SENDMESSAGE をすべて行う必要はありません。

非表示の GUI を使用してスクリプト間で通信する

2 つのスクリプトが相互に通信するもう 1 つの方法は、スクリプト #1 が編集ボックスと送信ボタンのある非表示の GUI ウィンドウを開いたままにすることです。このウィンドウは表示されません。ここで、スクリプト #2 はそのメッセージ ボックスを探しsend、編集ボックスに文字列を入力してから、control キーを押しながらクリックして送信ボタンを押します。これで、スクリプト #1 がスクリプト #2 から入力を受け取りました。また、両方のスクリプトにウィンドウの値を入れておけば、ウィンドウを探す必要さえありませんhwnd(したがって、事前にわかっているため)。これは魅力のように機能します。

スクリプトが完了したかどうかを伝える

ahk のコマンドを使用すると、そのプロセス (PID = プロセス ID)runを返すパラメーターがあります。PIDこれを使用しPIDて、スクリプトが実行されているかどうかを確認し、プロセスを終了するために使用できます。

また、runwait- を使用すると、そのコマンドを使用するスクリプトは一時停止し、実行中のプロセスが完了して終了するのを待ってから続行します。

于 2013-08-10T02:34:34.167 に答える
0

理論的には、スクリプト間でファイル オブジェクトを一種の stdin/stdout メソッドとして使用することもできます。これは、ファイル オブジェクトを共有として設定できるファイル オブジェクトでファイルを開く場合と同様です。

また、環境変数を設定し、変数の名前をスクリプトに渡すこともできます。これは、ターゲット スクリプトで引数処理を設定し、終了時に環境変数の値を設定する場合です。RunWait を使用すると、スクリプトの実行後に返される結果を確認できます。

最後に、関数の使用を検討してください。それはおそらく、あなたがやろうとしていることの「ベストプラクティス」です。関数はスクリプトが実行できることは何でも実行できるため、操作する配列を渡したり、配列パラメーターで ByRef を使用したりできます。これは、関数を記述するときに一連のパラメーターを記述する必要がなく、関数が完了すると変数が自動的にメモリを解放することを意味します。関数を別のファイルに記述し、#Include を使用してスクリプトで使用することもできます。

于 2015-06-21T09:15:41.400 に答える