kemyliu 发表于 2012-2-5 08:51:52

【已解决】多进程子进程无法使用主进程的变量

本帖最后由 kemyliu 于 2012-2-5 20:21 编辑

程式如下,多进程子进程无法使用主进程的变量,希望有高人帮忙解决!
问题已经得到解决,答案可以看14楼程式!感谢半芯竹兄!#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "CoProc.au3"
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 623, 444, 192, 124)
$Button1 = GUICtrlCreateButton("OK", 168, 248, 249, 73)
$Label1 = GUICtrlCreateLabel("This is for test!", 184, 120, 230, 41)
GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        _CoProc("Test")

        EndSwitch
WEnd

Func Reciver($vParameter)
    ;$vParameter里就是子进程发来的消息
    $aParam = StringSplit($vParameter,"|")
    If $aParam = "small" Then MsgBox(0,"TT",$aParam)
EndFunc
       
Func Test()
       
        GUICtrlSetData($Label1,"Change the text!")
EndFunc
同时分享【CoProc.au3】#cs
User Calltips:
_CoProc([$sFunction],[$vParameter]) Starts another Process and Calls $sFunc, Returns PID
_SuperGlobalSet($sName,[$vValue],[$sRegistryBase]) Sets or Deletes a Superglobal Variable
_SuperGlobalGet($sName,[$fOption],[$sRegistryBase]) Returns the Value of a Superglobal Variable
_ProcSuspend($vProcess) Suspends all Threads in $vProcess (PID or Name)
_ProcResume($vProcess) Resumes all Threads in $vProcess (PID or Name)
_ProcessGetWinList($vProcess, $sTitle = Default, $iOption = 0) Enumerates Windows of a Process
_CoProcReciver([$sFunction = ""]) Register/Unregister Reciver Function
_CoProcSend($vProcess, $vParameter,[$iTimeout = 500],[$fAbortIfHung = True]) Send Message to Process
_ConsoleForward($iPid1, [$iPid2], [$iPid3], [$iPidn])
_ProcessEmptyWorkingSet($vPid = @AutoItPID,[$hDll_psapi],[$hDll_kernel32]) Removes as many pages as possible from the working set of the specified process.
_DuplicateHandle($dwSourcePid, $hSourceHandle, $dwTargetPid = @AutoItPID, $fCloseSource = False) Returns a Duplicate handle
_CloseHandle($hAny) Close a Handle
$gs_SuperGlobalRegistryBase
$gi_CoProcParent
#ce

Global $gs_SuperGlobalRegistryBase = "HKEY_CURRENT_USER\Software\AutoIt v3\CoProc"
Global $gi_CoProcParent = 0
Global $gs_CoProcReciverFunction = ""
Global $gv_CoProcReviverParameter = 0

;===============================================================================
;
; Description: Starts another Process
; Parameter(s): $sFunction - Optional, Name of Function to start in the new Process
; $vParameter - Optional, Parameter to pass
; Requirement(s): 3.2.4.9
; Return Value(s): On Success - Pid of the new Process
; On Failure - Set @error to 1
; Author(s): Florian 'Piccaso' Fida
; Note(s): Inside the new Process $gi_CoProcParent holds the PID of the Parent Process.
; $vParameter must not be Binary, an Array or DllStruct.
; If $sFunction is a just a function name Like _CoProc("MyFunc","MyParameter") Then
; Call() will be used to Call the function and optional pass the Parameter (only one).
; If $sFunction is a expression like _CoProc("MyFunc('MyParameter')") Then
; Execute() will be used to evaluate this expression makeing more than one Parameter Possible.
; In the 'Execute()' Case the $vParameter Parameter will be ignored.
; In both cases there are Limitations, Read doc's (for Execute() and Call()) for more detail.
;
; If $sFunction is Empty ("" or Default) $vParameter can be the name of a Reciver function.
;
;
;===============================================================================
Func _CoProc($sFunction = Default, $vParameter = Default)
Local $iPid
If IsKeyword($sFunction) Or $sFunction = "" Then $sFunction = "__CoProcDummy"
EnvSet("CoProc", "0x" & Hex(StringToBinary ($sFunction)))
EnvSet("CoProcParent", @AutoItPID)
If Not IsKeyword($vParameter) Then
EnvSet("CoProcParameterPresent", "True")
EnvSet("CoProcParameter", StringToBinary ($vParameter))
Else
EnvSet("CoProcParameterPresent", "False")
EndIf
If @Compiled Then
$iPid = Run(FileGetShortName(@AutoItExe), @WorkingDir, @SW_HIDE, 1 + 2 + 4)
Else
$iPid = Run(FileGetShortName(@AutoItExe) & ' "' & @ScriptFullPath & '"', @WorkingDir, @SW_HIDE, 1 + 2 + 4)
EndIf
If @error Then SetError(1)
Return $iPid
EndFunc ;==>_CoProc


