Что нового

Консольное управление скриптом

musicstashall

Знающий
Сообщения
322
Репутация
7
Поделитесь пожалуйста опытом, дайте пример скрипта, который может управляться атрибутами из командной строки. Важно, чтобы сам скрипт не был сугубо консольным приложением, но имел пользовательский интерфейс. Хочу создать ярлык с атрибутами, чтобы скрипт выполнил какую либо функцию, например, открыл окно и тп... :IL_AutoIt_1:
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Alofa сказал(а):

Это очень интересное для меня открытие, ни разу на глаза не попадалось. Спасибо. Но я наверное неправильно поставил вопрос, мне не нужно запускать мой скрипт с какими-то параметрами, а управлять уже запущенным скриптом. Мне нужно получить доступ к функциям, наверное нужно создать что-то на подобие DLL и вызывать оттуда функции... Идея такая: добавить в контекстное меню команду для моего скрипта. Например:

Код:
Local $Key = 'HKEY_CLASSES_ROOT\DesktopBackground\Shell\Personalization'
RegWrite($Key & '\Shell\10tools', 'Icon', $_REG_SZ, @ScriptDir & '\myscript.exe')
RegWrite($Key & '\Shell\10tools', 'MUIVerb', $_REG_SZ, $MyName)
RegWrite($Key & '\Shell\10tools\Command', '', $_REG_SZ, @ScriptDir & '\myscript.exe -tools')


В данном случае команда «myscript.exe -tools» должна открыть окно.
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Супер! От души. Регистрация своего сообщения — это то что нужно.


Добавлено:
Сообщение автоматически объединено:

Реализовал, всё отлично работает:

Код:
; отправляем
$MESSAGE = _WinAPI_RegisterWindowMessage("MESSAGE")
If IsArray($CmdLine) Then
	$wParam = StringToBinary($CmdLine[1])
	$lParam = StringToBinary($CmdLine[2])
EndIf
ConsoleWrite($wParam & @CR & $lParam & @CR)
_WinAPI_PostMessage($hWND, $MESSAGE, $wParam, $lParam)

; получаем
$GET_MESSAGE = _WinAPI_RegisterWindowMessage("MESSAGE")
If IsAdmin() Then _WinAPI_ChangeWindowMessageFilterEx($hWnd, $GET_MESSAGE, $MSGFLT_ALLOW)
GUIRegisterMsg($GET_MESSAGE, "GET_MESSAGE")
Func GET_MESSAGE($Wnd, $Msg, $wParam, $lParam)
    Switch $wParam
		Case 1001 ; к примеру
			GuiOpenPage('Tab11')
		Case 1002
			GuiOpenPage('Tab12')	
		Case 1003
			GuiOpenPage('Tab13')	
		Case 1004
			GuiOpenPage('Tab14')	
		Case 1005
			GuiOpenPage('Tab15')	
	EndSwitch
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
musicstashall
в каком формате эти параметры должны отправляться, стринг или хекс?
Типы данных Windows
Фактически wParam и lParam - это числа. Строку просто так через эти параметры не передать. См. пример в английской справке к функции _WinAPI_CreateString. Также посмотрите: Еще один способ итеракции процессов

Можно организовать таблицу соответствия числа и команды и передавать через wParam или lParam число в соответствие с командой из командной строки. В принимающем скрипте через Switch определить по числу команду и выполнить её.

А совсем просто сделать в принимающем окне скрытый Edit и писать прямо в него через ControlSetText хоть всю командную строку целиком ;)
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Попробовал организовать передачу строки — почему-то не работает:

Код:
; передаем:
$lParam = _WinAPI_CreateString($CmdLine[2])
_WinAPI_SetMessageExtraInfo($lParam)

;получаем:
Local $pString = _WinAPI_GetMessageExtraInfo()
Local $sFunc = _WinAPI_GetString($pString)
_WinAPI_FreeMemory($lParam) ; !!!
Call($sFunc)


Интересно, эта функция работает только внутри одного потока?? То есть я не могу передавать сообщение из скрипта в скрипт?


Добавлено:
Сообщение автоматически объединено:

У меня исполняющий скрипт запускается от имени администратора, это усложняет дело.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
для обмена данными между процессами использую http://autoit-script.ru/index.php?topic=2733.0
в справке тоже есть этот пример
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Я смотрел этот пример, но почему-то отверг. Как он работает?? Там создаются какие-то файлы? Объяните в двух словах пожалуйста...
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
создается виртуальный файл (в памяти) одним из скриптов, второй (и все последующие) подключаются к этому файлу. все подключенные процессы могут пересылать друг другу строчные данные.
скомпилируй эти коды
запусти первый , потом второй. во втором окне кликай по строкам, результат будет появляться в первом окне

