如何将我的一个程序做成服务程序?(79分)

  • 主题发起人 主题发起人 yjwnnit
  • 开始时间 开始时间
Y

yjwnnit

Unregistered / Unconfirmed
GUEST, unregistred user!
在WINDOWS 中以服务的形式自动运行。 但我的程序里边有FROM几个窗体, 里边是对本地SQL SERVER数据库及局域网中的SQL SERVER 数据库进行数据时实交换的。 必需要窗体让用户可以有时候登录进WINDOWS后进行一些手动操作。 如何实现呢?

我看到一些帖子说的,服务是不能放窗体的, 但是象SQL SEVER 本身也做成了服务,里边也有启动窗体在右下角。


请能实现的朋友,说说如何将一个现有的程序(有窗体的) 一步一步的如何转变成为服务?
 
涉及权限问题
可以试着在服务程序中启动你自己的程序
启动时设置一下权限值就行了
 
来自:Mike1234567890, 时间:2006-9-12 11:52:10, ID:3569997
涉及权限问题
可以试着在服务程序中启动你自己的程序
启动时设置一下权限值就行了

---------------------------------------------------------------------------------
请问,如何在服务程序中启动我自己的EXE程序? 你所说的权限问题是什么意思?
 
其实这样的情况很多, FORM窗体可以设置我NONE,不让它显示出来。程序启动时写注册表为自动启动的,这样只要用户运行一次后,以后每次开机都会自动启动它,而且这样和数据交换的东西,最好做多线程,多少时间检查,执行一次。
 
在计算机管理中,打开你的服务的属性,勾上允许与桌面交互就可以看到服务的窗口了(如果有的话)。

服务默认是用SYSTEM登录的,权限很大。我试过在我做的服务中调用CMD。它的权限也是SYSTEM。System Volume Information目录想怎么样改都可以,太可怕了。
 
来自:sunny3super, 时间:2006-9-12 13:15:24, ID:3570062
其实这样的情况很多, FORM窗体可以设置我NONE,不让它显示出来。程序启动时写注册表为自动启动的,这样只要用户运行一次后,以后每次开机都会自动启动它,而且这样和数据交换的东西,最好做多线程,多少时间检查,执行一次。

-----------------------------------------------------------------------
我想这样, 你能否说实际一点, 我得把窗体显示出来,因为里边有手动操作功能。而程序应用多线程,这个方面你不需要为我考虑了, 我已经做好了。 现就是如何将程序加入到
服务中去。 你说的修改一下注册表, 请问如何修改? 修改哪个参数?
 
来自:sunny3super, 时间:2006-9-12 13:15:24, ID:3570062
其实这样的情况很多, FORM窗体可以设置我NONE,不让它显示出来。程序启动时写注册表为自动启动的,这样只要用户运行一次后,以后每次开机都会自动启动它,而且这样和数据交换的东西,最好做多线程,多少时间检查,执行一次。

--------------------------------------------------------------------------
需要做成服务的目的就是, 当该服务器重启后,不用登录用户密码进入桌面也能运行该程序。 请给点好办法吧。 详细说明实现步骤好吗?
 
设置服务与桌面交互 可以拥有窗体
 
设置安装时安装为服务,这有现成的服务涵数,你只要确定服务名、显示名、执行文件路径就可以了。下面除了服务涵数,还有御载涵数,等等。
//unit Service: List Service and Operate Service;
unit winntService;

interface

uses WinSvc,Classes,Windows,Sysutils,WinSvcEx;

function ServiceGetList(
sMachine : string;
dwServiceType,
dwServiceState : Dword;
slServicesList : TStrings )
: boolean; //List service

function ServiceGetKeyName(
sMachine,
sServiceDispName : string ) : string; //convert displayname to keyname

function ServiceGetDisplayName(
sMachine,
sServiceKeyName : string ) : string; //conver keyname to displayname

function ServiceGetStatus(
sMachine,
sService : string ) : DWord; //Get service status

function ServiceRunning(
sMachine,
sService : string ) : boolean;

function ServiceStopped(
sMachine,
sService : string ) : boolean;

function ServiceStart(
sMachine,
sService : string ) : boolean;

function ServiceStop(
sMachine,
sService : string ) : boolean;

function InstallService(Target:String;ServiceName:String;Filename:String;Value: string):Boolean;

function DelService(ServiceName:String):Boolean;

implementation
{const
//
// Service Types
//
SERVICE_KERNEL_DRIVER = $00000001;
SERVICE_FILE_SYSTEM_DRIVER = $00000002;
SERVICE_ADAPTER = $00000004;
SERVICE_RECOGNIZER_DRIVER = $00000008;

SERVICE_DRIVER =
(SERVICE_KERNEL_DRIVER or
SERVICE_FILE_SYSTEM_DRIVER or
SERVICE_RECOGNIZER_DRIVER);

SERVICE_WIN32_OWN_PROCESS = $00000010;
SERVICE_WIN32_SHARE_PROCESS = $00000020;
SERVICE_WIN32 =
(SERVICE_WIN32_OWN_PROCESS or
SERVICE_WIN32_SHARE_PROCESS);

// SERVICE_INTERACTIVE_PROCESS = $00000100;

SERVICE_TYPE_ALL =
(SERVICE_WIN32 or
SERVICE_ADAPTER or
SERVICE_DRIVER or
SERVICE_INTERACTIVE_PROCESS); }