;===============================================================================
;
; Description: Set a Superglobal Variable
; Parameter(s): $sName - Identifier for the Superglobal Variable
; $vValue - Value to be Stored (optional)
; $sRegistryBase - Registry Base Key (optional)
; Requirement(s): 3.2.4.9
; Return Value(s): On Success - Returns True
; On Failure - Returns False and Set
; @error to: 1 - Wrong Value Type
; 2 - Registry Problem
; Author(s): Florian 'Piccaso' Fida
; Note(s): $vValue must not be an Array or Struct.
; if $vValue is Omitted the Superglobal Variable will be deleted.
;
; Superglobal Variables are Stored in the Registry.
; $gs_SuperGlobalRegistryBase is holding the Default Base Key
;
;===============================================================================
Func _SuperGlobalSet($sName, $vValue = Default, $sRegistryBase = Default)
Local $vTmp
If $sRegistryBase = Default Then $sRegistryBase = $gs_SuperGlobalRegistryBase
If $vValue = "" Or $vValue = Default Then
RegDelete($sRegistryBase, $sName)
If @error Then Return SetError(2, 0, False) ; Registry Problem
Else
RegWrite($sRegistryBase, $sName, "REG_BINARY", StringToBinary ($vValue))
If @error Then Return SetError(2, 0, False) ; Registry Problem
EndIf
Return True
EndFunc ;==>_SuperGlobalSet

;===============================================================================
;
; Description: Get a Superglobal Variable
; Parameter(s): $sName - Identifier for the Superglobal Variable
; $fOption - Optional, if True The Superglobal Variable will be deleted after sucessfully Reading it out
; $sRegistryBase - Registry Base Key (optional)
; Requirement(s): 3.2.4.9
; Return Value(s): On Success - Returns the Value of the Superglobal Variable
; On Failure - Set
; @error to: 1 - Not Found / Registry Problem
; 2 - Error Deleting
; Author(s): Florian 'Piccaso' Fida
; Note(s): $vValue must not be an Array or Struct.
; Superglobal Variables are Stored in the Registry.
; $gs_SuperGlobalRegistryBase is holding the Default Base Key
;
;===============================================================================
Func _SuperGlobalGet($sName, $fOption = Default, $sRegistryBase = Default)
Local $vTmp
If $fOption = "" Or $fOption = Default Then $fOption = False
If $sRegistryBase = Default Then $sRegistryBase = $gs_SuperGlobalRegistryBase
$vTmp = RegRead($sRegistryBase, $sName)
If @error Then Return SetError(1, 0, "") ; Registry Problem
If $fOption Then
_SuperGlobalSet($sName)
If @error Then SetError(2)
EndIf
Return BinaryToString ("0x" & $vTmp)
EndFunc ;==>_SuperGlobalGet

