在WINDOWS NT 中有一个功能强大的SERVICE 管理器, 它管理着一部分实现重要功能的后台进程, 例如FTP.HTTP.RAS. 网络Message 等等, 这些后台进程被称之为Service, 他们可以在系统启动时就加载, 可以运行在较高的优先级, 可以说是非常靠近系统核心的设备驱动程序中的一种. WINDOWS95 没有提供SERVICE 管理器, 取而代之的是一个简单的登记接口, 可以类似的称之为WINDOWS95 下的Service( 不过严格的讲,WINDOWS95 下是没有Service 的), 同样的, 通过这个登记接口, 我们可以使自己的程序随系统启动而最先运行, 随系统关闭而最后停止, 和操作系统结合在一起, 实现许多独特的功能. 首先我们可以先来看看一些相关的知识。

进程数据库(PDB) 介绍
  在Windows 的核心数据结构中, 有一个重要的进程管理结构叫进程数据库, 它位于Kernel32 的公用内存堆中,可以通过GetCurrentProcessID(...) 得到指向该结构的指针, 以下是部分PDB 的组成, 与本文直接相关的是PDB 偏移21h 处的Service 标志字节, 通过后面的伪码分析, 我们可以清楚的看到所谓登记为Windows95 或Windows98 下的Service 进程, 只不过是把它相应的PDB 中该标志字节置为1 而已.

偏移量长度            说明
============================================
+00h   DWORD      Type // Kernel32 对象的类型
+04h   DWORD      CReference // 参考计数
+08h   DWORD      Un1 // 未知
+0ch   DWORD      pSomeEvent // 指向K32OBJ_EVENT 指针
+10h   DWORD      TerminationStatus // 活动标志或返回值
+14h   DWORD      Un2 // 未知
...
+21h   BYTE       Flags1 // Service 标记,
                         // "1" 是Service 进程,
                         // "0" 普通进程
...
+24h   DWORD      pPSP  // DOS PSP 指针
...
============================================

实现接口
  (1) Windows95 中提供的简单的Service 接口是一个32 位的API: RegisterServiceProcess, 由于在VC++ 的Online help 中得不到关于这个API 的确切解释, 笔者不得不针对此API 进行了逆向分析, 以下是在Windows95 的Kernel32.dll 中该API 的伪码. 我们可以清楚的看到Window95 内部到底是怎样做的, 其实处理的非常简单.

