研究了下这个问题,主要要在一般的windows服务程序中修改两个地方:

一、调用RegisterServiceCtrlHandlerEx

VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
    // Register
the handler function for the service.

gSvcStatusHandle =
RegisterServiceCtrlHandlerEx(
        SVCNAME,
      
 SvcCtrlHandler,
        NULL);

if( !gSvcStatusHandle )
    {

        printf("Failed to register service control handler");
      
 return;
    }

// These SERVICE_STATUS members remain as set
here.

gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  
 gSvcStatus.dwServiceSpecificExitCode = 0;

// Report initial
status to the SCM.

ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR,
3000 );

// Perform service-specific initialization and
work.

HDEVNOTIFY hDevNotify;

if(!DoRegisterDeviceInterface(GUID_DEVINTERFACE_VOLUME, &hDevNotify))
  
 {
        printf("DoRegisterDeviceInterface failed\n");
      
 ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
        return;
  
 }

SvcInit( dwArgc, lpszArgv );

UnregisterDeviceNotification(hDevNotify);
}

二、注册设备响应接口

/*
Routine Description:
    Registers for notification of changes
in the device interfaces for
    the specified interface class GUID.

Parameters:
    InterfaceClassGuid - The interface class GUID for the
device
        interfaces.

hDevNotify - Receives the device
notification handle. On failure,
        this value is NULL.

Return
Value:
    If the function succeeds, the return value is TRUE.
    If the
function fails, the return value is FALSE.
*/

BOOL DoRegisterDeviceInterface(
    GUID InterfaceClassGuid,
   
HDEVNOTIFY *hDevNotify
)

{
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
   
NotificationFilter.dbcc_size =
       
sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype
= DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_classguid =
InterfaceClassGuid;

*hDevNotify =
RegisterDeviceNotification(
        gSvcStatusHandle,

        &NotificationFilter,
       
DEVICE_NOTIFY_SERVICE_HANDLE
    );

if(!*hDevNotify)
   
{
        printf("RegisterDeviceNotification failed: %d\n",

                GetLastError());
        return FALSE;
   
}

return TRUE;
}

三、处理U盘插拔消息

DWORD WINAPI SvcCtrlHandler(DWORD dwCtrl, DWORD dwEventType, LPVOID
lpEventData, LPVOID lpContext)
{
    // Handle the requested control code.

    switch(dwCtrl)
    {  
    case SERVICE_CONTROL_STOP:
      
 ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

// Signal
the service to stop.

SetEvent(ghSvcStopEvent);
        
  
     return NO_ERROR;

case SERVICE_CONTROL_DEVICEEVENT:
        if
(DBT_DEVICEARRIVAL  == dwEventType)
        {
            FILE *fp;
  
         
            DEV_BROADCAST_HDR * pHdr = (DEV_BROADCAST_HDR
*)lpEventData;
            PDEV_BROADCAST_DEVICEINTERFACE pDevInf;
      
     PDEV_BROADCAST_HANDLE pDevHnd;
            PDEV_BROADCAST_OEM
pDevOem;
            PDEV_BROADCAST_PORT pDevPort;
          
 PDEV_BROADCAST_VOLUME pDevVolume;

switch(
pHdr->dbch_devicetype )
            {
            case
DBT_DEVTYP_DEVICEINTERFACE:
                pDevInf =
(PDEV_BROADCAST_DEVICEINTERFACE)pHdr;

fp =
fopen("C:\\log.txt", "a+");
                if (fp)
              
 {
                    _ftprintf(fp, _T("%s\n"),
pDevInf->dbcc_name);
                    fclose(fp);
              
 }
                break;
            case DBT_DEVTYP_HANDLE:
      
         pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr;
                break;
  
         case DBT_DEVTYP_OEM:
                pDevOem =
(PDEV_BROADCAST_OEM)pHdr;
                break;
            case
DBT_DEVTYP_PORT:
                pDevPort = (PDEV_BROADCAST_PORT)pHdr;
  
             break;
            case DBT_DEVTYP_VOLUME:
              
 pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
                break;
      
     }
        }
        break;

case
SERVICE_CONTROL_INTERROGATE:
        // Fall through to send current
status.
        break;

default:
        break;
    }

ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
  
 return NO_ERROR;
}