;===============================================================================
;
; Description: Suspend all Threads in a Process
; Parameter(s): $vProcess - Name or PID of Process
; Requirement(s): 3.1.1.130, Win ME/2k/XP
; Return Value(s): On Success - Returns Nr. of Threads Suspended and Set @extended to Nr. of Threads Processed
; On Failure - Returns False and Set
; @error to: 1 - Process not Found
; 2 - Error Calling 'CreateToolhelp32Snapshot'
; 3 - Error Calling 'Thread32First'
; 4 - Error Calling 'Thread32Next'
; 5 - Not all Threads Processed
; Author(s): Florian 'Piccaso' Fida
; Note(s): Ported from: http://www.codeproject.com/threads/pausep.asp
; Better read the article (and the warnings!) if you want to use it :)
;
;===============================================================================
Func _ProcSuspend($vProcess, $iReserved = 0)
Local $iPid, $vTmp, $hThreadSnap, $ThreadEntry32, $iThreadID, $hThread, $iThreadCnt, $iThreadCntSuccess, $sFunction
Local $TH32CS_SNAPTHREAD = 0x00000004
Local $INVALID_HANDLE_VALUE = 0xFFFFFFFF
Local $THREAD_SUSPEND_RESUME = 0x0002
Local $THREADENTRY32_StructDef = "int;" _; 1 -> dwSize
& "int;" _; 2 -> cntUsage
& "int;" _; 3 -> th32ThreadID
& "int;" _; 4 -> th32OwnerProcessID
& "int;" _; 5 -> tpBasePri
& "int;" _; 6 -> tpDeltaPri
& "int" ; 7 -> dwFlags
$iPid = ProcessExists($vProcess)
If Not $iPid Then Return SetError(1, 0, False) ; Process not found.
$vTmp = DllCall("kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPTHREAD, "int", 0)
If @error Then Return SetError(2, 0, False) ; CreateToolhelp32Snapshot Failed
If $vTmp = $INVALID_HANDLE_VALUE Then Return SetError(2, 0, False) ; CreateToolhelp32Snapshot Failed
$hThreadSnap = $vTmp
$ThreadEntry32 = DllStructCreate($THREADENTRY32_StructDef)
DllStructSetData($ThreadEntry32, 1, DllStructGetSize($ThreadEntry32))
$vTmp = DllCall("kernel32.dll", "int", "Thread32First", "ptr", $hThreadSnap, "long", DllStructGetPtr($ThreadEntry32))
If @error Then Return SetError(3, 0, False) ; Thread32First Failed
If Not $vTmp Then
DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hThreadSnap)
Return SetError(3, 0, False) ; Thread32First Failed
EndIf
While 1
If DllStructGetData($ThreadEntry32, 4) = $iPid Then
$iThreadID = DllStructGetData($ThreadEntry32, 3)
$vTmp = DllCall("kernel32.dll", "ptr", "OpenThread", "int", $THREAD_SUSPEND_RESUME, "int", False, "int", $iThreadID)
If Not @error Then
$hThread = $vTmp
If $hThread Then
If $iReserved Then
$sFunction = "ResumeThread"
Else
$sFunction = "SuspendThread"
EndIf
$vTmp = DllCall("kernel32.dll", "int", $sFunction, "ptr", $hThread)
If $vTmp <> -1 Then $iThreadCntSuccess += 1
DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hThread)
EndIf
EndIf
$iThreadCnt += 1
EndIf
$vTmp = DllCall("kernel32", "int", "Thread32Next", "ptr", $hThreadSnap, "long", DllStructGetPtr($ThreadEntry32))
If @error Then Return SetError(4, 0, False) ; Thread32Next Failed
If Not $vTmp Then ExitLoop
WEnd
DllCall("kernel32.dll", "int", "CloseToolhelp32Snapshot", "ptr", $hThreadSnap) ; CloseHandle
If Not $iThreadCntSuccess Or $iThreadCnt > $iThreadCntSuccess Then Return SetError(5, $iThreadCnt, $iThreadCntSuccess)
Return SetError(0, $iThreadCnt, $iThreadCntSuccess)
EndFunc ;==>_ProcSuspend

;===============================================================================
;
; Description: Resume all Threads in a Process
; Parameter(s): $vProcess - Name or PID of Process
; Requirement(s): 3.1.1.130, Win ME/2k/XP
; Return Value(s): On Success - Returns Nr. of Threads Resumed and Set @extended to Nr. of Threads Processed
; On Failure - Returns False and Set
; @error to: 1 - Process not Found
; 2 - Error Calling 'CreateToolhelp32Snapshot'
; 3 - Error Calling 'Thread32First'
; 4 - Error Calling 'Thread32Next'
; 5 - Not all Threads Processed
; Author(s): Florian 'Piccaso' Fida
; Note(s): Ported from: http://www.codeproject.com/threads/pausep.asp
; Better read the article (and the warnings!) if you want to use it :)
;
;===============================================================================
Func _ProcResume($vProcess)
Local $fRval = _ProcSuspend($vProcess, True)
Return SetError(@error, @extended, $fRval)
EndFunc ;==>_ProcResume