//-------------------------------------
// Get a list of services
//
// return TRUE if successful
//
// sMachine:
// machine name, ie: //SERVER
// empty = local machine
//
// dwServiceType
// SERVICE_WIN32,
// SERVICE_DRIVER or
// SERVICE_TYPE_ALL
//
// dwServiceState
// SERVICE_ACTIVE,
// SERVICE_INACTIVE or
// SERVICE_STATE_ALL
//
// slServicesList
// TStrings variable to storage
//
function ServiceGetList(
sMachine : string;
dwServiceType,
dwServiceState : Dword;
slServicesList : TStrings )
: boolean;
const
cnMaxServices = 4096;
type
TSvcA = array[0..cnMaxServices]
of TEnumServiceStatus;
PSvcA = ^TSvcA;

var
j : integer;
schm : SC_Handle;
nBytesNeeded,
nServices,
nResumeHandle : DWord;
ssa : PSvcA;
begin
Result := false;

schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_ALL_ACCESS);

if(schm > 0)then // if successful...
begin
nResumeHandle := 0;
New(ssa);

EnumServicesStatus(
schm,
dwServiceType,
dwServiceState,
ssa^[0],
SizeOf(ssa^),
nBytesNeeded,
nServices,
nResumeHandle );

for j := 0 to nServices-1 do
begin
slServicesList.
Add( StrPas(
ssa^[j].lpDisplayName ) );
end;
Result := true;
Dispose(ssa);
CloseServiceHandle(schm);
end;
end;


function ServiceGetKeyName(
sMachine,
sServiceDispName : string ) : string;
var
schm : SC_Handle;
nMaxNameLen : DWord; // max key name len
psServiceName : PChar; // temp. string
begin
Result := '';
nMaxNameLen := 255;

schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);
if(schm > 0)then // if successful...
begin
psServiceName :=
StrAlloc(nMaxNameLen+1);

if(nil <> psServiceName)then
begin
if(GetServiceKeyName(schm,PChar(sServiceDispName),psServiceName,nMaxNameLen ) )then
begin
psServiceName
[nMaxNameLen] := #0;
Result :=StrPas( psServiceName );
end;
StrDispose(psServiceName);
end;
CloseServiceHandle(schm);
end;
end;


function ServiceGetDisplayName(
sMachine,
sServiceKeyName : string ) : string;
var
schm : SC_Handle;
nMaxNameLen : DWord; // max display name len
psServiceName : PChar;
begin
Result := '';
nMaxNameLen := 255;
schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);
if(schm > 0)then // if successful...
begin
psServiceName :=
StrAlloc(nMaxNameLen+1);
if(nil <> psServiceName)then
begin
if( GetServiceDisplayName(schm,PChar(sServiceKeyName),psServiceName,nMaxNameLen ) )then
begin
psServiceName
[nMaxNameLen] := #0;
Result :=StrPas( psServiceName );
end;
StrDispose(psServiceName);
end;
CloseServiceHandle(schm);
end;
end;


//-------------------------------------
// get service status
//
// return status code if successful
// -1 if not
//
// return codes:
// SERVICE_STOPPED
// SERVICE_RUNNING
// SERVICE_PAUSED
//
// following return codes
// are used to indicate that
// the service is in the
// middle of getting to one
// of the above states:
// SERVICE_START_PENDING
// SERVICE_STOP_PENDING
// SERVICE_CONTINUE_PENDING
// SERVICE_PAUSE_PENDING
//
// sMachine:
// machine name, ie: //SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter
//
function ServiceGetStatus(sMachine,sService : string ) : DWord;
var
schm,schs : SC_Handle;
ss : TServiceStatus;
dwStat : DWord;
begin
dwStat := 0;
schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);
if(schm > 0)then // if successful...
begin

schs := OpenService(schm,PChar(sService),SERVICE_QUERY_STATUS);

if(schs > 0)then // if successful...
begin
if(QueryServiceStatus(schs,ss))then
begin
dwStat := ss.dwCurrentState;
end;
CloseServiceHandle(schs);
end;
CloseServiceHandle(schm);

Result := dwStat;
end
else Result := SERVICE_STOPPED;
end;


//-------------------------------------
// return TRUE if the specified
// service is running, defined by
// the status code SERVICE_RUNNING.
// return FALSE if the service
// is in any other state, including
// any pending states
//
function ServiceRunning(sMachine,sService : string ) : boolean;
begin
Result := SERVICE_RUNNING=ServiceGetStatus(sMachine, sService );
end;


//-------------------------------------
// return TRUE if the specified
// service was stopped, defined by
// the status code SERVICE_STOPPED.
//
function ServiceStopped(sMachine,sService : string ) : boolean;
begin
Result := SERVICE_STOPPED=ServiceGetStatus(sMachine, sService );
end;