BOOL RegisterServiceProcess( DWORD dwProcessID, DWORD dwType )
{
  HANDLE dwPID;
  if( dwProcessID == NULL )
     dwPID = dwCurrentProcessID; // Get global kernel32 variable
  else
      // Call some kernel functions
     if( ( dwPID = CheckPID( dwProcessID ) == NULL )
         return FALSE;
  if( dwType == 1 )
  {
     *(BYTE *)( dwPID + 0x21 ) | = 0x01;
     return TRUE;
  }
  if( dwType == 0 )
  {
     *(BYTE *)( dwPID + 0x21 ) & = 0xFE;
     return TRUE;
  }
  return FALSE;
}
    以下为函数原形:
BOOL    RegisterServiceProcess( DWORD dwPID, DWORD dwType )
参数:   dwPID: 进程ID, NULL 代表当前进程
        dwType: RSP_SIMPLE_SERVICE 为登记
                RSP_UNREGISTER_SERVICE 为取消登记
返回值: TRUE:   调用成功
        FALSE:  调用失败

  (2) 另外, 为了让Service 进程有机会在BOOT 后就启动,Windows95 的Registry 中提供了加载方法: 在KEY " MyComputer/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/RunServices " 加入自己的应用程序命令行, 即可实现开机自动加载. 当然, 如果你得机器中没有这个Key, 自己建一个也是可以的.

例程
---- 下面是实现例程, 所有代码经过了测试, 可以方便的加入到自己的项目文件中.
---- 头文件:

// File:           service.h
// The head file of "service.cpp"
// Note: 1. You must use C++ compiler
//     2. The platform is WIN32 (WINNT & WIN95)

#ifndef _SERVICE_H
#define _SERVICE_H

/// USED FOR WIN95 SERVICE
// Micros
#define RSP_SIMPLE_SERVICE                      1
#define RSP_UNREGISTER_SERVICE          0

// Function types for GetProcAddress
#define RegisterServiceProcess_PROFILE  (DWORD (__stdcall *) (DWORD, DWORD))

// Service Fuctions in Win95
BOOL    W95ServiceRegister(DWORD dwType);
BOOL    W95StartService( DWORD dwType );

#endif

CPP 文件:
// File:                service.cpp --- implement the service

#include "service.h"
/// USED FOR WIN95 SERVICE
登记为Service 子程序:

/
// Define:              BOOL    W95ServiceRegister(DWORD dwType)
// Parameters:  dwType  --- Flag to register or unregister the service
//            RSP_SIMPLE_SERVICE      means register
//            RSP_UNREGISTER_SERVICE  means unregister
// Return:  TRUE --- call success; FALSE --- call failer

BOOL    W95ServiceRegister( DWORD dwType )
{
        // Function address defination
        DWORD   (__stdcall * hookRegisterServiceProcess)
                   ( DWORD dwProcessId, DWORD dwType );

// Get address of function
        hookRegisterServiceProcess = RegisterServiceProcess_PROFILE
                                                 GetProcAddress
   (GetModuleHandle("KERNEL32"),
  TEXT("RegisterServiceProcess"));

// Register the WIN95 service
        if(hookRegisterServiceProcess(NULL,dwType)==0)
                return FALSE;
        return TRUE;
}

加入注册表程序:

#define SERVICE_NAME    TEXT("SERVICE")
// Define:              BOOL    W95StartService( DWORD dwType )
// Parameters:  dwType  --- Flag to register or unregister the service
//            RSP_SIMPLE_SERVICE      means register
//            RSP_UNREGISTER_SERVICE  means unregister
// Return: TRUE --- call success; FALSE --- call failer

BOOL W95StartService( DWORD dwType )
{
        // Local Variables
        TCHAR   lpszBuff[256];
        LPTSTR  lpszStr = lpszBuff +128;
        LPTSTR  lpszName        = lpszBuff;
        HANDLE  hKey            = NULL;
        DWORD   dwStrCb         = 0;
        DWORD   dwValueType     = 0;

// Get service name currently
        lpszName = GetCommandLine();
        for( int i = _tcslen(lpszName)-1; i>=0; i-- )
        {
                if( ( lpszName[i] != '"' )&&( lpszName[i]!=' ') )
                        break;
                else if( lpszName[i] == '"' )
                        lpszName[i] = '/0';
        }
        if( lpszName[0] == '"' )
                lpszName = lpszName +1;

// Registe as start up service
        if( RegOpenKeyEx (HKEY_LOCAL_MACHINE,
TEXT( "SOFTWARE//Microsoft//Windows//CurrentVersion//RunServices"),
                     0,
                     KEY_QUERY_VALUE | KEY_SET_VALUE,
                     &hKey ) != ERROR_SUCCESS )
        {
                if( RegCreateKey(       HKEY_LOCAL_MACHINE,
TEXT( "SOFTWARE//Microsoft//Windows//CurrentVersion//RunServices"),
                                        &hKey ) != ERROR_SUCCESS )
                {
                        //DebugOut( "RegCreateKey() error!");
                        return FALSE;
                }
        }

dwValueType     = REG_SZ;
        dwStrCb         = 128;

// Take value
        if( RegQueryValueEx(hKey,
                                SERVICE_NAME,
                                0,
                                &dwValueType,
                                (LPBYTE)lpszStr,
                                &dwStrCb ) == ERROR_SUCCESS )
        
        {
                // Find this key value
                if( _tcscmp( lpszStr, lpszName )==0 )
                {
                        // Remove the service
                        if( dwType == RSP_UNREGISTER_SERVICE )
                        {
if( RegDeleteValue( hKey, SERVICE_NAME ) == ERROR_SUCCESS )
                                {
                                        RegCloseKey ( hKey );
                                        return TRUE;
                                }
                                RegCloseKey( hKey );
                                return FALSE;
                        }
                        // Already exist service
                        if( dwType == RSP_SIMPLE_SERVICE )
                        {
                                //DebugOut("Already registed!");
                                RegCloseKey( hKey );
                                return TRUE;
                        }
                }
                // Not find it
        } // No this value

// Unregiste return
        if( dwType == RSP_UNREGISTER_SERVICE )
        {
                RegCloseKey( hKey );
                return TRUE;
        }

// No this value then create it
        if( dwType == RSP_SIMPLE_SERVICE )
        {
                dwStrCb = 128;

// Set value
                if( RegSetValueEx(hKey,
                                        SERVICE_NAME,
                                        0,
                                        REG_SZ,
                                        (CONST BYTE *)lpszName,
                                        dwStrCb ) != ERROR_SUCCESS )
                {
                        //DebugOut("RegSetValueEx() error!");
                        RegCloseKey( hKey );

return FALSE;
                }
                RegCloseKey( hKey );
                return TRUE;
        }

// Unknow type
        RegCloseKey( hKey );
        return FALSE;
}

主程序:
// WinMain function is the entry of the this program
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
        if( W95ServiceRegister( RSP_SIMPLE_SERVICE ) )
        {
                W95StartService( RSP_SIMPLE_SERVICE );
        }

MessageBox(NULL, "Sample service", "SERVICE", MB_OK );
        UNREFERENCED_PARAMETER( hInstance );
        UNREFERENCED_PARAMETER( lpCmdLine );
        UNREFERENCED_PARAMETER( nCmdShow );
        UNREFERENCED_PARAMETER( hPrevInstance );
        return 0;
}

  运行这个程序, 等到MessageBox 弹出后, 从WINDOWS 中退出到LOG ON 状态, 你会看见MessageBox 一直保持打开状态直至受到响应或系统关机.