;===============================================================================
;
; Description: Enumerates Windows of a Process
; Parameter(s): $vProcess - Name or PID of Process
; $sTitle - Optional Title of window to Find
; $iOption - Optional, Can be added together
; 0 - Matches any Window (Default)
; 2 - Matches any Window Created by GuiCreate() (ClassName: AutoIt v3 GUI)
; 4 - Matches AutoIt Main Window (ClassName: AutoIt v3)
; 6 - Matches Any AutoIt Window
; 16 - Return the first Window Handle found (No Array)
; Requirement(s): 3.1.1.130
; Return Value(s): On Success - Retuns an Array/Handle of Windows found
; On Failure - Set @ERROR to: 1 - Process not Found
; 2 - Window(s) not Found
; 3 - GetClassName Failed
; Author(s): Florian 'Piccaso' Fida
; Note(s):
;
;===============================================================================
Func _ProcessGetWinList($vProcess, $sTitle = Default, $iOption = 0)
Local $aWinList, $iCnt, $aTmp, $aResult, $iPid, $fMatch, $sClassname
$iPid = ProcessExists($vProcess)
If Not $iPid Then Return SetError(1) ; Process not Found
If $sTitle = "" Or IsKeyword($sTitle) Then
$aWinList = WinList()
Else
$aWinList = WinList($sTitle)
EndIf
For $iCnt = 1 To $aWinList
$hWnd = $aWinList[$iCnt]
$iProcessId = WinGetProcess($hWnd)
If $iProcessId = $iPid Then
If $iOption = 0 Or IsKeyword($iOption) Or $iOption = 16 Then
$fMatch = True
Else
$fMatch = False
$sClassname = DllCall("user32.dll", "int", "GetClassName", "hwnd", $hWnd, "str", "", "int", 1024)
If @error Then Return SetError(3) ; GetClassName
If $sClassname = 0 Then Return SetError(3) ; GetClassName
$sClassname = $sClassname
If BitAND($iOption, 2) Then
If $sClassname = "AutoIt v3 GUI" Then $fMatch = True
EndIf
If BitAND($iOption, 4) Then
If $sClassname = "AutoIt v3" Then $fMatch = True
EndIf
EndIf
If $fMatch Then
If BitAND($iOption, 16) Then Return $hWnd
ReDim $aResult
$aResult = $hWnd
EndIf
EndIf
Next
$aResult = UBound($aResult) - 1
If $aResult < 1 Then Return SetError(2, 0, 0) ; No Window(s) Found
Return $aResult
EndFunc ;==>_ProcessGetWinList

;===============================================================================
;
; Description: Register Reciver Function
; Parameter(s): $sFunction - Optional, Function name to Register.
; Omit to Disable/Unregister
; Requirement(s): 3.2.4.9
; Return Value(s): On Success - Returns True
; On Failure - Returns False and Set
; @error to: 1 - Unable to create Reciver Window
; 2 - Unable to (Un)Register WM_COPYDATA or WM_USER+0x64
; Author(s): Florian 'Piccaso' Fida
; Note(s): If the process doesent have a Window it will be created
; The Reciver Function must accept 1 Parameter
;
;===============================================================================
Func _CoProcReciver($sFunction = Default)
Local $sHandlerFuction = "__CoProcReciverHandler", $hWnd, $aTmp
If IsKeyword($sFunction) Then $sFunction = ""
$hWnd = _ProcessGetWinList(@AutoItPID, "", 16 + 2)
If Not IsHWnd($hWnd) Then
$hWnd = GUICreate("CoProcEventReciver")
If @error Then Return SetError(1, 0, False)
EndIf
If $sFunction = "" Or IsKeyword($sFunction) Then $sHandlerFuction = ""
If Not GUIRegisterMsg(0x4A, $sHandlerFuction) Then Return SetError(2, 0, False) ; WM_COPYDATA
If Not GUIRegisterMsg(0x400 + 0x64, $sHandlerFuction) Then Return SetError(2, 0, False) ; WM_USER+0x64
$gs_CoProcReciverFunction = $sFunction
Return True
EndFunc ;==>_CoProcReciver
Func __CoProcReciverHandler($hWnd, $iMsg, $WParam, $LParam)
If $iMsg = 0x4A Then ; WM_COPYDATA
Local $COPYDATA, $MyData
$COPYDATA = DllStructCreate("ptr;dword;ptr", $LParam)
$MyData = DllStructCreate("char[" & DllStructGetData($COPYDATA, 2) & "]", DllStructGetData($COPYDATA, 3))
$gv_CoProcReviverParameter = DllStructGetData($MyData, 1)
Return 256
ElseIf $iMsg = 0x400 + 0x64 Then ; WM_USER+0x64
If $gv_CoProcReviverParameter Then
Call($gs_CoProcReciverFunction, $gv_CoProcReviverParameter)
If @error And @Compiled = 0 Then MsgBox(16, "CoProc Error", "Unable to Call: " & $gs_CoProcReciverFunction)
$gv_CoProcReviverParameter = 0
Return 0
EndIf
EndIf
EndFunc ;==>__CoProcReciverHandler

