I Developed an Application in Delphi 7 that runs as a windows service. I need this service catch all logged on users (this service will be installed on WTS server too). I tried some codes I found in Web, but the service starts with system account, and the only thing that shows me as users is "System" or nothing.
我在Delphi 7中开发了一个作为Windows服务运行的应用程序。我需要这个服务捕获所有登录的用户(此服务也将安装在WTS服务器上)。我尝试了一些我在Web上找到的代码,但是服务从系统帐户开始,唯一让我看作用户的是“系统”或什么都没有。
I'm new at Delphi, so tanks for some help.
我是德尔福的新手,所以坦克可以提供一些帮助。
UPDATE:
Here is the actual code (very crazy) i'm using: I'm trying to run a MSDOS Command and get the return os command to Delphi. In Windows XP outside ActiveDirectory it works, but in Windows 7/8 inside ActiveDirectory show me nothing:
这是我正在使用的实际代码(非常疯狂):我正在尝试运行MSDOS命令并获取返回os命令到Delphi。在ActiveDirectory外部的Windows XP中它可以工作,但在Windows 7/8内部,ActiveDirectory中没有显示任何内容:
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
WorkDir: string;
Handle: Boolean;
CommandLine: string;
usuario: string;
begin
totalinfo:= TStringlist.Create;
try
//--------------
CommandLine:='WMIC COMPUTERSYSTEM GET USERNAME';
with SA do begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
try
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
WorkDir := 'C:\';
Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
usuario:=Buffer;
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
end;
Tanks.
1 个解决方案
#1
4
Your service can use the WTSEnumerateSessions()
and WTSQuerySessionInformation()
functions, eg:
您的服务可以使用WTSEnumerateSessions()和WTSQuerySessionInformation()函数,例如:
uses
..., Windows;
type
WTS_INFO_CLASS = (
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSSessionInfoEx,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
);
WTS_CONNECTSTATE_CLASS = (
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
);
PWTS_SESSION_INFO = ^WTS_SESSION_INFO;
WTS_SESSION_INFO = record
SessionId: DWORD;
pWinStationName: LPTSTR;
State: WTS_CONNECTSTATE_CLASS;
end;
const
WTS_CURRENT_SERVER_HANDLE: HANDLE = 0;
function WTSEnumerateSessions(hServer: THandle; Reserved: DWORD; Version: DWORD; var ppSessionInfo: PWTS_SESSION_INFO; var pCount: DWORD): BOOL; stdcall; external 'Wtsapi32.dll' name {$IFDEF UNICODE}'WTSEnumerateSessionsW'{$ELSE}'WTSEnumerateSessionsA'{$ENDIF};
function WTSQuerySessionInformation(hServer: THandle; SessionId: DWORD; WTSInfoClass: WTS_INFO_CLASS; var ppBuffer: LPTSTR; var pBytesReturned: DWORD): BOOL; stdcall; external 'Wtsapi32.dll' name {$IFDEF UNICODE}'WTSQuerySessionInformationW'{$ELSE}'WTSQuerySessionInformationA'{$ENDIF};
procedure WTSFreeMemory(pMemory: Pointer); stdcall; external 'Wtsapi32.dll';
var
Sessions, Session: PWTS_SESSION_INFO;
NumSessions, I, NumBytes: DWORD;
UserName: LPTSTR;
begin
if not WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, Sessions, NumSessions) then
RaiseLastOSError;
try
if NumSessions > 0 then
begin
Session := Sessions;
for I := 0 to NumSessions-1 do
begin
if Session.State = WTSActive then
begin
if WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, Session.SessionId, WTSUserName, UserName, NumBytes) then
begin
try
// use UserName as needed...
finally
WTSFreeMemory(UserName);
end;
end;
end;
Inc(Session);
end;
end;
finally
WTSFreeMemory(Sessions);
end;
end;
#1
4
Your service can use the WTSEnumerateSessions()
and WTSQuerySessionInformation()
functions, eg:
您的服务可以使用WTSEnumerateSessions()和WTSQuerySessionInformation()函数,例如:
uses
..., Windows;
type
WTS_INFO_CLASS = (
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSSessionInfoEx,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
);
WTS_CONNECTSTATE_CLASS = (
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
);
PWTS_SESSION_INFO = ^WTS_SESSION_INFO;
WTS_SESSION_INFO = record
SessionId: DWORD;
pWinStationName: LPTSTR;
State: WTS_CONNECTSTATE_CLASS;
end;
const
WTS_CURRENT_SERVER_HANDLE: HANDLE = 0;
function WTSEnumerateSessions(hServer: THandle; Reserved: DWORD; Version: DWORD; var ppSessionInfo: PWTS_SESSION_INFO; var pCount: DWORD): BOOL; stdcall; external 'Wtsapi32.dll' name {$IFDEF UNICODE}'WTSEnumerateSessionsW'{$ELSE}'WTSEnumerateSessionsA'{$ENDIF};
function WTSQuerySessionInformation(hServer: THandle; SessionId: DWORD; WTSInfoClass: WTS_INFO_CLASS; var ppBuffer: LPTSTR; var pBytesReturned: DWORD): BOOL; stdcall; external 'Wtsapi32.dll' name {$IFDEF UNICODE}'WTSQuerySessionInformationW'{$ELSE}'WTSQuerySessionInformationA'{$ENDIF};
procedure WTSFreeMemory(pMemory: Pointer); stdcall; external 'Wtsapi32.dll';
var
Sessions, Session: PWTS_SESSION_INFO;
NumSessions, I, NumBytes: DWORD;
UserName: LPTSTR;
begin
if not WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, Sessions, NumSessions) then
RaiseLastOSError;
try
if NumSessions > 0 then
begin
Session := Sessions;
for I := 0 to NumSessions-1 do
begin
if Session.State = WTSActive then
begin
if WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, Session.SessionId, WTSUserName, UserName, NumBytes) then
begin
try
// use UserName as needed...
finally
WTSFreeMemory(UserName);
end;
end;
end;
Inc(Session);
end;
end;
finally
WTSFreeMemory(Sessions);
end;
end;