自己编制windows的后台进程程序相关推荐

  1. Windows平台下程序打包流程

    Windows平台下程序打包流程 1.所有测试完成之后.程序release编译完成 2.依赖库打包 执行deploy.bat 脚本打包最新的程序以及依赖库 3.可执行程序打包 打开打包工程文件.evb ...

  2. Windows下Qt程序打包

    Windows下Qt程序打包 将windeployqt.exe 目录添加到系统环境变量 windeployqt.exe目录如下: 命令行打包 1.打开命令行 2.执行打包命令 windeployqt ...

  3. Windows Azure Platform Introduction (6) Windows Azure应用程序运行环境

    <Windows Azure Platform 系列文章目录> Windows Azure应用程序运行环境 Windows Azure云计算平台是提供PaaS(平台即服务)和IaaS(基础 ...

  4. Windows Phone 应用程序生命周期

    下图演示了 Windows Phone 应用程序的生命周期.在该图中,圆圈表示应用程序的状态.矩形显示应用程序应管理其状态的应用程序级别或页面级别的事件. Launching 事件 Launching ...

  5. 如何在C#Windows控制台应用程序中更新当前行?

    使用C#构建Windows控制台应用程序时,是否可以在不扩展当前行或转到新行的情况下写入控制台? 例如,如果我想显示一个百分比,该百分比代表一个过程到完成为止的距离,我只想在与光标相同的行上更新值,而 ...

  6. Windows Phone + VB 程序员=好的移动应用程序

    原文出处:http://blogs.msdn.com/b/somasegar/archive/2010/09/23/windows-phone-vb-developers-great-mobile-a ...

  7. 有了Windows Defender应用程序防护功能,再也不担心电脑免遭恶意***

    测试者发现,Windows 10 Creators Update (Redstone 2) build 15031中的Edge浏览器已经集成了Windows Defender应用程序防护功能,用户可以 ...

  8. 什么是Windows Service应用程序?(转)

    什么是Windows Service应用程序? Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务 ...

  9. Windows 8让程序员们忧心忡忡

    一周前,微软首次向外界展示了其下一代操作系统的用户界面,评论圈的大部分反应是积极的,然而程序员们却感到忧心忡忡:因为他们以前的经验在Windows 8中变得无足轻重. Windows 8中提供了新的A ...

最新文章

  1. JavaScript面向对象怎样删除标签页?
  2. 使用了SDRAM,使用了分散加载文件,出现HardFault_Handler
  3. mysql text 不可指定默认值
  4. java排队买票_【排队买票】 (Java代码)
  5. 有三AI一周年了,说说我们的初衷,生态和愿景
  6. 清华源安装指定版本tensorflow
  7. Linux部署oracle11g,linux环境下部署Oracle11g
  8. docker kibana mysql_docker 安装常用组件:[redis,mysql,mongodb,elasticsearch,kibana,exceptionless]...
  9. Nginx Location块中proxy_pass配置/路径问题
  10. Java 从入门到精通 第16章String类
  11. 电源电压测试所用到的电流探头-品致探头
  12. (1)ENVI-met项目介绍
  13. 女子学电子计算机哪一项专业好,2018最适合女生的高考热门专业有哪些
  14. Python学习打卡【Task3】异常处理
  15. 沈航C语言上机实验题答案,2017年沈阳航空航天大学航空航天工程学部823C语言程序设计考研题库...
  16. Hibernate 3.6.10 jar包下载链接
  17. android 查看视频大小,android mediaplayer 视频修改视频大小 (屏幕尺寸mediaPlayer =......
  18. 【Android】RXAndroid
  19. 联想A800新蜂ROM V1.1 基于官方4.0.4精简省电稳定
  20. DOL魔盘存储网络管理系统试用心得(转)

热门文章

  1. 利用这些心理学效应,轻松拿到满意offer
  2. 2019-2020年中国小吃产业发展报告
  3. 2020年灵活用工行业研究报告
  4. 互联网日报 | 苏宁易购拿下英雄联盟职业联赛赞助权;荣耀游戏本年内将推出;英特尔芯片总设计师辞职...
  5. 上班之第一个无聊周末
  6. 上传图片在浏览器可以正常查看 在手机不显示_自己拥有一台服务器可以做哪些很酷的事情...
  7. 大规模异构数据并行处理系统的设计、实现与实践
  8. 【新书速递】你想知道的通信“灵魂三问”都在这里……(福利再现)
  9. 【计算机组成原理】总线
  10. 【分享】搭建域环境实现主域和文件服务器的热备冗余