Что нового

[Автоматизация] Функция Список Пользователей На Сервере()

Renz

Осваивающий
Сообщения
63
Репутация
37
Функция должна возвращать список пользователей на сервере(и не только) - аналог списка пользователей в диспетчере задач.
Но пока возвращает непайму что. :wacko: Может кто оценит своим трезвым взглядом? :smile:
Два дня на свадьбе не прошли даром :beer:
Код:
Код:
#include "WinAPI.au3"
Global Const $tag_SESSION_INFO = "dword SessionId;dword pWinStationName;dword WTS_CONNECTSTATE_CLASS"
Global Const $tag_WTSClientProtocolType      = 16
Global Const $tag_WTSUserName = 5
;~ ************************************************
;~ BOOL WTSEnumerateSessions (
;~   __in HANDLE hServer,
;~   __in DWORD Reserved,
;~   __in DWORD версии,
;~   __out PWTS_SESSION_INFO * ppSessionInfo,
;~   __out DWORD * pCount
;~ );
;~ ------------------------------------------------
;~ typedef struct _WTS_SESSION_INFO {
;~   DWORD                  SessionId;
;~   LPTSTR                 pWinStationName;
;~   WTS_CONNECTSTATE_CLASS State;
;~ } WTS_SESSION_INFO, *PWTS_SESSION_INFO;
;~ ************************************************
Func __WTSEnumerateSessions()
	Local $hServer = _WTSOpenServer ()
	Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSEnumerateSessions", "HANDLE", $hServer, "dword", 0, "dword", 1, _
		"ptr*", 0, "dword*", 0)
	If @error Then Return MsgBox(0,"Error",@error)
	 Local $iCount = $aResult[5]
	Local $aInfo[$iCount + 1][3]	
	$aInfo[0][0] = $iCount
	If $aResult[0] <> 0 Then
		Local $pInfo = $aResult[4]
		Local $tInfo
		For $iI = 1 To $iCount-1
			$tInfo = DllStructCreate($tag_SESSION_INFO, $pInfo)
			if @error Then
				MsgBox(0,"","Error in DllStructCreate " & @error);
				exit
			endif
			$aInfo[$iI][0] = DllStructGetData($tInfo, "SessionId")
			$aInfo[$iI][1] = _WinAPI_WideCharToMultiByte(DllStructGetData($tInfo, "pWinStationName"))
			$aInfo[$iI][2] = DllStructGetData($tInfo, "WTS_CONNECTSTATE_CLASS")
			$pInfo += DllStructGetSize($tInfo)
			MsgBox(0,"SESSION_INFO",$aInfo[$iI][0]&"|"&$aInfo[$iI][1]&"|"&$aInfo[$iI][2])
		Next
	EndIf
	__WTSFreeMemory($aResult[4])
	_WTSCloseServer ($hServer)
	Return SetExtended($aResult[0], $aInfo)
EndFunc ;==> _WTSEnumerateSessions

Func _WTSOpenServer ($sServer = "")
	If $sServer = "" Then $sServer = @ComputerName
	Local $aResult = DllCall("Wtsapi32.dll", "HANDLE", "WTSOpenServerA", "str", $sServer)
 	If @error Then Return SetError(@error, @extended, 0)
	Return $aResult[0]
EndFunc  ;==>_WTSOpenServer

Func _WTSCloseServer ($hServer)
	Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSCloseServer", "HANDLE", $hServer)
	If @error Then Return MsgBox(0,"Error",@error)
EndFunc  ;==>_WTSCloseServer

Func __WTSFreeMemory($pBuffer)
	Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSFreeMemory", "ptr", $pBuffer)
	If @error Then Return SetError(@error, @extended, False)
	Return $aResult[0]
EndFunc   ;==>__WTSFreeMemory

;~ BOOL WTSQuerySessionInformation(
;~   __in   HANDLE hServer,
;~   __in   DWORD SessionId,
;~   __in   WTS_INFO_CLASS WTSInfoClass,
;~   __out  LPTSTR *ppBuffer,
;~   __out  DWORD *pBytesReturned
;~ );
Func _WTSQuerySessionInformation($aInfo)
	Local $hServer = _WTSOpenServer ()
	Local $iCount = $aInfo[0][0]
	Local $aInfoSes[$iCount][2]
	$aInfoSes[0][0] = $iCount
	For $iI =1 To $iCount
		$sSessionId = $aInfo[$iI][0]  
		Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "HANDLE", $hServer, "dword", $sSessionId, _
		"int", $tag_WTSUserName, "dword*", 0, "dword*", 0 )
		If @error Then Return MsgBox(0,"Error",@error)
		$aInfoSes[$iI][0] = $aResult[4]
		MsgBox(0,"Name",$aResult[4])
		Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "HANDLE", $hServer, "dword", $sSessionId, _
		"int", $tag_WTSClientProtocolType, "dword*", 0, "dword*", 0 )
		If @error Then Return MsgBox(0,"Error",@error)
		$aInfoSes[$iI][1] = $aResult[4]
		MsgBox(0,"ClientProtocol",$aResult[4])
	Next
	_WTSCloseServer ($hServer)
	Return SetExtended($aResult[0], $aInfoSes)