如何在Windows服务程序中添加U盘插拔的消息的更多相关文章

  1. 如何在Windows服务程序中读写HKEY_CURRENT_USER注册表

    在服务程序中想要对注册表HKEY_CURRENT_USER下的内容进行读写,不会返回失败,但是始终无效.原因是: 1.服务运行在系统权限之下,而不是任何一个用户 2.HKEY_CURRENT_USER ...

  2. 如何在windows“我的电脑”中添加快捷文件夹

    如图所示,windows中打开“我的电脑”时,原来有6个默认的文件夹,访问非常便捷,自己想再增加,可以使用“ThisPCTweaker”即可完成 操作如下图,不多解释,简单操作: 文件下载:http: ...

  3. 如何在 Windows 10 中搭建 Node.js 环境?

    [编者按]本文作者为 Szabolcs Kurdi,主要通过生动的实例介绍如何在 Windows 10 中搭建 Node.js 环境.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 在本文中 ...

  4. 如何在VUE项目中添加ESLint

    如何在VUE项目中添加ESLint 1. 首先在项目的根目录下 新建 .eslintrc.js文件,其配置规则可以如下:(自己小整理了一份),所有的代码如下: // https://eslint.or ...

  5. 如何在Android Studio中添加注释模板信息?

    如何在Android Studio中添加注释模板信息? 在开发程序的时候,我们一般都会给文件自动添加上一些关于文件的注释信息,比如开发者的名字,开发的时间,开发者的联系方式等等.那么在android ...

  6. 如何在windows计划中调用备份sharepoint2010网站集的powershell脚本

    最近有个项目需要在在windows计划中使用powershell脚本备份sharepoint2010网站集,打开sharepoint的powershell执行命令管理界面的属性 查看: C:\Wind ...

  7. 文章翻译:ABP如何在EF core中添加数据过滤器

    原文地址:https://aspnetboilerplate.com/Pages/Documents/Articles%5CHow-To%5Cadd-custom-data-filter-ef-cor ...

  8. 在Windows服务中添加定时器

    创建windows服务: 在VisualStudio中用C#创建一个Windows服务,微软MSDN参考地址: http://msdn.microsoft.com/zh-cn/library/zt39 ...

  9. 如何在windows 11中安装WSLG(WSL2)

    什么是 WSL WSL(Windows Subsystem for Linux):Windows 系统中的一个子系统,在这个子系统上可以运行 Linux 操作系统. 可以让开发人员直接在 Window ...

随机推荐

  1. 2018-2019-2 网络对抗技术 20165301 Exp3 免杀原理与实践

    2018-2019-2 网络对抗技术 20165301 Exp3 免杀原理与实践 实验内容 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用 ...

  2. node.js获取请求参数的方法和文件上传

    var http=require('http') var url=require('url') var qs=require('querystring') http.createServer(onRe ...

  3. Cap+Exceptionless实现日志消息发布订阅异常情况日志处理及Cap DashBoard授权处理

    Dashboard介绍 capOptions.UseDashboard(dashoptions => { dashoptions.AppPath = "applicationpath& ...

  4. 解决导入Android例子时“Unable to resolve target 'android-x' ”的错误

    今天导入一个Android的例子程序,出现了Unable to resolve target 'android-2' 的错误. 最后google之后才发现原来是 ADK版本 :---API Level ...

  5. 使用Golang开发一个本地代理

    引言 最近需要对接一个接口,人家提供了两种调用方式,第一种是基于IE浏览器的Active,第二种是动态链接库dll.我们公司的产品不支持IE,所以只能通过调用dll来完成了. 之前我已经用Java实现 ...

  6. 网页图表Highcharts实践教程之图表区

    网页图表Highcharts实践教程之图表区 网页图表Highcharts图表区 图表区是图表的基本区域.所有的数据和图形都是绘制在图表区中.从图形绘制范围来分,图表区域分为外层图表区和绘图区.本章将 ...

  7. 捕获程序异常之onerror

    问题描述:html5页面在电脑上打开,功能正常,没有报错,一旦嵌进微信或者APP,页面就卡住了,不好排查js问题. 预期结果:手机微信页面功能失效时,开发人员在console面板能明确看到出错信息,出 ...

  8. [ 转载 ] get和post的区别

    GET和POST两种基本请求方法的区别   GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过r ...

  9. BZOJ.1034.[ZJOI2008]泡泡堂(贪心)

    题目链接 容易想到田忌赛马.但是是不对的,比如2 3对1 3,按田忌赛马策略会3->1 2->3,但是3->3 2->1显然更优. 而如果按己方最强>=对方最强则开打,也 ...

  10. zoj 3460 二分+二分图匹配

    不错的思想 /* 大致题意: 用n个导弹发射塔攻击m个目标.每个发射架在某个时刻只能为 一颗导弹服务,发射一颗导弹需要准备t1的时间,一颗导弹从发 射到击中目标的时间与目标到发射架的距离有关.每颗导弹 ...