Что нового

[Процессы] Контроль над программой.

ZanMax

Тестер
Сообщения
120
Репутация
5
Всем привет.
У меня такая ситуация :
Есть корпоративная программа которая сервер Xeon с 8 ядрами и с 16 гб ОЗУ загружает под завязку.
Нагружает потому что пользователи запускают 2 - 4 - 8 копий этой програмки.Сама программа ничего не делает но опредильоный ее модуль (выборка с БД) просто убивает сервер.
Как возможно контролировать программу. Не давать пользователю открыть болие 1 копии. Тоесть програм он может запустить хоть 10 но если появляеться болие 1 окна с заголовком "ВЫБОРКА" он закрывает именно новое окно и выдает сообщение мол "НЕЛЬЗЯ запустить болие 1 копии".
Даеюсь все ясно росказал.
Спасибо большое.
 

killbond

Осваивающий
Сообщения
96
Репутация
32
Вот, выключается по Ctrl+Alt+Q. Признак в $sTitle, естественно, свой.
Код:
#include <Misc.au3>
#NoTrayIcon

$sTitle = "Калькулятор Плюс"

While (Not _IsPressed (11)) OR (Not _IsPressed (12)) OR (Not _IsPressed (51))
	$avWnds = WinList ($sTitle)
	if $avWnds [0] [0] > 1 Then
		For $iCounter = 2 to $avWnds [0] [0]
			WinKill ($avWnds [$iCounter] [1])
		Next
		MsgBox (16, '', 'Нельзя запустить более одной копии ' & '"' & WinGetTitle($sTitle) & '"', 3)
	EndIf
	sleep (50)
WEnd
 

Guezt

Продвинутый
Сообщения
335
Репутация
81
ZanMax
Код:
Opt("WinTitleMatchMode", 3) ; точное совпадение
$hWin = "ВЫБОРКА"
$hWinNew = "ВЫБОРКА (одна копия)"

While 1
	WinWaitActive("") ; ждем окно
	If WinWaitActive($hWin) Then ; Если выборка то
		If Not WinExists($hWinNew) Then ; Если нет нашего первого окна то
			   WinSetTitle($hWin,"",$hWinNew) ; создадим его
		   Else  ; иначе ( тоесть если есть )
			   WinClose($hWin) ; закроем это
			   MsgBox(0,"","НЕЛЬЗЯ запустить болие 1 копии") ; предупредим
			   WinActive($hWinNew) ; активируем то что есть!
		EndIf
	EndIf
	Sleep(500)
WEnd

или так :smile:
 

killbond

Осваивающий
Сообщения
96
Репутация
32
OffTopic:
Код:
MsgBox(0,"","НЕЛЬЗЯ запустить болие 1 копии")
Это сарказм? :rofl:
 
Автор
Z

ZanMax

Тестер
Сообщения
120
Репутация
5
killbond сказал(а):
Вот, выключается по Ctrl+Alt+Q. Признак в $sTitle, естественно, свой.
Код:
#include <Misc.au3>
#NoTrayIcon

$sTitle = "Калькулятор Плюс"

While (Not _IsPressed (11)) OR (Not _IsPressed (12)) OR (Not _IsPressed (51))
	$avWnds = WinList ($sTitle)
	if $avWnds [0] [0] > 1 Then
		For $iCounter = 2 to $avWnds [0] [0]
			WinKill ($avWnds [$iCounter] [1])
		Next
		MsgBox (16, '', 'Нельзя запустить более одной копии ' & '"' & WinGetTitle($sTitle) & '"', 3)
	EndIf
	sleep (50)
WEnd
Спасибо большое. Но как сделать закрытие новой копии ???
Нужно закрывать все новые копии. А первою всегда оставлять.
Спасибо всем кто откликнулся. Очень ценю вашу помощь.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
а каждая копия опрашиваемого окна порождает новый процесс или все в пределах одного родительского?
 

Yashied

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

Код:
#Include <Date.au3>
#Include <WinAPI.au3>

Opt('MustDeclareVars', 1)

Global $tFILETIME, $tFirst, $List, $Title = 'Calculator'

While 1
	$List = WinList($Title)
	If $List[0][0] > 1 Then
		For $i = 1 To $List[0][0] ; ищем самую первую копию
			$List[$i][0] = WinGetProcess($List[$i][1])
			$tFILETIME = _GetProcessCreationTime($List[$i][0])
			If $i > 1 Then
				If _Date_Time_CompareFileTime(DllStructGetPtr($tFILETIME), DllStructGetPtr($tFirst)) > 0 Then
					ContinueLoop
				EndIf
			EndIf
			$tFirst = $tFILETIME
			$List[0][1] = $i
		Next
		For $i = 1 To $List[0][0] ; убиваем все процессы, кроме самого первого
			If $i <> $List[0][1] Then
				ProcessClose($List[$i][0])
			EndIf
		Next
		MsgBox(16, ':)', 'Нельзя запускать более одной копии программы!')
	EndIf
	Sleep(500)
WEnd

Func _GetProcessCreationTime($PID)

	Local $hProc = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'dword', 0x00000400, 'int', 0, 'dword', $PID)

	If (@error) Or ($hProc[0] = 0) Then
		Return SetError(1, 0, 0)
	EndIf

	$hProc = $hProc[0]

	Local $tFILETIME = DllStructCreate('dword;dword')
	Local $Ret = DllCall('kernel32.dll', 'int', 'GetProcessTimes', 'ptr', $hProc, 'ptr', DllStructGetPtr($tFILETIME), 'ptr*', 0, 'ptr*', 0, 'ptr*', 0)

	If (@error) Or ($Ret[0] = 0) Then
		$Ret = 0
	EndIf
	_WinAPI_CloseHandle($hProc)
	If Not IsArray($Ret) Then
		Return SetError(1, 0, 0)
	EndIf
	Return $tFILETIME
EndFunc   ;==>_GetProcessCreationTime



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

OffTopic:
Я думаю тебя те самые пользователи за это живьем съедят.

:smile:
 
Верх