EndFunc
_WTSQuerySessionInformation(__WTSEnumerateSessions())
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Если Win 2003 Server - помогу.
Список каких пользоателей?
Активных?
Или всех, зарегестрированных?
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Т.е. те пользователи, которые в настоящий момент активны (например, мы их
видим в Диспетчере служб терминалов) и видим мы их еще в Диспетчере задач.
Что ж., мог бы и сам написать. Просто прочтешь справку по командной строке + синтаксис. А зная как написать батник, то и Autoit будет по-зубам.
 
Автор
Renz

Renz

Осваивающий
Сообщения
63
Репутация
37
Yuriy спс канешн но мне нужна реальная помощь: а если точнее отправка и получение значений при работе с длл в автоит и преобразование типов данных. Код: то смотрел?
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Извини. А где код7


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

Renz
А тебе, что, жалко, рассказать что тебе надо.
 
Автор
Renz

Renz

Осваивающий
Сообщения
63
Репутация
37
Извини. А где код7
Хм а кнопка "Подробнее" не робить?
Код:
#include "WinAPI.au3"
Global Const $tag_SESSION_INFO = "dword SessionId;dword pWinStationName;dword WTS_CONNECTSTATE_CLASS"
Global Const $tag_WTSClientProtocolType      = 16
Global Const $tag_WTSUserName = 5
;~ ************************************************
;~ BOOL WTSEnumerateSessions (
;~   __in HANDLE hServer,
;~   __in DWORD Reserved,
;~   __in DWORD версии,
;~   __out PWTS_SESSION_INFO * ppSessionInfo,
;~   __out DWORD * pCount
;~ );
;~ ------------------------------------------------
;~ typedef struct _WTS_SESSION_INFO {
;~   DWORD                  SessionId;
;~   LPTSTR                 pWinStationName;
;~   WTS_CONNECTSTATE_CLASS State;
;~ } WTS_SESSION_INFO, *PWTS_SESSION_INFO;
;~ ************************************************
Func __WTSEnumerateSessions()
	Local $hServer = _WTSOpenServer ()
	Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSEnumerateSessions", "HANDLE", $hServer, "dword", 0, "dword", 1, _
		"ptr*", 0, "dword*", 0)
	If @error Then Return MsgBox(0,"Error",@error)
	 Local $iCount = $aResult[5]
	Local $aInfo[$iCount + 1][3]	
	$aInfo[0][0] = $iCount
	If $aResult[0] <> 0 Then
		Local $pInfo = $aResult[4]
		Local $tInfo
		For $iI = 1 To $iCount-1
			$tInfo = DllStructCreate($tag_SESSION_INFO, $pInfo)
			if @error Then
				MsgBox(0,"","Error in DllStructCreate " & @error);
				exit
			endif
			$aInfo[$iI][0] = DllStructGetData($tInfo, "SessionId")
			$aInfo[$iI][1] = _WinAPI_WideCharToMultiByte(DllStructGetData($tInfo, "pWinStationName"))
			$aInfo[$iI][2] = DllStructGetData($tInfo, "WTS_CONNECTSTATE_CLASS")
			$pInfo += DllStructGetSize($tInfo)
			MsgBox(0,"SESSION_INFO",$aInfo[$iI][0]&"|"&$aInfo[$iI][1]&"|"&$aInfo[$iI][2])
		Next
	EndIf
	__WTSFreeMemory($aResult[4])
	_WTSCloseServer ($hServer)
	Return SetExtended($aResult[0], $aInfo)
EndFunc ;==> _WTSEnumerateSessions

Func _WTSOpenServer ($sServer = "")
	If $sServer = "" Then $sServer = @ComputerName
	Local $aResult = DllCall("Wtsapi32.dll", "HANDLE", "WTSOpenServerA", "str", $sServer)
 	If @error Then Return SetError(@error, @extended, 0)
	Return $aResult[0]
EndFunc  ;==>_WTSOpenServer

Func _WTSCloseServer ($hServer)
	Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSCloseServer", "HANDLE", $hServer)
	If @error Then Return MsgBox(0,"Error",@error)
EndFunc  ;==>_WTSCloseServer

Func __WTSFreeMemory($pBuffer)
	Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSFreeMemory", "ptr", $pBuffer)
	If @error Then Return SetError(@error, @extended, False)
	Return $aResult[0]
EndFunc   ;==>__WTSFreeMemory