;===============================================================================
;
; Description: Send a Message to a CoProcess
; Parameter(s): $vProcess - Name or PID of Process
; $vParameter - Parameter to pass
; $iTimeout - Optional, Defaults to 500 (msec)
; $fAbortIfHung - Optional, Default is True
; Requirement(s): 3.2.4.9
; Return Value(s): On Success - Returns True
; On Failure - Returns False and Set
; @error to: 1 - Process not found
; 2 - Window not found
; 3 - Timeout/Busy/Hung
; 4 - PostMessage Falied
; Author(s): Florian 'Piccaso' Fida
; Note(s):
;
;==========================================================================
Func _CoProcSend($vProcess, $vParameter, $iTimeout = 500, $fAbortIfHung = True)
Local $iPid, $hWndTarget, $MyData, $aTmp, $COPYDATA, $iFuFlags
$iPid = ProcessExists($vProcess)
If Not $iPid Then Return SetError(1, 0, False) ; Process not Found
$hWndTarget = _ProcessGetWinList($vProcess, "", 16 + 2)
If @error Or (Not $hWndTarget) Then Return SetError(2, 0, False) ; Window not found
$MyData = DllStructCreate("char[" & StringLen($vParameter) + 1 & "]")
$COPYDATA = DllStructCreate("ptr;dword;ptr")
DllStructSetData($MyData, 1, $vParameter)
DllStructSetData($COPYDATA, 1, 1)
DllStructSetData($COPYDATA, 2, DllStructGetSize($MyData))
DllStructSetData($COPYDATA, 3, DllStructGetPtr($MyData))
If $fAbortIfHung Then
$iFuFlags = 0x2 ; SMTO_ABORTIFHUNG
Else
$iFuFlags = 0x0 ; SMTO_NORMAL
EndIf
$aTmp = DllCall("user32.dll", "int", "SendMessageTimeout", "hwnd", $hWndTarget, "int", 0x4A _; WM_COPYDATA
, "int", 0, "ptr", DllStructGetPtr($COPYDATA), "int", $iFuFlags, "int", $iTimeout, "long*", 0)
If @error Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
If Not $aTmp Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
If $aTmp <> 256 Then Return SetError(3, 0, False)
$aTmp = DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWndTarget, "int", 0x400 + 0x64, "int", 0, "int", 0)
If @error Then Return SetError(4, 0, False)
If Not $aTmp Then Return SetError(4, 0, False)
Return True
EndFunc ;==>_CoProcSend

