to abrams(The night beckons): 我的程序是在windows2000下运行的,我把2000下的msgina.dll替换程我的动态连接库,然后在程序初始化时,创建一个线程,这个线程用来抓屏的,就是这样(这时他能抓到安全界面的屏幕,也就是说,执行代码进入这个动态库时,就能抓到当前窗口,否则抓不到)。如果我作一个程序,在浏览器下运行,结果正好相反。 您帮我想想办法吧,我实在搞不通了!
file/new/projects/atl com appwizard/dynamic link library
#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;
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.
// 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);
// 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);
你好,我的程序没有注册为服务,但是他也是个服务程序。能否用代码来达到与桌面进行交互啊,帮帮忙啊,谢谢你
我的程序是在windows2000下运行的,我把2000下的msgina.dll替换程我的动态连接库,然后在程序初始化时,创建一个线程,这个线程用来抓屏的,就是这样(这时他能抓到安全界面的屏幕,也就是说,执行代码进入这个动态库时,就能抓到当前窗口,否则抓不到)。如果我作一个程序,在浏览器下运行,结果正好相反。 您帮我想想办法吧,我实在搞不通了!
我抓到的图片是个“白板”,什么都没有啊
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;
}