;~ BOOL WTSQuerySessionInformation(
;~   __in   HANDLE hServer,
;~   __in   DWORD SessionId,
;~   __in   WTS_INFO_CLASS WTSInfoClass,
;~   __out  LPTSTR *ppBuffer,
;~   __out  DWORD *pBytesReturned
;~ );
Func _WTSQuerySessionInformation($aInfo)
	Local $hServer = _WTSOpenServer ()
	Local $iCount = $aInfo[0][0]
	Local $aInfoSes[$iCount+1][2]
	$aInfoSes[0][0] = $iCount
	For $iI =1 To $iCount
		$sSessionId = $aInfo[$iI][0]  
		Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "HANDLE", $hServer, "dword", $sSessionId, _
		"int", $tag_WTSUserName, "dword*", 0, "dword*", 0 )
		If @error Then Return MsgBox(0,"Error",@error)
		$aInfoSes[$iI][0] = $aResult[4]
		MsgBox(0,"Name",$aResult[4])
		Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "HANDLE", $hServer, "dword", $sSessionId, _
		"int", $tag_WTSClientProtocolType, "dword*", 0, "dword*", 0 )
		If @error Then Return MsgBox(0,"Error",@error)
		$aInfoSes[$iI][1] = $aResult[4]
		MsgBox(0,"ProtocolType",$aResult[4])
	Next
	_WTSCloseServer ($hServer)
	Return SetExtended($aResult[0], $aInfoSes)
EndFunc
_WTSQuerySessionInformation(__WTSEnumerateSessions())

А тебе, что, жалко, рассказать что тебе надо.
Нет. Если есть ответ можно было и команду привести для примера ;)
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Я имел в виду другое.
Твой код мне очень долго разбирать (там нет пояснений)
Спроси ты примерно так:
Мне надо, что бы в Win 2003 Server:
- хочу видеть список активных пользователей сервера
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Вот справку почитал.
Кусок справки:
Query user
Отображает сведения о пользовательских сеансах на сервере терминалов.

Примечания
Эта команда может использоваться для выяснения того, вошел ли определенный пользователь на заданный сервер терминалов. С помощью команды query user можно получить следующие сведения:
имя пользователя;
имя сеанса на сервере терминалов;
код сеанса;
состояние сеанса (активно или отключено);
время простоя сеанса (количество минут, прошедшее с последнего нажатия клавиши клавиатуры или движения указателя мыши);
дату и время входа пользователя.

Примеры
Чтобы отобразить сведения о всех пользователях, которые вошли в систему, введите:
query user
Чтобы отобразить сведения о пользователе USER1 на сервере SERVER1, введите:
query user USER1 /server:SERVER1

Query session
Отображает сведения о сеансах на сервере терминалов. Этот список включает не только сведения об активных сеансах, но и о других сеансах, запущенных на сервере.
Дальше продолжать не буду.
 
Автор
Renz

Renz

Осваивающий
Сообщения
63
Репутация
37
Усложню задачу : Без использования командной строки результат в массиве в AutoIt
Интересно с помощью WMI запроса есть возможность? :whistle:
 

VladUs

Скриптер
Сообщения
621
Репутация
181
Вам необходим список клиентов подключенных только в терминальном режиме ?
Или еще и пользователи подключившиеся и к вашим общим ресурсам.
Скрипт ниже, выводит список пользователей, подключившихся к Вам с других компьютеров, к Вашим общим ресурсам (допустим к общей папке).

Код:
$strComputer = "." 
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") 
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_ServerConnection") 
For $objItem in $colItems 
    ConsoleWrite ("=================================================" & @CRLF)
    ConsoleWrite ("ComputerName: " & $objItem.ComputerName & @CRLF)
    ConsoleWrite ("UserName: " & $objItem.UserName & @CRLF)
    ConsoleWrite ("ShareName: " & $objItem.ShareName & @CRLF)
    
Next
 
Автор
Renz

Renz

Осваивающий
Сообщения
63
Репутация
37
Мне нужен:
[box title=1.]Аналог консольной команды Query user

Разобрал regapi.dll которую использует эта команда. по Функции RegQueryUtilityCommandList() нет вообще никакой справки. Нарыл только:

Код:
int __fastcall RegQueryUtilityCommandList(int,int,LPCWSTR lpSubKey,int)
public _RegQueryUtilityCommandList@8

Входные данные можно еще подобрать, но вот с Return ... :scratch: :wacko:[/box]

или

[box title=2.]Аналог таблицы в закладке Пользователи Диспетчера задач

С диспетчером тут проще, документация по функциям Wtsapi32.dll есть в MSDN.
[/box]

Кто-нибудь посмотрит мой код ? Я думаю он проще чем этот :smile:
Одним словом: Нид спец по Сишнику


