我的程序是在登录前启动的,无法进行抓屏操作(抓到的图象都是空白);如果把这个程序在IE下执行,就可以进行抓屏。实在不知这是为什么,请大家帮帮忙,谢谢!

解决方案 »

  1.   

    abrams:
      你好,我的程序没有注册为服务,但是他也是个服务程序。能否用代码来达到与桌面进行交互啊,帮帮忙啊,谢谢你
      

  2.   

    to abrams(The night beckons):
      我的程序是在windows2000下运行的,我把2000下的msgina.dll替换程我的动态连接库,然后在程序初始化时,创建一个线程,这个线程用来抓屏的,就是这样(这时他能抓到安全界面的屏幕,也就是说,执行代码进入这个动态库时,就能抓到当前窗口,否则抓不到)。如果我作一个程序,在浏览器下运行,结果正好相反。  您帮我想想办法吧,我实在搞不通了!
      

  3.   

    to nscboy(宝贝) :
      我抓到的图片是个“白板”,什么都没有啊
      

  4.   

    对了,这个动态库(msgina.dll)是属于logon.exe进程
      

  5.   

    这样吧,你换个思路试试看,你用atl做个com services,让它具有系统权限,并且允许与桌面交互,把这个服务注册好后会在,控制面板/服务 中出现,你把它启动方式设置为自动就可以了,核心代码基本不变(我指的是你控制部分)
      

  6.   

    我做不来,没做过这个程序啊,是Service application吗
      

  7.   

    file/new/projects/atl com appwizard/dynamic link library
      

  8.   

    #define SERVICE_NAME "你的服务名"SERVICE_STATUS_HANDLE serviceStatusHandle;
    HANDLE threadHandle;
    int windowId;//服务启动主程序
    int WINAPI WinMain(HINSTANCE hinst,HINSTANCE,LPSTR lpcmd,int)
    {
       SERVICE_TABLE_ENTRY serviceTable[] = {{SERVICE_NAME,(LPSERVICE_MAIN_FUNCTION)ServiceMain},{NULL,NULL}};

    StartThisServer(serviceTable);

    return 0;
    }//启动服务(执行服务代码)
    void StartThisServer(SERVICE_TABLE_ENTRY* st)
    {
    if(st == NULL)
    return; // Register with the SCM
    if(!StartServiceCtrlDispatcher(st))
    ErrorHandler("启动服务失败,调用StartServiceCtrlDispatcher错误,错误号:",GetLastError(),TRUE);
    }/////////////////////////////////////////////////////////////
    //
    // 服务主程序
    // ServiceMain is called when the SCM wants to
    // start the service. When it returns, the service
    // has stopped. It therefore waits on an event
    // just before the end of the function, and
    // that event gets set when it is time to stop.
    // It also returns on any error because the
    // service cannot start if there is an eror.
    //
    //////////////////////////////////////////////////////////////
    VOID ServiceMain(DWORD argc, LPTSTR *argv)
    {
       BOOL success;
        
       // immediately call Registration function
       serviceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME,(LPHANDLER_FUNCTION)Handler);   if(!serviceStatusHandle)
    {
    terminate(GetLastError());
    return;
    }
        
       // 通知 SCM 服务运行
       success = SendStatusToSCM(SERVICE_START_PENDING,NO_ERROR, 0, 1, 5000);
       if(!success)
    {
    terminate(GetLastError());
    return;
    }
       
       // 启动服务
    InitService();   
    }// 接收 SCM 事件函数
    VOID Handler (DWORD controlCode)
    {
    DWORD currentState = 0;
       BOOL success;
        
       switch(controlCode)
       {
    case SERVICE_CONTROL_STOP: //停止服务
    // Tell the SCM what's happening
    success = SendStatusToSCM(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, 5000);
             //这里处理一些退出时的清理工作。         
    if(windowId != 0)
    {
    //如果创建了窗口,这里先关闭你创建的窗口,然后执行下面语句
    //PostMessage(hwnd,WM_DESTROY,0,0);
    PostThreadMessage(windowId, WM_QUIT, 0, 0);
    }
    return;
             
          case SERVICE_CONTROL_INTERROGATE:
    //it will fall to bottom and send status
             break;
             //Do nothing in a shutdown. Could do cleanup
             //here but it must be very quick.
          case SERVICE_CONTROL_SHUTDOWN:
             return;
          default:
             break;
       }
       SendStatusToSCM(currentState,NO_ERROR,0,0,0);
    }
    // Handle an error from ServiceMain by cleaning up
    // and telling SCM that the service didn't start.
    VOID terminate(DWORD error)
    {
       // if terminateEvent has been created, close it.
        
       // 通知 scm 服务终止
       if(serviceStatusHandle)
          SendStatusToSCM(SERVICE_STOPPED, error,0, 0, 0);
       
       // If the thread has started, kill it off
       if(windowId != 0)
    {
    //PostMessage(hwnd,WM_DESTROY,0,0);
    PostThreadMessage(windowId, WM_QUIT, 0, 0);

       // Do not need to close serviceStatusHandle
    }BOOL SendStatusToSCM(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwServiceSpecificExitCode,DWORD dwCheckPoint,DWORD dwWaitHint)
    {
        BOOL success;
        SERVICE_STATUS serviceStatus;
        
        // Fill in all of the SERVICE_STATUS fields
        serviceStatus.dwServiceType = SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS;
        serviceStatus.dwCurrentState = dwCurrentState;
        
        // If in the process of doing something, then accept
        // no control events, else accept anything
        if (dwCurrentState == SERVICE_START_PENDING)
            serviceStatus.dwControlsAccepted = 0;
        else
            serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
            SERVICE_ACCEPT_PAUSE_CONTINUE |
            SERVICE_ACCEPT_SHUTDOWN;
        
        // if a specific exit code is defined, set up
        // the win32 exit code properly
        if (dwServiceSpecificExitCode == 0)
            serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
        else
            serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
        serviceStatus.dwServiceSpecificExitCode =dwServiceSpecificExitCode;
        serviceStatus.dwCheckPoint = dwCheckPoint;
        serviceStatus.dwWaitHint = dwWaitHint;
        
        // Pass the status record to the SCM
        success = SetServiceStatus(serviceStatusHandle,&serviceStatus);
        return success;
    }// 初始化并启动服务
    BOOL InitService()
    {
       // 开始服务线程
       DWORD gdwThreadId;
    threadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WindowThread,0,0,&gdwThreadId);

    return (threadHandle != NULL);
    }DWORD WindowThread(LPDWORD param)
    {
    windowId = GetCurrentThreadId();

    // report the status to the service control manager.
    //
    BOOL success = SendStatusToSCM(SERVICE_RUNNING,NO_ERROR,0,0,0);
       if(!success)
    {
    terminate(GetLastError());
    return 1000;
    }

    StartWindow(); SendStatusToSCM(SERVICE_STOPPED,NO_ERROR,0,0,0);
    return 1002;
    }void StartWindow()
    {
    //这里创建你的窗口,开始消息循环,抓屏等操作
    //注意窗口不关闭不能退出本函数,否则服务就退出了。
    }还有注意就是如果登陆后启动服务,能看到窗口,如果登陆前启动服务,则登陆后窗口是隐藏的,需要发消息让窗口显示。
    注册服务代码:
    //注册服务
    int regserv(BOOL bShowError/*=TRUE*/)
    {
    SC_HANDLE newService, scm;
    int res = 1; // open a connection to the SCM
    scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

    if(!scm) 
    ErrorHandler("打开服务失败,错误号:",GetLastError(),TRUE);

    // Install the new service
    newService = CreateService(
    scm,
    SERVICE_NAME,
    SERVICE_NAME,
    SERVICE_ALL_ACCESS,
    SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
    SERVICE_AUTO_START,
    SERVICE_ERROR_NORMAL,
    "可执行文件路径,eg:c:\winnt\xxx.exe"
    0, 0, 0, 0, 0);
    if(!newService)
    {
    switch(GetLastError())
    {
    case ERROR_SERVICE_EXISTS:
    ErrorHandler("服务已存在");
    break;
    default:
    res = GetLastError();
    ErrorHandler("注册服务失败(CreateService),错误号:",res,TRUE);
    break;
    }
    }
    else
    {
    ErrorHandler("服务注册成功,请在服务中启动%s服务",SERVICE_NAME);
    }

    //clean up
    CloseServiceHandle(newService);
    CloseServiceHandle(scm);
    return res;
    }
      

  9.   

    忘了讲了,ErrorHandler是我自己写的一个函数,目的是显示错误或记录到日志
      

  10.   

    终于解决了,但是服务程序只能抓到explorer桌面上的界面,不能抓到安全界面,我改成在安全界面时,使用gian里抓屏,在安全界面使用服务程序抓屏。谢谢大家帮忙。