Что нового

Обмен данными между процессами,автоматизация

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
AutoIt: 3.3.12.0

Категория: Интеракция

Описание: Изначально примеры взяты из http://autoit-script.ru/index.php?topic=2733.0
Теперь их можно найти в справке (английский). Я использовал этот метод для двустороннего обмена данными между процессами.
Данные функции - это попытка немного автоматизировать процесс создания файла и структуры данных

Sender:
Код:
#include <WinAPIFiles.au3>
#include <WinAPI.au3>

HotKeySet('{ESC}', '_exit')

;$CreateFileMap = _CreateFileMap()
;$CreateFileMap = _CreateFileMap('world')
$CreateFileMap = _CreateFileMap('123','int','one','512')
;$CreateFileMap = _CreateFileMap('world|war','wchar|char','one|two','512|1024')
;$CreateFileMap = _CreateFileMap('|','wchar|char','one|two','512|1024')
;$CreateFileMap = _CreateFileMap('world|war','wchar|char','one|two','|')
;$CreateFileMap = _CreateFileMap('|','wchar|char','one|two','|')
If @error Then
	MsgBox(16, 'Ошибка', @error)
	Exit
EndIf

Func _exit()
	Exit
EndFunc   ;==>_exit

ConsoleWrite($CreateFileMap[2].one & @CR)

While 1
	Sleep(1000)
WEnd

;Функция: _CreateFileMap($IncomingData = '', $DataType = 'wchar', $ElementName = 'var', $ElementSize = '', $Separator = '|', $FileMapName = 'DataExchangeFile')
;
;Параметры:
;                     $IncomingData - входящие данные(единичные данные или разделенные символом $Separator)
;                     $DataType - тип данных.при создании нескольких элементов используется $Separator
;                     $ElementName - имя элемента структуры. при создании нескольких элементов используется $Separator
;                     $ElementSize  - размер элемента структуры.если указан размер, то фактический размер данных игнорируется.при создании нескольких элементов используется $Separator
;                     $Separator - знак разделитель,которым разделяем блоки данных в $IncomingData, $DataType, $ElementName,$ElementSize
;                     $FileMapName - имя создаваемого файла
;Возвращаемые значения:
;                     Успех. Массив, в котором:
;                       $array[0] - дескриптор файла
;                       $array[1] - адрес подключения к файлу
;                       $array[2] - указатель структуры
;                     Ошибка:
;                        1 - Неправильно указаны параметры функции
;                        2 - Ошибка создания файла
;                        3 - Ошибка подключения к файлу
;                        4 - Ошибка создания структуры
;Автор:                joiner
;
;Примечание:
;       При создании нескольких элементов структуры (даже если они будут пустые), обязательно использование $Separator
Func _CreateFileMap($IncomingData = '', $DataType = 'wchar', $ElementName = 'var', $ElementSize = '', $Separator = '|', $FileMapName = 'DataExchangeFile')
	Local $DataSize, $CreatedStruct, $InfoSizeStruct, $BaseStruct, $tagSTRUCT, $hMapping, $pAddress, $tData

	Local $SplitInData = StringSplit($IncomingData, $Separator)
	Local $SplitDataType = StringSplit($DataType, $Separator)
	Local $SplitNameData = StringSplit($ElementName, $Separator)
	Local $SplitSizeData = StringSplit($ElementSize, $Separator)

	If $SplitInData[0] <> $SplitNameData[0] Or $SplitInData[0] <> $SplitDataType[0] Or $SplitInData[0] <> $SplitSizeData[0] Then Return SetError(1)

	For $i = 1 To $SplitInData[0]
		If $SplitDataType[$i] = '' Or $SplitNameData[$i] = '' Then ContinueLoop
		$DataNextElement = StringLen($SplitInData[$i])
		$DataSize += $DataNextElement
		If $SplitInData[$i] = '' And $SplitSizeData[$i] = '' Then
			$CreatedStruct &= $SplitDataType[$i] & ' ' & $SplitNameData[$i] & ';'
		ElseIf Not $SplitSizeData[$i] = '' Then
			$CreatedStruct &= $SplitDataType[$i] & ' ' & $SplitNameData[$i] & '[' & $SplitSizeData[$i] & ']' & ';'
		ElseIf Not $SplitInData[$i] = '' And $SplitSizeData[$i] = '' Then
			$CreatedStruct &= $SplitDataType[$i] & ' ' & $SplitNameData[$i] & '[' & $DataNextElement & ']' & ';'
		EndIf
	Next

	$CreatedStruct = StringTrimRight($CreatedStruct, 1)

	$InfoSizeStruct = StringLen($CreatedStruct)
	$BaseStruct = 'short sol[10];wchar info[' & $InfoSizeStruct & '];'
	$tagSTRUCT = $BaseStruct & $CreatedStruct
	$hMapping = _WinAPI_CreateFileMapping(-1, ($DataSize + $InfoSizeStruct) * 2 + 20, $FileMapName)
	If $hMapping = 0 Then Return SetError(2, _WinAPI_GetLastError())
	$pAddress = _WinAPI_MapViewOfFile($hMapping)
	If $pAddress = 0 Then Return SetError(3, _WinAPI_GetLastError())
	$tData = DllStructCreate($tagSTRUCT, $pAddress)
	If @error Then Return SetError(4, @error)
	$tData.sol = $InfoSizeStruct
	$tData.info = $CreatedStruct

	For $i = 1 To $SplitInData[0]
		DllStructSetData($tData, $SplitNameData[$i], $SplitInData[$i])
	Next

	Local $dArray[3]
	$dArray[0] = $hMapping
	$dArray[1] = $pAddress
	$dArray[2] = $tData

	Return $dArray
