留给编程高手的问题

一个程序如何才能做到真正的后台程序?
如若把一个普通的电脑应用程序加工成为后台运行,
要哪些步骤?要点是什么?

如果你是要想如何做windows服务程序的话,可以使用windows Services API族,具体步骤如下,首先连接服务控制管理数据库使用OpenSCManager函数,然后调用CreateService函数创建服务,成功后使用RegisterServiceCtrlHandler函数注册控制处理例程,然后通过SetServiceStatus函数设置服务状态,这个时候就可以进入你的主程序进行处理了,当然了这个步骤是将注册服务和处理事务都在一个程序内,如果分开的话就需要使用RegisterServiceProcess函数进行注册了。
我以前做过一个通用的注册服务程序,你只需将自己处理函数放在我程序指定的位置就行了。下面贴出代码,但是这个地方自动将空格置顶,如果你觉得看的不舒服,可以访问http://www.wyos.net获得代码或者直接mail我wy_lslrt@yahoo.com.cn,我给你发过去。
需要补充一下,为何要有一个MsgBox()函数,因为在windows的服务程序中是没有GUI环境的如果需要使用GUI必须手动的打开窗口站,才可以使用GUI。
===================Service.h=====================
#define WYCONST_SLEEPTIME 4000
#define WYCONST_FILEPATHSIZE 1024
#define WYCONST_MSGBOX_ERROR 65535
#define WYCONST_SERVICE_NAME "NTMService"

SERVICE_STATUS WY_SvcStatus;
SERVICE_STATUS_HANDLE WY_hSvcStatusHandle;
TCHAR WY_szBinpath[WYCONST_FILEPATHSIZE];
DWORD WY_dwCurState; //服务进程当前状态

/*-----------------ServiceMain()----------------------*/
/*
服务入口函数
*/
VOID WINAPI ServiceMain(DWORD WY_dwArgc, LPTSTR * WY_lpszArgv);

/*-----------------ServiceContro()l--------------------*/
/*
服务控制响应函数
*/
VOID WINAPI ServiceControl(DWORD WY_dwCtrlCode);

/*-----------------IsServiceSetup()-------------------*/
/*
判断服务是否已经安装函数
return value:
FALSE 没有安装
TRUE 已经安装
*/
BOOL IsServiceSetup();

/*----------------IsServiceRun()-------------------*/
/*
判断服务是否已经运行
return value:
FALSE 没有运行
TRUE 已经运行
*/
BOOL IsServiceRun();

/*----------------SetupService()---------------------*/
/*
安装服务函数
return value:
FALSE 安装失败
TRUE 安装成功
*/
BOOL SetupService();

/*----------------RunService()----------------------*/
/*
运行服务
此函数是在安装服务后调用
return value:
FALSE 服务运行失败
TRUE 服务成功运行
*/
BOOL RunService(SC_HANDLE WY_hSvcHandler);

/*-----------------MsgBox()------------------------*/
/*
显示一个对话框
此函数是在服务程序中显示一个对话框
parameter:
LPCTSTR WY_lpszText 要显示的信息
LPCTSTR WY_lpszTitle 要显示的对话框的标题
UINT WY_uType 要显示的对话框类型
类型值查阅MSDN的MessageBox的uType的值
return value:

如果成功返回,值是下面的一种
IDABORT Abort 按钮被按下.
IDCANCEL Cancel 按钮被按下.
IDCONTINUE Continue 按钮被按下.
IDIGNORE Ignore 按钮被按下.
IDNO No 按钮被按下.
IDOK OK 按钮被按下.
IDRETRY Retry 按钮被按下.
IDTRYAGAIN Try 按钮被按下.
IDYES Yes 按钮被按下.
WYCONST_MSGBOX_ERROR 显示对话框失败.
*/
int MsgBox(LPCTSTR WY_lpszText,LPCTSTR WY_lpszTitle,UINT WY_uType);
=================Service.c======================
/*
在ServiceMain 中注释"请在这里插入处理函数"处放入处理函数
*/
#include <TCHAR.h>
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <winsvc.h>
#include <process.h>
#include "service.h"

