我建立了一个Service Application,中间有一个Thread,在一定条件下,我需要它运行另一个外部的程序。
可以当我启动服务,外部程序并没有显示的运行,在任务管理器中可以看到,而且不能够终止。
请问这是为什么,要怎样才能够解决。
代码大概是这样子的:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;
type
T = class(TThread)
protected
procedure Execute; override;
end;
TService1 = class(TService)
procedure ServiceStart(Sender: TService; var Started: Boolean);
private
{ Private declarations }
tt: T;
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
Service1: TService1;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;
function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure T.Execute;
begin
while true do
begin
if fileexists('c:\start.txt') then
winexec('notepad.exe', SW_SHOWNORMAL); //运行一个程序,但看不到窗口,用ShellExecute也一样
sleep(1000);
end;
end;
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
tt := T.Create(false);
Started := True;
end;
end.
可以当我启动服务,外部程序并没有显示的运行,在任务管理器中可以看到,而且不能够终止。
请问这是为什么,要怎样才能够解决。
代码大概是这样子的:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;
type
T = class(TThread)
protected
procedure Execute; override;
end;
TService1 = class(TService)
procedure ServiceStart(Sender: TService; var Started: Boolean);
private
{ Private declarations }
tt: T;
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
Service1: TService1;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;
function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure T.Execute;
begin
while true do
begin
if fileexists('c:\start.txt') then
winexec('notepad.exe', SW_SHOWNORMAL); //运行一个程序,但看不到窗口,用ShellExecute也一样
sleep(1000);
end;
end;
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
tt := T.Create(false);
Started := True;
end;
end.
解决方案 »
- Delphi改错
- 请问如何设置 socket 阻塞或者非阻塞?
- 如何控制串口打印机实现打印等操作?
- 号召:大家赶快到Borland的Qualiti Central中建议把D2005的ActiveForm向导恢复出来!
- halfdream(哈欠)、jinjazz(人雅的标记--落寞刺客) 接分
- 请教各位高手 怎样屏蔽掉Memo控件的键盘事件
- 谁有vc6的免费下载地址?急用呀!
- 关于midas三层数据库服务器客户端互相传递文件的新问题,请高手指教,100分保证送
- 过节了,技术大放送10:用Label显示自己程序的版本。
- 怎样使得DBGrid更新
- installshield打包问题
- dbgrideh如何在里面输入数据?
否则系统会默认是服务桌面而不是系统桌面,运行的程序会在服务桌面显示出来,当前屏幕下自然看不到了
不过我不太了解
dwCreationFlags := NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE;
ZeroMemory(@si, sizeof(STARTUPINFO));
si.cb := sizeof(STARTUPINFO);
si.lpDesktop := 'winsta0\default';
ZeroMemory(@pi, sizeof(pi));
hProcess := OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid); if (not OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY
or TOKEN_DUPLICATE or TOKEN_ASSIGN_PRIMARY or TOKEN_ADJUST_SESSIONID
or TOKEN_READ or TOKEN_WRITE, hPToken)) then
begin
abcd := GetLastError();
err('Process token open Error: ' + inttostr(GetLastError()));
end; if (not LookupPrivilegeValue(nil, SE_DEBUG_NAME, tp.Privileges[0].Luid)) then
begin
err('Lookup Privilege value Error: ' + inttostr(GetLastError()));
end;
tp.PrivilegeCount := 1;
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, nil,
SecurityIdentification, TokenPrimary, hUserTokenDup);
dup := GetLastError(); // Adjust Token privilege SetTokenInformation(hUserTokenDup,
TokenSessionId, pointer(dwSessionId), sizeof(DWORD)); if (not AdjustTokenPrivileges(hUserTokenDup, FALSE, @tp, sizeof(TOKEN_PRIVILEGES),
nil, nil)) then
begin
abc := GetLastError();
err('Adjust Privilege value Error: ' + inttostr(GetLastError()));
end; if (GetLastError() = ERROR_NOT_ALL_ASSIGNED) then
begin
err('Token does not have the provilege');
end; lpEnv := nil; if (CreateEnvironmentBlock(lpEnv, hUserTokenDup, TRUE)) then
begin
dwCreationFlags := dwCreationFlags or CREATE_UNICODE_ENVIRONMENT;
end
else
lpEnv := nil; // Launch the process in the client's logon session. bResult := CreateProcessAsUser(
hUserTokenDup, // client's access token
'D:\panorama\panorama.exe', // file to execute
nil, // command line
nil, // pointer to process SECURITY_ATTRIBUTES
nil, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
dwCreationFlags, // creation flags
lpEnv, // pointer to new environment block
'D:\panorama', // name of current directory
si, // pointer to STARTUPINFO structure
pi // receives information about new process
); // End impersonation of client.
//GetLastError Shud be 0 iResultOfCreateProcessAsUser := GetLastError(); //Perform All the Close Handles tasks
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
CloseHandle(hPToken);
end;end.
var
hToken:THandle ;
pi:PROCESS_INFORMATION;
psid:TProcessInformation ;
si:STARTUPINFO ; begin
FillChar(si, Sizeof(STARTUPINFO), 0);
si.cb:= sizeof(STARTUPINFO);
si.lpDesktop:=PChar('winsta0\\default');
CreateProcessAsUser(
hToken,
'notepad.exe',
nil,
nil,
nil,
FALSE,
0,
nil,
nil,
si,
pi
)
end;
我是这样写的好像无效啊。。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,TLhelp32;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Function GetProcessIdFromName(_GetPID:String):String;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
hUserTokenDup:THandle ;
pi:PROCESS_INFORMATION;
si:STARTUPINFO ;
PID:DWORD;
begin
PID:=DWORD(GetProcessIdFromName('explorer.exe'));
OpenProcessToken(OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,FALSE,PID),TOKEN_EXECUTE,hUserTokenDup);
ZeroMemory(@si, sizeof(STARTUPINFO));
si.cb:= sizeof(STARTUPINFO);
si.lpDesktop:=PChar('winsta0\\default');
si.wShowWindow := SW_SHOWNORMAL;
// ZeroMemory(@pi, sizeof(pi));
CreateProcessAsUser(hUserTokenDup,'c:\q.exe', nil,nil,nil,FALSE, CREATE_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS,nil, nil, si, pi);end;Function TForm1.GetProcessIdFromName(_GetPID:String):String;
var
h:thandle;
f:boolean;
lppe:tprocessentry32;
begin
h := CreateToolhelp32Snapshot(TH32cs_SnapProcess, 0);
lppe.dwSize := sizeof(lppe);
f := Process32First(h, lppe); //lppe.szExeFile是进程的名字,自己挑选你要的
while integer(f) <> 0 do
begin
if lppe.szExeFile = _GetPID then
begin
Result:=(inttostr(lppe.th32ProcessID));
break;
end;
f := Process32Next(h,lppe);
end;
end;
end.
可以运行。但是q.exe还是打不开,不知道为什么,帮我看看谢谢