;===============================================================================
;
; Description: Forwards StdOut and StdErr from specified Processes to Calling process
; Parameter(s): $iPid1 - Pid of Procces
; $iPidn - Optional, Up to 16 Processes
; Requirement(s): 3.1.1.131
; Return Value(s): None
; Author(s): Florian 'Piccaso' Fida
; Note(s): Processes must provide StdErr and StdOut Streams (See Run())
;
;==========================================================================
Func _ConsoleForward($iPid1, $iPid2 = Default, $iPid3 = Default, $iPid4 = Default, $iPid5 = Default, $iPid6 = Default, $iPid7 = Default, $iPid8 = Default, $iPid9 = Default, $iPid10 = Default, $iPid11 = Default, $iPid12 = Default, $iPid13 = Default, $iPid14 = Default, $iPid15 = Default, $iPid16 = Default)
Local $iPid, $i, $iPeek
For $i = 1 To 16
$iPid = Eval("iPid" & $i)
If $iPid = Default Or Not $iPid Then ContinueLoop
If ProcessExists($iPid) Then
$iPeek = StdoutRead($iPeek, 0, True)
If Not @error And $iPeek > 0 Then
ConsoleWrite(StdoutRead($iPid))
EndIf
$iPeek = StderrRead($iPeek, 0, True)
If Not @error And $iPeek > 0 Then
ConsoleWriteError(StderrRead($iPid))
EndIf
EndIf
Next
EndFunc ;==>_ConsoleForward

;===============================================================================
;
; Description: Removes as many pages as possible from the working set of the specified process.
; Parameter(s): $vPid - Optional, Pid or Process Name
; $hDll_psapi - Optional, Handle to psapi.dll
; $hDll_kernel32 - Optional, Handle to kernel32.dll
; Requirement(s): 3.2.1.12
; Return Value(s): On Success - nonzero
; On Failure - 0 and sets error to
; @error to: 1 - Process Doesent exist
; 2 - OpenProcess Failed
; 3 - EmptyWorkingSet Failed
; Author(s): Florian 'Piccaso' Fida
; Note(s): $vPid can be the -1 Pseudo Handle
;
;===============================================================================
Func _ProcessEmptyWorkingSet($vPid = @AutoItPID, $hDll_psapi = "psapi.dll", $hDll_kernel32 = "kernel32.dll")
Local $av_EWS, $av_OP, $iRval
If $vPid = -1 Then ; Pseudo Handle
$av_EWS = DllCall($hDll_psapi, "int", "EmptyWorkingSet", "ptr", -1)
Else
$vPid = ProcessExists($vPid)
If Not $vPid Then Return SetError(1, 0, 0) ; Process Doesent exist
$av_OP = DllCall($hDll_kernel32, "int", "OpenProcess", "dword", 0x1F0FFF, "int", 0, "dword", $vPid)
If $av_OP = 0 Then Return SetError(2, 0, 0) ; OpenProcess Failed
$av_EWS = DllCall($hDll_psapi, "int", "EmptyWorkingSet", "ptr", $av_OP)
DllCall($hDll_kernel32, "int", "CloseHandle", "int", $av_OP)
EndIf
If $av_EWS Then
Return $av_EWS
Else
Return SetError(3, 0, 0) ; EmptyWorkingSet Failed
EndIf
EndFunc ;==>_ProcessEmptyWorkingSet


;===============================================================================
;
; Description: Duplicates a Handle from or for another process
; Parameter(s): $dwSourcePid - Pid from Source Process
; $hSourceHandle - The Handle to duplicate
; $dwTargetPid - Optional, Pid from Target Procces - Defaults to current process
; $fCloseSource - Optional, Close the source handle - Defaults to False
; Requirement(s): 3.2.4.9
; Return Value(s): On Success - Duplicated Handle
; On Failure - 0 and sets error to
; @error to: 1 - Api OpenProcess Failed
; 2 - Api DuplicateHandle Falied
; Author(s): Florian 'Piccaso' Fida
; Note(s):
;
;===============================================================================
Func _DuplicateHandle($dwSourcePid, $hSourceHandle, $dwTargetPid = @AutoItPID, $fCloseSource = False)
Local $hTargetHandle, $hPrSource, $hPrTarget, $dwOptions
$hPrSource = __dh_OpenProcess($dwSourcePid)
$hPrTarget = __dh_OpenProcess($dwTargetPid)
If $hPrSource = 0 Or $hPrTarget = 0 Then
_CloseHandle($hPrSource)
_CloseHandle($hPrTarget)
Return SetError(1, 0, 0)
EndIf
; DUPLICATE_CLOSE_SOURCE = 0x00000001
; DUPLICATE_SAME_ACCESS = 0x00000002
If $fCloseSource <> False Then
$dwOptions = 0x01 + 0x02
Else
$dwOptions = 0x02
EndIf
$hTargetHandle = DllCall("kernel32.dll", "int", "DuplicateHandle", "ptr", $hPrSource, "ptr", $hSourceHandle, "ptr", $hPrTarget, "long*", 0, "dword", 0, "int", 1, "dword", $dwOptions)
If @error Then Return SetError(2, 0, 0)
If $hTargetHandle = 0 Or $hTargetHandle = 0 Then
_CloseHandle($hPrSource)
_CloseHandle($hPrTarget)
Return SetError(2, 0, 0)
EndIf
Return $hTargetHandle
EndFunc ;==>_DuplicateHandle
Func __dh_OpenProcess($dwProcessId)
; PROCESS_DUP_HANDLE = 0x40
Local $hPr = DllCall("kernel32.dll", "ptr", "OpenProcess", "dword", 0x40, "int", 0, "dword", $dwProcessId)
If @error Then Return SetError(1, 0, 0)
Return $hPr
EndFunc ;==>__dh_OpenProcess
Func _CloseHandle($hAny)
If $hAny = 0 Then Return SetError(1, 0, 0)
Local $fch = DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hAny)
If @error Then Return SetError(1, 0, 0)
Return $fch
EndFunc ;==>_CloseHandle



