首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

以SYSTEM权限运行的程序怎样可以显示界面?有代码解决方法

2012-03-08 
以SYSTEM权限运行的程序怎样可以显示界面?有代码program SvrDemousesWindows,WinSvc,winsockconstRegNam

以SYSTEM权限运行的程序怎样可以显示界面?有代码
program SvrDemo;

uses
  Windows,
  WinSvc,
  winsock;

const
  RegName = 'SvrDemo';

var
  szServiceName: pchar = 'SvrDemo';
  szFileName:pchar;
  ServiceTable: array [0..1] of TServiceTableEntry;
  Status: SERVICE_STATUS;
  StatusHandle: SERVICE_STATUS_HANDLE;
  Stopped: boolean;
  Paused: boolean;
  cmd :array[0..MAX_PATH] of char;


function InstallService(ServiceName, DisplayName, FileName: string): boolean;
var
  SCManager,Service: THandle;
  Args: pchar;
begin
  Result := False;
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then Exit;
  try
  Service := CreateService(SCManager, //句柄
  PChar(ServiceName), //服务名称
  PChar(DisplayName), //显示服务名
  SERVICE_ALL_ACCESS, //服务访问类型
  SERVICE_WIN32_OWN_PROCESS, //服务类型 or SERVICE_INTERACTIVE_PROCESS
  SERVICE_AUTO_START, //自动启动服务
  SERVICE_ERROR_IGNORE, //忽略错误
  PChar(FileName), //启动的文件名
  nil, //name of load ordering group (载入组名) 'LocalSystem'
  nil, //标签标识符
  nil, //相关性数组名
  nil, //帐户(当前)
  nil); //密码(当前)

  Args := nil;
  StartService(Service, 0, Args);
  CloseServiceHandle(Service);
  finally
  CloseServiceHandle(SCManager);
  end;
  Result := True;
end;

procedure UninstallService(ServiceName: string);
var
  SCManager,Service: THandle;
  ServiceStatus: SERVICE_STATUS;
begin
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then Exit;
  try
  Service := OpenService(SCManager, PChar(ServiceName), SERVICE_ALL_ACCESS);
  ControlService(Service, SERVICE_CONTROL_STOP, ServiceStatus);
  DeleteService(Service);
  CloseServiceHandle(Service);
  finally
  CloseServiceHandle(SCManager);
  end;
end;

procedure ServiceCtrlHandler(Control: dword); stdcall;
begin
  case Control of
  SERVICE_CONTROL_STOP:
  begin
  Stopped := True;
  Status.dwCurrentState := SERVICE_STOPPED;
  end;
  SERVICE_CONTROL_PAUSE:
  begin
  Paused := True;
  Status.dwcurrentstate := SERVICE_PAUSED;
  end;
  SERVICE_CONTROL_CONTINUE:
  begin
  Paused := False;
  Status.dwCurrentState := SERVICE_RUNNING;
  end;
  SERVICE_CONTROL_INTERROGATE: ;
  SERVICE_CONTROL_SHUTDOWN: Stopped := True;
  end;
  SetServiceStatus(StatusHandle, Status);
end;
 
procedure ServiceMain;
begin
{注意这里,虽然程序是运行成功,但看不见界面,
后来发现是因为程序是以SYSTEM权限运行造成的(也一定要用这个权限运行),
有什么方法可以使程序界面显示在当前用户桌面上?
有人说是消息处理不好,但不知应该怎样处理}
winexec(pchar('Project1.exe'),1);
  sleep(1500);
  ExitProcess(0);
end;

procedure ServiceCtrlDispatcher(dwArgc: dword; var lpszArgv: pchar); stdcall;
begin
  StatusHandle := RegisterServiceCtrlHandler(szServiceName, @ServiceCtrlHandler);
  if StatusHandle <> 0 then
  begin
  ZeroMemory(@Status, SizeOf(Status));
  Status.dwServiceType := SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS;


  Status.dwCurrentState:= SERVICE_START_PENDING;
  Status.dwControlsAccepted := SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE;
  Status.dwWaitHint := 1000;
  SetServiceStatus(StatusHandle, Status);
  Stopped := False;
  Paused := False;
  Status.dwCurrentState := SERVICE_RUNNING;
  SetServiceStatus(StatusHandle, Status);
  ServiceMain;
  end;
end;

procedure Main;
begin
  UninstallService(szServiceName);
  szFileName :=pchar(ParamStr(0));
  GetModuleFileName(hInstance,cmd,MAX_PATH);
  ServiceTable[0].lpServiceName := szServiceName;
  ServiceTable[0].lpServiceProc := @ServiceCtrlDispatcher;
  ServiceTable[1].lpServiceName := nil;
  ServiceTable[1].lpServiceProc := nil;
  StartServiceCtrlDispatcher(ServiceTable[0]);

 InstallService(szServiceName, szServiceName, szFileName);
 UninstallService(szServiceName);

end;

begin
  Main;
end.

[解决办法]
可以用服务程序+服务管理程序
[解决办法]
用ShellExecute试一下

[解决办法]
CreateProcessAsUser

[解决办法]
那你就安装的时候创建一个专用的用户,很多软件都这么做的(IIS就是典型)。

[解决办法]
WinSTA的问题吧~
Service用的和Desktop不是一个嘛

2个方法
1)用SYSTEM权限,可以替换EXE的TOKEN实现的,这需要驱动支持而已
一般替换为WinLOGON的TOKEN就可以,任何程序替换TOKEN,就马上换了权限的
2)指定服务程序所用之WINSTA为用户WINSTA

热点排行