void main()
{
//定义服务入口结构
SERVICE_TABLE_ENTRY WY_ServiceEntry[2];
DWORD WY_dwErrCode;
DWORD WY_dwRetValue;
char WY_szErrString[256];

//先获得当前服务程序的路径
WY_dwRetValue = GetModuleFileName(NULL,WY_szBinpath,WYCONST_FILEPATHSIZE);
if(!WY_dwRetValue)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"GetModuleFileName Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return;
}
OutputDebugString(WY_szBinpath);
//下面if else 是判断服务是否已经安装
//如果已经安装则进入服务入口函数
//否则进行安装服务
if(IsServiceSetup())
{
OutputDebugString("Service have setuped");

if(!IsServiceRun())
{
WY_ServiceEntry[0].lpServiceName = WYCONST_SERVICE_NAME;
WY_ServiceEntry[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

WY_ServiceEntry[1].lpServiceName = NULL;
WY_ServiceEntry[1].lpServiceName = NULL;

//启动服务的控制分配机制线程

if(!StartServiceCtrlDispatcher(WY_ServiceEntry))
{
WY_dwErrCode = GetLastError();
if(WY_dwErrCode == ERROR_INVALID_DATA)
{
OutputDebugString((LPCTSTR)"无效的服务入口结构");
return;
}
if(WY_dwErrCode == ERROR_SERVICE_ALREADY_RUNNING)
{
OutputDebugString((LPCTSTR)"服务已经运行");
return;
}
OutputDebugString((LPCTSTR)"启动服务入口函数未知错误");
return;
}
}
else
{
OutputDebugString((LPCTSTR)"服务已经运行");
return;
}
}
else
{ //安装服务
OutputDebugString("Not find Service");
if(!SetupService())
{
OutputDebugString((LPCTSTR)"安装服务失败");
return;
}
}

}
/*---------------服务进程必须提供的函数--------------------*/
VOID WINAPI ServiceMain(DWORD WY_dwArgc,LPTSTR *WY_lpszArgv)
{
//初始化服务状态
OutputDebugString((LPCTSTR)"初始化服务状态");
WY_SvcStatus.dwServiceType = SERVICE_WIN32;
WY_SvcStatus.dwCurrentState = SERVICE_START_PENDING;
WY_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
WY_SvcStatus.dwWin32ExitCode = NO_ERROR;
WY_SvcStatus.dwServiceSpecificExitCode = NO_ERROR;
WY_SvcStatus.dwCheckPoint = 0;
WY_SvcStatus.dwWaitHint = 0;
//注册控制函数
OutputDebugString((LPCTSTR)"注册控制函数");
WY_hSvcStatusHandle = RegisterServiceCtrlHandler(WYCONST_SERVICE_NAME,ServiceControl);
if(WY_hSvcStatusHandle == ERROR_INVALID_NAME)
{
OutputDebugString((LPCTSTR)"无效的服务名称");
return;
}
if(WY_hSvcStatusHandle == ERROR_SERVICE_DOES_NOT_EXIST)
{
OutputDebugString((LPCTSTR)"未找到指定服务");
return;
}
//成功注册
WY_SvcStatus.dwCurrentState = SERVICE_RUNNING;
//设置服务进程状态
OutputDebugString((LPCTSTR)"设置服务进程状态");
SetServiceStatus(WY_hSvcStatusHandle,&WY_SvcStatus);
WY_dwCurState = SERVICE_RUNNING;

//
//请在这里加入处理函数

while(WY_SvcStatus.dwCurrentState == SERVICE_RUNNING)
{
OutputDebugString((LPCTSTR)"在这里加入你的处理代码");
// MsgBox("test",WYCONST_SERVICE_NAME,0);

Sleep(WYCONST_SLEEPTIME);
}

return;
}