01010101001011110010101010100111101010101011001101111110101010101011001010101011010101010101010101010101010101010101010110101010111111111000000010101010110101000101101011111110000000001111110101001010100101011101011110000110101010010101010101010101010100011

Ответы Типа:
А диспетчер задач это что?
У тебя флаг в MsgBox не тот.
Код:
If @error Then Return MsgBox(0,"Error",@error)
- А может вот из-за этого?
Ты че букавы "GOOGLE" не знаешь?
Как ответ не принимаются! Заранее Спс тому кто хотя бы посмотрит
Func _WTSOpenServer () :smile:
 

VladUs

Скриптер
Сообщения
621
Репутация
181
Renz [?]
Функция должна возвращать список пользователей на сервере(и не только) - аналог списка пользователей в диспетчере задач.

Код:
Global $Bufer
For $s = 0 To 100
$DllFunc = DllCall("Wtsapi32.dll", "Bool","WTSQuerySessionInformation","Dword",0 ,"Dword",$s,"Dword",5, "str*", $Bufer, "Dword*",1024)

For $i = 0 To UBound($DllFunc) - 1
 If StringIsAlpha ( $DllFunc[$i] )  Then
  ConsoleWrite($DllFunc[$i] & @CRLF)
 EndIf
Next

Next
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
VladUs,
Может так?
Код:
Global $sBufer, $iS = 0
Global Const $WTSUserName = 5;*
Global Const $WTS_CURRENT_SERVER_HANDLE = 0
While 1
	$aDllFunc = DllCall('Wtsapi32.dll', 'Bool', 'WTSQuerySessionInformation', 'HANDLE', $WTS_CURRENT_SERVER_HANDLE, 'Dword', $iS, 'Dword', $WTSUserName, 'str*', $sBufer, 'Dword*', 1024)
	If @error Or Not $aDllFunc[0] Then ExitLoop
	$iS += 1
	ConsoleWrite($aDllFunc[4] & @CR)
WEnd
;http://msdn.microsoft.com/en-us/library/aa383838(VS.85).aspx
;*http://msdn.microsoft.com/en-us/library/aa383861(v=VS.85).aspx
 

VladUs

Скриптер
Сообщения
621
Репутация
181
madmasles [?]
Да.. так лучше. Хотя по-правельному второй параметр этой функции должен заполнятся результатом возврата функции WTSEnumerateSessions()(так написано в MSDN) , а не указываться через счетчик. Но я не стал по этому поводу замарачиваться...
Мне Ваш вариант больше нравится.
 
Автор
Renz

Renz

Осваивающий
Сообщения
63
Репутация
37
Спс всем кто откликнулся :beer: Ларчик то просто открывался.
А я то наворотил. Хотел как правильно, а получилось как всегда :smile:

Долго не мог зайти на комп: чипсет ерундит. Переодически приходится жарить (уже второй раз) Заснял сиё действо ;D


Еще раз спасибо. Решено!



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

А этим WTSFreeMemory буфер чистить надо ?
 

VladUs

Скриптер
Сообщения
621
Репутация
181
Кстати, с помощью библиотеки WTSApi32.dll, удается вернуть имена всех учетных записей от лица которых запущены процессы. Раньше, для этого, мне приходилось использовать WMI.
Может кому - нибудь пригодится :

Код:
#Include <Security.au3>

$list = ProcessList()
For $i = 1 to $list[0][0]
  ConsoleWrite($list[$i][0] &" : "&  _GetProcessUser($list[$i][1]) & @CRLF)
Next

Func _GetProcessUser($PID)

$WTS_PROCESS_INFO= "DWORD SessionId; DWORD ProcessId; PTR pProcessName; PTR pUserSid"
$aDllRet=DllCall("WTSApi32.dll", "bool", "WTSEnumerateProcesses", "Dword", 0, "Dword", 0, _ 
                        "Dword", 1, "ptr*", DllStructGetPtr($WTS_PROCESS_INFO), "Dword*", 0)
Local $mem, $aProc[$aDllRet[5]][4]

For $i=0 To $aDllRet[5]-1
     $mem=DllStructCreate($WTS_PROCESS_INFO, $aDllRet[4]+($i*DllStructGetSize($mem)))
     $aProc[$i][1]=DllStructGetData($mem, "ProcessId")
     $aSid = _Security__LookupAccountSid(DllStructGetData($mem, "pUserSid"))
     If IsArray($aSid) Then $aProc[$i][3] = $aSid[0]
Next
 
For $i=0 to UBound($aProc) - 1
     if $aProc[$i][1] = $PID Then
       Return $aProc[$i][3]
     EndIf
Next
 
DllCall("WTSApi32.dll", "int", "WTSFreeMemory", "int", $aDllRet[4])
EndFunc
 
Верх