EndFunc   ;==>_CreateFileMap

Receiver:
Код:
#include <WinAPIFiles.au3>
#include <WinAPI.au3>

$OpenFileMap = _OpenFileMap()
If @error Then
	MsgBox(0, @extended, @error)
	Exit
EndIf
ConsoleWrite($OpenFileMap[2].one & @CR)


While 1
	Sleep(1000)
WEnd

; Функция _OpenFileMap - подключение к файлу, созданному функцией _CreateFileMap
; Возвращаемые значения те же

Func _OpenFileMap($FileMapName = 'DataExchangeFile')
	Local $TempData, $TempInfData
	Local $hMapping = _WinAPI_OpenFileMapping($FileMapName)
	If $hMapping = 0 Then Return SetError(1, _WinAPI_GetLastError())
	Local $pAddress = _WinAPI_MapViewOfFile($hMapping)
	If $pAddress = 0 Then Return SetError(2, _WinAPI_GetLastError())
	Local $t_Data = DllStructCreate('short sol[10]', $pAddress)
	If @error Then Return SetError(3, @error)
	$TempData = $t_Data.sol
	$t_Data = 0
	Local $tInfData = DllStructCreate('short sol[10];wchar info[' & $TempData & ']', $pAddress)
	If @error Then Return SetError(4, @error)
	$TempInfData = $tInfData.info
	$tInfData = 0
	Local $tData = DllStructCreate('short sol[10];wchar info[' & $TempData & '];' & $TempInfData, $pAddress)
	If @error Then Return SetError(5, @error)
	Local $dArray[3]
	$dArray[0] = $hMapping
	$dArray[1] = $pAddress
	$dArray[2] = $tData
	Return $dArray
EndFunc   ;==>_OpenFileMap

Источник: autoit-script.ru
Автор(ы): joiner
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Re: Обмен данными между процессами

OffTopic:
ну..если прикрепить моторчик, то можно :smile:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Re: Обмен данными между процессами

Мне кажется, что структура могла бы быть фиксированного размера. Например byte[64 * 1024 * 1024].
OffTopic:
64 мегабайта хватит всем :whistle:.
. Мне пока еще никогда не было нужно передавать больше данных другому процессу.
И тогда весь код сократился бы до пару строк.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Re: Обмен данными между процессами

а структура и так не большая. два базовых элемента. размер файла и структуры формируется исходя из размера входящих данных
от этого такой размер функции. подсчет, сортировка и тп
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Re: Обмен данными между процессами

Не очень практично.
Я бы хотел иметь возможность передавать тип данных "как есть", например:

Код:
_CreateFileMap(0, $aArray, 'var1')
_CreateFileMap(0, $tPointer, 'var2')
_CreateFileMap(0, $oObject, 'var3')


это умеет делать Container UDF.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Re: Обмен данными между процессами

CreatoR
функция не претендует на пальму первенства
Yashied [?]
На мой взгляд, это один из самых простых способов обмена данными между процессами.
я разделил свой код http://autoit-script.ru/index.php?topic=13191.0
на два процесса, первый передает данные для копирования, второй копирует и информирует о деталях: процент копирования, текущий файл и прочее.
пример Yashied`а вполне подошел для двустороннего обмена. и ни разу не было ошибки
я написал эти функции чтобы автоматизировать создание файла(не прописывать постоянно его размер) и создание структуры..
массив можно передать строкой, а потом его восстановить в принимающем файле. это ведь просто.
насчет остального, то пусть будут другие методы. у меня не возникало нужды в этом.
насчет Container UDF, то я ее тоже пробовал..еще тогда ХР было на рабочем компе. выдавало ошибки. я отказался.
да, сейчас это не актуально, ХР почти в руках не бывает. но все же
думаю, что идеального метода нет
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Re: Обмен данными между процессами

joiner [?]
ХР почти в руках не бывает
У нас в школе на многих компьютерах установлена XP, у нескольких моих друзей тоже, на моём старом ноутбуке тоже XP... Так что она пока в руках... :smile: ;) :D
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
сделал некоторые упрощения в первой функции. смотри описание
 
Верх