#region Internal Functions
Func __CoProcStartup()
Local $sCmd = EnvGet("CoProc")
If StringLeft($sCmd, 2) = "0x" Then
$sCmd = BinaryToString ($sCmd)
$gi_CoProcParent = Number(EnvGet("CoProcParent"))
If StringInStr($sCmd, "(") And StringInStr($sCmd, ")") Then
Execute($sCmd)
If @error And Not @Compiled Then MsgBox(16, "CoProc Error", "Unable to Execute: " & $sCmd)
Exit
EndIf
If EnvGet("CoProcParameterPresent") = "True" Then
Call($sCmd, BinaryToString (EnvGet("CoProcParameter")))
If @error And Not @Compiled Then MsgBox(16, "CoProc Error", "Unable to Call: " & $sCmd & @LF & "Parameter: " & BinaryToString (EnvGet("CoProcParameter")))
Else
Call($sCmd)
If @error And Not @Compiled Then MsgBox(16, "CoProc Error", "Unable to Call: " & $sCmd)
EndIf
Exit
EndIf
EndFunc ;==>__CoProcStartup
Func __CoProcDummy($vPar = Default)
If Not IsKeyword($vPar) Then _CoProcReciver($vPar)
While ProcessExists($gi_CoProcParent)
Sleep(500)
WEnd
EndFunc ;==>__CoProcDummy
__CoProcStartup()
#endregion

sdc7 发表于 2012-2-5 08:57:39

大兄弟。。。这个肯定是不能的~ 你自己想想多个进程相当于多个AU3脚本执行, 变量怎么可能通用!
实在需要的话就_CoProcSend 发送到主进程 主进程再接收,或者写到配置文件,主进程再读。传递下!

kemyliu 发表于 2012-2-5 09:06:03

回复 2# sdc7

现在是子进程要使用主进程的变量,主进程有没有办法传递参数给子进程啊?如上面的Label变量?

sdc7 发表于 2012-2-5 09:09:24

回复 3# kemyliu 一样的 子进程可以建立接收函数的`

kemyliu 发表于 2012-2-5 09:20:44

回复 4# sdc7

能否举个例子?非常感谢!

sdc7 发表于 2012-2-5 09:43:54

需要吗? 真的需要吗?跟主进程一样建立子进程函数`~~` 自己揣摩把

zldfsz 发表于 2012-2-5 10:24:59

回复 2# sdc7


请问_CoProcSend 是什么,是自定义函数吗?能否分享一下,怎么用?

sdc7 发表于 2012-2-5 10:38:03

回复 7# zldfsz


   你去看多进程的帮助去 自带函数   一个发送一个接收 不过建议你最好通过配置文件交换也不错

kemyliu 发表于 2012-2-5 11:12:21

回复 8# sdc7

label这样的变量也可以通过配置文件交换吗?这个不太懂

半芯竹 发表于 2012-2-5 11:31:24

