Что нового

Открытие документов из проводника в уже запущенную программу - как это проиходит

pboy

Новичок
Сообщения
18
Репутация
0
Есть программы, которые могут открывать сразу несколько файлов (например, MS Word). Когда мы нажимаем на документ в проводнике, а программа-обработчик уже была открыта до этого, документ открывается в уже запущенном экземпляре программы, а не в новом. Вопрос - как подобное можно реализовать в свой программе на AutoIt, чтоб больше одного процесса не запускалось, документ открывался в первом и единственном?
Аспект в каких окнах или субокнах всё это открывать - не суть важен.
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
как это реализовать на автоите не знаю но можно чтонить замутить
а вообще система такая что вот ты запустил прогу (Экз-1) и в неё что-то ты открыл, и когда ты будешь запускать ещё раз эту же программу но уже с файлом в параметре(Экз-2), программа (Экз-2) проверит запущенали её копия уже на компьютере и находит программу (Экз-1), далее (Экз-2) через SenMessage отправляет в (Экз-1) иформацию о файле для открыти и (Экз-1) его открывает
Всё просто же :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Есть два варианта организовать открытие множества файлов через проводник:

1. Отслеживание повторного запуска приложения и передача параметров в основное окно.
2. Использование Dynamic Data Exchange (DDE).

Второй способ основан на СОМ и довольно муторный, но тем не менее реализуем на AutoIt. Необходимую библиотеку с примерами можно найти здесь. Что касается первого способа, то вот простой пример (взят из архива, поэтому оптимальность кода не гарантирую):

Код:
#NoTrayIcon

#Include <APIConstants.au3>
#Include <Array.au3>
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)
Opt('WinTitleMatchMode', 3)
Opt('WinWaitDelay', 0)

If Not $CmdLine[0] Then
	Exit
EndIf

Global $tCOPYDATA, $hReceiver, $hMutex, $Ret, $Lenght, $Count = 1
Global $Path[101] = [1, $CmdLine[1]]

$hMutex = _WinAPI_CreateMutex('{3891B756-85A2-4274-9226-5E66967E60A4}')
If _WinAPI_GetLastError() = 183 Then
	$hReceiver = WinWait('{A257F21D-D0BF-4CE9-A6C9-84C7D258C91B}', '', 3)
	If @error Then
		Exit
	EndIf
	$Lenght = StringLen($CmdLine[1]) + 1
	$tCOPYDATA = DllStructCreate('ulong_ptr;dword;ptr;wchar[' & $Lenght & ']')
	DllStructSetData($tCOPYDATA, 1, 0x1000)
	DllStructSetData($tCOPYDATA, 2, 2 * $Lenght)
	DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tCOPYDATA, 4))
	DllStructSetData($tCOPYDATA, 4, $CmdLine[1])
	$Ret = DllCall('user32.dll', 'uint', 'SendMessage', 'hwnd', $hReceiver, 'uint', $WM_COPYDATA, 'ptr', 0, 'ptr', DllStructGetPtr($tCOPYDATA))
	If (@error) Or (Not $Ret[0]) Then
		; Nothing
	EndIf
	Exit
EndIf

$hReceiver = GUICreate('{A257F21D-D0BF-4CE9-A6C9-84C7D258C91B}')
GUIRegisterMsg($WM_COPYDATA, 'WM_COPYDATA')

While 1
	Sleep(200)
	If $Path[0] = $Count Then
		ExitLoop
	EndIf
	$Count = $Path[0]
WEnd

GUIRegisterMsg($WM_COPYDATA, '')
GUIDelete($hReceiver)

_WinAPI_CloseHandle($hMutex)

ReDim $Path[$Path[0] + 1]

_ArrayDisplay($Path)

Func WM_COPYDATA($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hReceiver
			Local $tCOPYDATA = DllStructCreate('ulong_ptr;dword;ptr', $lParam)
			Switch DllStructGetData($tCOPYDATA, 1)
				Case 0x1000
					$Path[0] += 1
					If $Path[0] > UBound($Path) - 1 Then
						ReDim $Path[$Path[0] + 100]
					EndIf
					$Path[$Path[0]] = DllStructGetData(DllStructCreate('wchar[' & (DllStructGetData($tCOPYDATA, 2) / 2) & ']', DllStructGetData($tCOPYDATA, 3)), 1)
					Return 1
			EndSwitch
	EndSwitch
	Return 0
EndFunc   ;==>WM_COPYDATA


Как проверить. Скомпилируйте этот скрипт в .ехе файл (MyScript.exe) и зарегистрируйте какое-нибудь неиспользуемое расширение для него, например .zzz:

Код:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.zzz]
@="ZZZ.File"

[HKEY_CLASSES_ROOT\ZZZ.File]

[HKEY_CLASSES_ROOT\ZZZ.File\shell]

[HKEY_CLASSES_ROOT\ZZZ.File\shell\Open]

[HKEY_CLASSES_ROOT\ZZZ.File\shell\Open\command]
@="\"C:\\MyScript.exe\" \"%1\""

Затем наделайте кучу .zzz файлов (1.zzz, 2.zzz и т.д.), выделите их все и выберите в контекстном меню "Open". После этого проводник будет делать последовательные вызовы:

C:\MyScript.exe 1.zzz
C:\MyScript.exe 2.zzz
C:\MyScript.exe 3.zzz

и т.д.

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

Узким местом здесь является определение конца списка имен файлов, т.к. узнать об этом не представляется возможным. Поэтому в цикле стоит небольшая задержка (200 мс). Если по каким-либо причинам задержка между вызовами приложения превысит 200 мс (что вряд ли), то скрипт выдаст неполный список файлов, а остаток пойдет во вторую пачку, т.е. на экране будет отображено последовательно два списка. В большинстве случаев некритично, но это нужно иметь ввиду и при необходимости увеличить задержку.

P.S.

GUID в скрипте взяты просто как имена и не имеют никакой логической нагрузки.
 
Верх