VOID WINAPI ServiceControl(DWORD WY_dwCtrlCode)
{
OutputDebugString((LPCTSTR)"接受控制");
switch(WY_dwCtrlCode)
{
case SERVICE_CONTROL_STOP:
OutputDebugString((LPCTSTR)"服务退出");

WY_SvcStatus.dwCurrentState = SERVICE_STOPPED;
WY_SvcStatus.dwWin32ExitCode = NO_ERROR;

SetServiceStatus(WY_hSvcStatusHandle,&WY_SvcStatus);
WY_dwCurState = SERVICE_STOPPED;
return;
case SERVICE_CONTROL_SHUTDOWN:
OutputDebugString((LPCTSTR)"系统关机");

WY_SvcStatus.dwCurrentState = SERVICE_STOPPED;
WY_SvcStatus.dwWin32ExitCode = NO_ERROR;

SetServiceStatus(WY_hSvcStatusHandle,&WY_SvcStatus);
WY_dwCurState = SERVICE_STOPPED;
return;
default:

break;

}
SetServiceStatus(WY_hSvcStatusHandle,&WY_SvcStatus);
}
/*---------------------------服务运行前的配置函数--------------------*/
BOOL IsServiceSetup()
{
SC_HANDLE WY_hSCHandle;
DWORD WY_dwErrCode;
DWORD WY_dwBufferNeeded = 0;
DWORD WY_dwEntriesNum = 0;
DWORD WY_dwNextEntry = 0;
DWORD WY_i;
char WY_szErrString[256];
BOOL WY_isSetup = FALSE;
ENUM_SERVICE_STATUS WY_essService,*WY_pessService;

//打开服务控制管理数据库
WY_hSCHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(!WY_hSCHandle)
{
WY_dwErrCode = GetLastError();
if(WY_dwErrCode == ERROR_ACCESS_DENIED)
{
OutputDebugString((LPCTSTR)"请求被拒绝");
exit(0);
}
if(WY_dwErrCode == ERROR_DATABASE_DOES_NOT_EXIST)
{
OutputDebugString((LPCTSTR)"服务程序数据库未找到");
exit(0);
}
if(WY_dwErrCode == ERROR_INVALID_PARAMETER)
{
OutputDebugString((LPCTSTR)"无效的参数");
exit(0);
}
OutputDebugString((LPCTSTR)"OpenSCManager 未知错误");
exit(0);
}
//成功打开服务控制管理数据库,枚举服务
//首先获得需要多大的缓存空间
if(!EnumServicesStatus(WY_hSCHandle,SERVICE_WIN32,SERVICE_STATE_ALL,&WY_essService,sizeof(ENUM_SERVICE_STATUS),
&WY_dwBufferNeeded,&WY_dwEntriesNum,&WY_dwNextEntry))
{
WY_dwErrCode = GetLastError();
if(WY_dwErrCode == ERROR_MORE_DATA) //获得了需要的缓存大小,重新获得服务数据
{
WY_dwBufferNeeded += sizeof(ENUM_SERVICE_STATUS);
WY_pessService = (LPENUM_SERVICE_STATUS)malloc(WY_dwBufferNeeded);

if(!EnumServicesStatus(WY_hSCHandle,SERVICE_WIN32,SERVICE_STATE_ALL,WY_pessService,WY_dwBufferNeeded,
&WY_dwBufferNeeded,&WY_dwEntriesNum,&WY_dwNextEntry))
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"EnumServiceStatus Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
exit(0);
}
//开始枚举服务
for(WY_i = 0;WY_i<WY_dwEntriesNum;WY_i++)
{
WY_dwErrCode = (DWORD)_tcscmp(WY_pessService[WY_i].lpServiceName,WYCONST_SERVICE_NAME);
if(WY_dwErrCode == 0) //找到安装的服务
{
WY_isSetup = TRUE;
WY_dwCurState = WY_pessService[WY_i].ServiceStatus.dwCurrentState;
break;
}
}

}
else
{
sprintf(WY_szErrString,"EnumServiceStatus Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
exit(0);
}
}
free(WY_pessService) ;
CloseServiceHandle(WY_hSCHandle);

return WY_isSetup;
}

BOOL IsServiceRun()
{
if(WY_dwCurState == SERVICE_RUNNING)
{
return TRUE;
}
else
{
return FALSE;
}
}

BOOL SetupService()
{
SC_HANDLE WY_hSCHandler,WY_hSvcHandler;
DWORD WY_dwErrCode;
char WY_szErrString[256];

//打开服务控制管理数据库
WY_hSCHandler = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(!WY_hSCHandler)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"OpenSCManager Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return FALSE;
}

//创建服务
WY_hSvcHandler = CreateService(WY_hSCHandler,WYCONST_SERVICE_NAME,WYCONST_SERVICE_NAME,SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,WY_szBinpath,
NULL,NULL,NULL,NULL,NULL);
if(!WY_hSvcHandler)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"CreateService Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return FALSE;
}
if(!RunService(WY_hSvcHandler))
{
OutputDebugString((LPCTSTR)"运行服务失败");
return FALSE;
}
CloseServiceHandle(WY_hSvcHandler);
CloseServiceHandle(WY_hSCHandler);
return TRUE;
}