function ServiceStart( sMachine,
sService : string ) : boolean;
var
schm,schs : SC_Handle;
ss : TServiceStatus;
psTemp : PChar;
dwChkP : DWord;
begin
ss.dwCurrentState := 0;
schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);
if(schm > 0)then // if successful...
begin
schs := OpenService(schm,PChar(sService),
SERVICE_START or
SERVICE_QUERY_STATUS);

if(schs > 0)then // if successful...
begin
psTemp := Nil;
if(StartService(schs,0,psTemp))then
begin
if(QueryServiceStatus(schs,ss))then
begin
while(SERVICE_RUNNING<>ss.dwCurrentState)do
begin
dwChkP := ss.dwCheckPoint;
Sleep(ss.dwWaitHint);
if(not QueryServiceStatus(schs,ss))then
begin
break;
end;
if(ss.dwCheckPoint <dwChkP)then
begin
break;
end;
end;
end;
end;
CloseServiceHandle(schs);
end;
CloseServiceHandle(schm);
end;
Result :=SERVICE_RUNNING=ss.dwCurrentState;
end;



function ServiceStop(
sMachine,
sService : string ) : boolean;
var
schm,schs : SC_Handle;
ss : TServiceStatus;
dwChkP : DWord;
begin
schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);
if(schm > 0)then // if successful...
begin
schs := OpenService(schm,PChar(sService),
SERVICE_STOP or
SERVICE_QUERY_STATUS);
if(schs > 0)then // if successful...
begin
if(ControlService(schs,SERVICE_CONTROL_STOP,ss))then
begin
if(QueryServiceStatus(schs,ss))then
begin
while(SERVICE_STOPPED<>ss.dwCurrentState)do
begin
dwChkP := ss.dwCheckPoint;
Sleep(ss.dwWaitHint);
if(not QueryServiceStatus(schs,ss))then
begin
break;
end;
if(ss.dwCheckPoint <dwChkP)then
begin
break;
end;
end;
end;
end;
CloseServiceHandle(schs);
end;
CloseServiceHandle(schm);
end;

Result :=SERVICE_STOPPED=ss.dwCurrentState;
end;



function InstallService(Target:String;ServiceName:String;Filename:String;Value: string):Boolean;
var
ss : TServiceStatus;
psTemp : PChar;
hSCM,hSCS:THandle;

srvdesc : PServiceDescription;
desc : string;
SrvType : DWord;
begin
psTemp := Nil;

SrvType := SERVICE_WIN32_OWN_PROCESS and SERVICE_INTERACTIVE_PROCESS;;

hSCM:=OpenSCManager('',nil,SC_MANAGER_ALL_ACCESS);
hSCS:=CreateService(hSCM, //句柄
Pchar(Target), //服务名称
Pchar(ServiceName), //显示服务名
SERVICE_ALL_ACCESS, //服务访问类型
SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS,//服务类型 SERVICE_WIN32_OWN_PROCESS and SERVICE_INTERACTIVE_PROCESS
SERVICE_AUTO_START, //自动启动服务
SERVICE_ERROR_IGNORE, //忽略错误
Pchar(Filename), //启动的文件名
nil,//name of load ordering group (载入组名) 'LocalSystem'
nil,//标签标识符
nil,//相关性数组名
nil,//帐户(当前)
nil);//密码(当前)


if Assigned(ChangeServiceConfig2) then
begin
// Service descriptions can't be longer than 1024!!!
desc := Copy(Value,1,1024);
GetMem(srvdesc,SizeOf(TServiceDescription));
GetMem(srvdesc^.lpDescription,Length(desc) + 1);
try
StrPCopy(srvdesc^.lpDescription, desc);

ChangeServiceConfig2(hSCS,SERVICE_CONFIG_DESCRIPTION,srvdesc);

finally
FreeMem(srvdesc^.lpDescription);
FreeMem(srvdesc);
end;
end;

{ if(StartService(hSCS,0,psTemp))then
begin
while QueryServiceStatus(hSCS,ss) do begin
if ss.dwCurrentState=SERVICE_START_PENDING then
Sleep(30)
else break;
if ss.dwCurrentState=SERVICE_RUNNING then begin
CloseServiceHandle(hSCS);
result :=True;
end else result :=False;
end;
end; }
end;

function DelService(ServiceName:String):Boolean;
var
sm: THandle;
sh: THandle;
ret: Integer;
begin
try
ret := 0;
sm := OpenSCManager('', nil, SC_MANAGER_ALL_ACCESS);
if sm <> 0 then
begin
sh := OpenService(sm, PChar(ServiceName), SERVICE_ALL_ACCESS);
if sh <> 0 then
begin
DeleteService(sh);
ret := 1;
CloseServiceHandle(sh);
end;
CloseServiceHandle(sm);
end;
if Ret > 0 then
result :=True
else
result :=False;
except
end;
end;

end.
 
我现在是这样 , 建了个服务,在服务CREATE事件中执行那个EXE文件。 然后把服务设置服务与桌面交互 就OK了。 只是不能够在退出该EXE程序时结束服务。 但是问题还是算解决了。 好了给大家加分了
 
多人接受答案了。
 
后退
顶部