Что нового

_WinAPI_AssignProcessToJobObject(): тест на Vista/7

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Друзья, у кого стоит Windows 7, просьба проверить пример для функции _WinAPI_AssignProcessToJobObject() из WinAPIEx.au3. Я пробывал запускать на Vist'е... нефига не работает. При вызове _WinAPI_AssignProcessToJobObject() выдает ошибку "Access denied". Поиск выдал это, ну просто :Censored: какая-то, иначе не назовешь. Вот мне и интересно, как это работает в 7-ке, надеюсь Microsoft изменил этот :Censored: UAC.

И все же жуткая система эта Vista...
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied
Запускал скрипт из примера в справке к _WinAPI_AssignProcessToJobObject()
1. На XP SP3 запускает 3 калькулятора и ждет, пока их не закроешь.
2. На Win 7 32 запускает 3 калькулятора и просто без ошибки заканчивает свою работу. :(
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Спасибо madmasles. А если скрипт сначала откомпилировать, затем запустить .exe?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied
Скомпилировал скрипт и запускал его на Win 7 32, что с включенным UAC, что с отключенным, результат один и тот же:
У меня срабатывает, то есть ждет закрытия всех трех калькуляторов только первый раз после перезагрузки. Любой последующий запуск просто открывает три калькулятора и завершает свою работу. Мистика какая-то. :shok:
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
:Censored:



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

madmasles, еще одна просьба. Попробуй положить файл манифеста в один каталог с компилированным примером и запусти .exe (разумеется название .exe и .manifest должны быть одинаковыми).

Код:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel
        level="requireAdministrator"
        uiAccess="false"/>
      </requestedPrivileges>
  </security>
</trustInfo>
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied [?]
Попробуй положить файл манифеста в один каталог с компилированным примером и запусти .exe
Все так и сделал - то же самое, один запуск с отработкой и все. Забыл в прошлый раз написать, в скрипт добавил с самого начала #RequireAdmin.
 
Автор
Yashied

Yashied

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

Код:
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global Const $sTemp = @TempDir & '\Test.au3'

Global $hFile

; Create temporary .au3 file
$hFile = FileOpen($sTemp, 2)
For $i = 1 To 3
	FileWriteLine($hFile, 'Run(@SystemDir & "\calc.exe")')
Next
FileClose($hFile)

; Run 3 times the "calc.exe" and wait until you have closed all 3 processes
_RunWaitEx(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sTemp & '"')

; Delete temporary .au3 file
FileDelete($sTemp)

Func _RunWaitEx($sCMD)

	; Original idea by amel27

	Local $tProcess = DllStructCreate($tagPROCESS_INFORMATION)
	Local $tStartup = DllStructCreate($tagSTARTUPINFO)
	Local $tInfo = DllStructCreate($tagJOBOBJECT_BASIC_ACCOUNTING_INFORMATION)
	Local $hJob, $hProcess, $hThread

	$hJob = _WinAPI_CreateJobObject()
	If @error Then
		Return SetError(1, 0, 0)
	EndIf
	DllStructSetData($tStartup, 'Size', DllStructGetSize($tStartup))
	If Not _WinAPI_CreateProcess('', $sCMD, 0, 0, 0, 0x01000004, 0, 0, DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) Then
		Return SetError(1, _WinAPI_FreeHandle($hJob), 0)
	EndIf
	$hProcess = DllStructGetData($tProcess, 'hProcess')
	$hThread = DllStructGetData($tProcess, 'hThread')
	_WinAPI_AssignProcessToJobObject($hJob, $hProcess)
	_WinAPI_ResumeThread($hThread)
	_WinAPI_FreeHandle($hThread)
	Do
		If Not _WinAPI_QueryInformationJobObject($hJob, 1, $tInfo) Then
			ExitLoop
		EndIf
		Sleep(100)
	Until Not DllStructGetData($tInfo, 'ActiveProcesses')
	_WinAPI_FreeHandle($hProcess)
	_WinAPI_FreeHandle($hJob)
	Return 1
EndFunc   ;==>_RunWaitEx

Func _WinAPI_ResumeThread($hThread)

	Local $Ret = DllCall('kernel32.dll', 'dword', 'ResumeThread', 'ptr', $hThread)

	If (@error) Or (_WinAPI_DWordToInt($Ret[0]) = -1) Then
		Return SetError(1, 0, -1)
	EndIf
	Return $Ret[0]
EndFunc   ;==>_WinAPI_AssignProcessToJobObject
 
Верх