BOOL RunService(SC_HANDLE WY_hSvcHandler)
{
DWORD WY_dwErrCode;
char WY_szErrString[256];

if(!StartService(WY_hSvcHandler,0,NULL))
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"StartService Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return FALSE;
}
return TRUE;
}

int MsgBox(LPCTSTR WY_lpszText, LPCTSTR WY_lpszTitle, UINT WY_uType)
{
// DWORD WY_dwCurrentTID;
DWORD WY_dwErrCode;
char WY_szErrString[256];
HWINSTA WY_hWinStaSave,WY_hWinStaUser;
HDESK WY_hDeskSave,WY_hDeskUser;
int WY_nResult;

//先保存服务进程原先的窗口站
GetDesktopWindow();
WY_hWinStaSave = GetProcessWindowStation();
if(!WY_hWinStaSave)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"GetProcessWindowStation Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return WYCONST_MSGBOX_ERROR;
}
WY_hDeskSave = GetThreadDesktop(GetCurrentThreadId());
if(!WY_hDeskSave)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"GetThreadDesktop Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return WYCONST_MSGBOX_ERROR;
}

//为了显示对话框,首先打开WinSta0 窗口站,再打开Default 桌面
WY_hWinStaUser = OpenWindowStation("WinSta0",FALSE,MAXIMUM_ALLOWED);
if(!WY_hWinStaUser)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"OpenWindowStation Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
return WYCONST_MSGBOX_ERROR;
}
SetProcessWindowStation(WY_hWinStaUser);
WY_hDeskUser = OpenDesktop("Default",0,FALSE,MAXIMUM_ALLOWED);
if(!WY_hDeskUser)
{
WY_dwErrCode = GetLastError();
sprintf(WY_szErrString,"OpenDesktop Error %d",WY_dwErrCode);
OutputDebugString(WY_szErrString);
//打开Default 桌面错误,并恢复原先的窗口站
SetProcessWindowStation(WY_hWinStaSave);
CloseWindowStation(WY_hWinStaUser);
return WYCONST_MSGBOX_ERROR;
}
SetThreadDesktop(WY_hDeskUser);

//显示MessageBox 对话框
WY_nResult = MessageBox(NULL,WY_lpszText,WY_lpszTitle,WY_uType);
//恢复原先的窗口站
SetThreadDesktop(WY_hDeskSave);
SetProcessWindowStation(WY_hWinStaSave);
CloseDesktop(WY_hDeskUser);
CloseWindowStation(WY_hWinStaUser);
return WY_nResult;
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2006-10-11
'在模块中申明:
Declare Function RegisterServiceProcess Lib "kernel32" (ByVal _
ProcessID As Long, ByVal ServiceFlags As Long) As Long
Declare Function GetCurrentProcessId Lib "kernel32" () As Long

'程序
'隐藏
RegisterServiceProcess GetCurrentProcessId, 1
'显示
RegisterServiceProcess GetCurrentProcessId, 0

---------------------------------------------------------------

Private Declare Function RegisterServiceProcess Lib "kernel32" (ByVal ProcessID As Long, ByVal ServiceFlags As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long

试试 Ctrl+Alt+Del 是不是你的程序隐藏了

Private Sub Command1_Click()
i = RegisterServiceProcess(GetCurrentProcessId, 1)
End Sub
第2个回答  2006-10-11
后台程序其实是一个叫法而已,一般不需要人工操作的一些功能类程序习惯叫做后台程序,其实也就是普通的程序而已。

如果你说的是那种WINDOWS服务程序的话,那需要按照专门的服务程序模式编写才行,普通应用程序没有办法转换成服务程序,除非重写。
第3个回答  2006-10-13
后台程序,想必楼主是要隐藏的效果。通常是没有用户界面,以及进程管理无法看见进程。

没有用户界面可以自己实现。
没有进程,有如下方法:
RegisterServiceProcess 注册隐藏
或者
根本就不是一个进程,例如是一个dll(包括api或者com)被其他进程加载或者主动注入其他进程等,请参考《windows核心编程》
第4个回答  2006-10-20
不会,纯学习 ,作书签

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网