本帖最后由 半芯竹 于 2012-2-5 17:44 编辑

回复 9# kemyliu #include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "CoProc.au3"
#Region ### START Koda GUI section ### Form=
Global $Label1
$Form1 = GUICreate("Form1", 623, 444, 192, 124)
$Button1 = GUICtrlCreateButton("OK", 168, 248, 249, 73)
$Label1 = GUICtrlCreateLabel("This is for test!", 184, 120, 230, 81)
GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        _CoProc(test(),$Label1)
      EndSwitch
WEnd
      
Func Test()
       GUICtrlSetData($Label1,"Change the text!")
EndFunc是你代码写错了而已 ,本身就可以传递变量。。

浪迹红客 发表于 2012-2-5 16:25:18

路过的。。。。。。。

kemyliu 发表于 2012-2-5 17:45:19

回复 10# 半芯竹



莫非你的可真的可以运行?看来这个真的是难题啊!!

半芯竹 发表于 2012-2-5 17:46:11

本帖最后由 半芯竹 于 2012-2-5 17:50 编辑

回复 12# kemyliu


    我的的确可以运行,你是否使用了我所发的代码?





Func Reciver($vParameter)
    ;$vParameter里就是子进程发来的消息
    $aParam = StringSplit($vParameter,"|")
    If $aParam = "small" Then MsgBox(0,"TT",$aParam)
EndFunc
我不知道你上面的这一段是用来干嘛的,没有看到主程序里有相当调用。

kemyliu 发表于 2012-2-5 19:47:43

回复 13# 半芯竹

非常感谢你的帮助,现在问题已经解决了,非常感谢!!#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "CoProc.au3"
#Region ### START Koda GUI section ### Form=
Global $Label1,$Label2,$arry
$Form1 = GUICreate("Form1", 623, 444, 192, 124)
$Button1 = GUICtrlCreateButton("OK", 168, 248, 249, 73)
$Label1 = GUICtrlCreateLabel("This is for test one!", 10, 120, 230, 81)
GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
$Label2 = GUICtrlCreateLabel("This is for test two!", 350, 120, 230, 81)
GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
GUISetState(@SW_SHOW)
$arry=$Label1
$arry=$Label2
#EndRegion ### END Koda GUI section ###

While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        _CoProc(test(),$arry)
      EndSwitch
WEnd
      
Func Test()
       GUICtrlSetData($arry,"Change the text One!")
           GUICtrlSetData($arry,"Change the text Two!")
           _CoProcSend($gi_CoProcParent,"small|1")
EndFunc

kemyliu 发表于 2012-2-6 14:20:10

回复 10# 半芯竹

实际上我的方法并没有错,按照你方法调用,实际只是但进程,必须一个进程完成才能运行另外一个进程。
正确的方法是: _CoProc("test1",$arry) 而非 _CoProc(test1(),$arry)
可以用下面的列子查看:#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "CoProc.au3"
#Region ### START Koda GUI section ### Form=
Global $Label1,$Label2,$arry
$Form1 = GUICreate("Form1", 623, 444, 192, 124)
$Button1 = GUICtrlCreateButton("OK", 168, 248, 249, 73)
$Label1 = GUICtrlCreateLabel("This is for test one!", 10, 120, 230, 81)
GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
$Label2 = GUICtrlCreateLabel("This is for test two!", 350, 120, 230, 81)
GUICtrlSetFont(-1, 24, 800, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x0000FF)
GUISetState(@SW_SHOW)
$arry=$Label1
$arry=$Label2
#EndRegion ### END Koda GUI section ###

While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        _CoProc(test1(),$arry)
                                                _CoProc(test2(),$arry)
      EndSwitch
WEnd
      
Func Test1()
        try($arry)
;~         _CoProcSend($gi_CoProcParent,"small|1")
EndFunc

      
Func Test2()
        MsgBox(0,"$arry",$arry)
EndFunc

Func try($arry)
        GUICtrlSetData($arry,"Change the text One!")
        GUICtrlSetData($arry,"Change the text Two!")
        Sleep(10000)
EndFunc

          
       
页: [1] 2
查看完整版本: 【已解决】多进程子进程无法使用主进程的变量