первый
Код:
#include <WinAPIFiles.au3>
Local $MapFile = _WinAPI_CreateFileMapping(-1, 4096, 'DataExchangeFile')
Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
Local $StructFile = DllStructCreate('wchar string[512];int id[10]', $PosFile)
Local $Form1 = GUICreate('Form1', 243, 114, 192, 124)
Local $Label1 = GUICtrlCreateLabel('', 32, 24, 148, 17)
Local $Label2 = GUICtrlCreateLabel('', 32, 64, 156, 17)
GUISetState()
Local $str = '', $int = 0
While 1
	$str = StringStripWS(DllStructGetData($StructFile, 'string'), 3)
	$int = DllStructGetData($StructFile, 'id')
	If $str <> '' Then
		GUICtrlSetData($Label1, 'text - ' & $str)
		DllStructSetData($StructFile, 1, '')
		$str = ''
	EndIf
	If $int Then
		GUICtrlSetData($Label2, 'id - ' & $int)
		DllStructSetData($StructFile, 2, 0)
		$int = 0
	EndIf
	Switch GUIGetMsg()
		Case -3
			Exit

	EndSwitch
WEnd


второй
Код:
#include <WinAPIFiles.au3>
Local $MapFile = _WinAPI_OpenFileMapping('DataExchangeFile')
If Not $MapFile Then Exit
Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
Local $StructFile = DllStructCreate('wchar string[512];int id[10]', $PosFile)
Local $Form2 = GUICreate("Form2", 548, 315, -1, -1)
Local $Label1 = GUICtrlCreateLabel("Label1", 56, 32, 332, 17)
Local $Label2 = GUICtrlCreateLabel("Label2", 56, 72, 340, 17)
Local $Label3 = GUICtrlCreateLabel("Label3", 56, 120, 332, 17)
Local $Label4 = GUICtrlCreateLabel("Label4", 56, 160, 332, 17)
Local $Label5 = GUICtrlCreateLabel("Label5", 52, 210, 332, 17)
GUISetState()

While 1
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $Label1
			DllStructSetData($StructFile, 'string', GUICtrlRead($Label1))
			DllStructSetData($StructFile, 'id', $Label1)
		Case $Label2
			DllStructSetData($StructFile, 'string', GUICtrlRead($Label2))
			DllStructSetData($StructFile, 'id', $Label2)
		Case $Label3
			DllStructSetData($StructFile, 'string', GUICtrlRead($Label3))
			DllStructSetData($StructFile, 'id', $Label3)
		Case $Label4
			DllStructSetData($StructFile, 'string', GUICtrlRead($Label4))
			DllStructSetData($StructFile, 'id', $Label4)
		Case $Label5
			DllStructSetData($StructFile, 'string', GUICtrlRead($Label5))
			DllStructSetData($StructFile, 'id', $Label5)

	EndSwitch
WEnd
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
А! Структура в память мапится?? Круто! Делаю...
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Вот ещё одна "крутотень". Запись ANSI текста в память процесса приёмника. Длина текста и указатель на область памяти передаётся через собственное сообщение в параметрах wParam и lParam соответственно.

Приёмник
Код:
#include <WinAPI.au3>

$GUI = GUICreate("Приёмник")
$Edit = GUICtrlCreateEdit("", 5, 5, 390, 390)
GUISetState()

GUIRegisterMsg(_WinAPI_RegisterWindowMessage("Transmit"), "Transmit")

Do
  Switch GUIGetMsg()
    Case -3
      Exit
  EndSwitch
Until 0

Func Transmit($hWnd, $iMsg, $wParam, $lParam)
  Local $Buf = DllStructCreate("char[" & Int($wParam) & "]", $lParam)
  Local $Text = BinaryToString(DllStructGetData($Buf, 1))
  GUICtrlSetData($Edit, $Text)
EndFunc

Передатчик
Код:
#include <WinAPI.au3>
#include <Memory.au3>

$GUI = GUICreate("Передатчик")
$Edit = GUICtrlCreateEdit("", 5, 5, 390, 340)
$Btn = GUICtrlCreateButton("Отправить", 150, 360, 100, 30)
GUISetState()

$Transmit = _WinAPI_RegisterWindowMessage("Transmit")

Do
  Switch GUIGetMsg()
    Case -3
      Exit
    Case $Btn
      $hWnd = WinGetHandle("Приёмник")
      $PID = WinGetProcess($hWnd)
      $Text = GUICtrlRead($Edit)
      $Len = StringLen($Text)
      $Buf = DllStructCreate("char[" & $Len & "]")
      DllStructSetData($Buf, 1, GUICtrlRead($Edit))
      $hProc = _WinAPI_OpenProcess(BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_WRITE), False, $PID, True)
      $pMem = _MemVirtualAllocEx($hProc, 0, $Len, $MEM_COMMIT, $PAGE_READWRITE)
      $Written = 0
      _WinAPI_WriteProcessMemory($hProc, $pMem, DllStructGetPtr($Buf), $Len, $Written)
      _SendMessage($hWnd, $Transmit, $Len, $pMem)
      _MemVirtualFreeEx($hProc, $pMem, $Len, $MEM_DECOMMIT)
  EndSwitch
Until 0
 
Верх