WINAPI里的CreateThread函数
传给CreateThread的函数,必须是全局函数或静态函数,不能使用类的普通函数即,你可以使用如下函数声明:static DWORD WINAPI Run(LPVOID LpParameter);因为类的普通函数会传递类对象指针作为隐含参数,所以与CreateThread所要求的函数类型不匹配
C++ windows 本地Service
以下是一些基本知识, 不得不耐下心去理解,这对程序理解和编写非常用帮助.首先Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的Windows 会话中可长时间运行的可执行应用程序。
这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。
这使服务非常适合在服务器上使用,或任何时候,为了不影响在同一台计算机上工作的其他用户,需要长时间运行功能时使用。
还可以在不同于登录用户的特定用户帐户或默认计算机帐户的安全上下文中运行服务。
服务是有状态的,当我们使用windows自带的服务管理程序sc.exe 查看服务状态时可以显示服务的当前状态,这个状态是由我们在程序代码中进行控制的。
你最好在服务初始化的时候将服务设置为SERVICE_START_PENDING,当初始化完毕时设为SERVICE_RUNNING,这些状 态是系统自定义的状态,可通过msdn查看其他状态。
这个状态信息你会在sc.exe中看到。
在编写windows服务程序过程中你需要关注的函数有: 1.首先是main函数,由于windows服务不需要界面,所以大部分程序为win32控制台应用程序,所以程序主函数为main 而不是WinMain()。
在主函数要做的主要工作就是初始化一个SERVICE_TABLE_ENTRY 分派表结构体,然后调用StartServiceCtrlDispatcher();这将把调用进程的主线程转换为控制分派器。
该分派器启动一个新线程,该线程运行分派表中对应于你的服务的ServiceMain()函数。
ServiceMain()函数将在下面提到。
此过程示例代码如下: SERVICE_TABLE_ENTRY entrytable[2]; entrytable[0].lpServiceName="testservice"; entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain; entrytable[1].lpServiceName=NULL; entrytable[1].lpServiceProc=NULL; StartServiceCtrlDispatcher(entrytable); 在这之后系统将自动创建一个线程去执行ServiceMain函数的内容,你应该将你要执行的任务 在ServiceMain中循环,这样服务就开始运行了。
2.ServiceMain函数为void WINAPI ServiceMain(int argc, char** argv)格式的函数,函数名字可以任意定义。
它的作用就是:将你需要执行的任务放到该函数中循环执行即可。
这就是服务程序的工作函数。
在ServiceMain执行你的任务前,需要给SERVICE_TABLE_ENTRY 分派 表结构体进行赋值,注意由于此时服务还没有开始执行你的任务所以我们将服务的状态设置为SERVICE_START_PENDING,即正在初始化。
我们进行如下赋值: servicestatus.dwServiceType = SERVICE_WIN32; servicestatus.dwCurrentState = SERVICE_START_PENDING; servicestatus.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP; //在本例中只接受系统关机和停止服务两种控制命令 servicestatus.dwWin32ExitCode = 0; servicestatus.dwServiceSpecificExitCode = 0; servicestatus.dwCheckPoint = 0; servicestatus.dwWaitHint = 0; hstatus = ::RegisterServiceCtrlHandler("testservice", CtrlHandler); CtrlHandler为void WINAPI CtrlHandler(DWORD request)型的函数,函数名字可以任意设定。
将在下一点讲到。
Hstatus 为SERVICE_STATUS_HANDLE 类 型 的 全 局 变 量 。
当 需 要 改 变 服 务 状 态 时SetServiceStatus()函数需要它做为参数来标识一个服务。
3. void WINAPI CtrlHandler(DWORD request),函数的主要功能是,接收系统传递的控制命令,比如当你通过sc.exe关闭服务时,该函数会收到SERVICE_CONTROL_STOP消息,你就可以对服务进行必要的管理。
在本例子程序中就只接收SERVICE_ACCEPT_SHUTDOWN 和 SERVICE_ACCEPT_STOP消息,这是通过前面给servicestatus赋值设定的。
这样一个基本的服务程序就完成了。
本文结束的时候会附上如 何安装服务。
当服务程序需要使用某些功能时,由于用户的关系而受到限制,比如访问注册表的HKEY_CURRENT_USER键,使用网络等等,这时候就需要以当前登陆用户的身份去进行操作,通常会创建一个进程来完成需要的功能。
如果使用CreateProcess, 来创建进程的话,新创建的进程和服务程序依然是相同的用户身份,还是无法达到目的,只有使用CreateProcessAsUser了。
但CreateProcessAsUser的第一个参数是HANDLE hToken,该参数通常应该用LogonUser来获得,但是LogonUser又需要用户名和用户密码,这样就很不现实。
那应该怎么办呢?我想到了一个方法可以绕过LogonUser直接获得hToken。
因为用户已经登陆,那么肯定有Shell(就是EXPLORER.EXE)运行了,我们可以通过遍历进程来取得Shell的hToken来运行进程。
因此需要 BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName); BOOL RunProcess(LPCSTR lpImage);两个函数 示例是关于基于opencv人脸识别, 遍历样本文件夹,删除多余的图片保留10张, 然后执行 外部自定义程序"GetFeatureDATA.exe "函数提取特征 GetFeatureDATA.exe中最头上加上#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"...
如何创建一个Service
首先从VS2010中选择File -> New -> Project... 。
选择Visual C++ -> ATL -> ATL Project。
写好Name,点击OK。
再点击Next。
然后选择Service(EXE),点击Finish。
这时你会发现一个空的Service就已经被创建了。
然后里面只有两个函数。
_tWinMain 和InitializeSecurity 明显只有这两个函数是不够的。
因此还须添加其他一些函数。
具体请看以下全部CPP内的代码。
只需更改CPP内代码,就完成了。
[cpp] view plaincopy// TestService.cpp : Implementation of WinMain #include #include "stdafx.h" #include "resource.h" #include "TestService_i.h" #define SERVICE_NAME _T("Test Service") #define SERVICE_DESC _T("Test Service") const TCHAR REG_KEY_TESTSRV[] = _T("SYSTEM\\CurrentControlSet\\Services\\Test Service"); class CTestServiceModule : public ATL::CAtlServiceModuleT { public : DECLARE_LIBID(LIBID_TestServiceLib) DECLARE_REGISTRY_APPID_RESOURCEID(IDR_TESTSERVICE, "{6F4B5E0D-EBCC-472C-AD6A-897DC5BA19A1}") HRESULT InitializeSecurity() throw() { // TODO : Call CoInitializeSecurity and provide the appropriate security settings for your service // Suggested - PKT Level Authentication, // Impersonation Level of RPC_C_IMP_LEVEL_IDENTIFY // and an appropiate Non NULL Security Descriptor. HRESULT hResult = CoInitializeSecurity( NULL,-1,NULL,NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL,EOAC_NONE,NULL); if(FAILED(hResult)){ return FALSE; } return S_OK; } HRESULT RegisterAppId(bool bService = false) throw() { if (!Uninstall()) { return E_FAIL; } HRESULT hr = UpdateRegistryAppId(TRUE); if (FAILED(hr)) { return hr; } CRegKey keyAppID; LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE); if (lRes != ERROR_SUCCESS) { return AtlHresultFromWin32(lRes); } CRegKey key; lRes = key.Create(keyAppID, GetAppIdT()); if (lRes != ERROR_SUCCESS) { return AtlHresultFromWin32(lRes); } key.DeleteValue(_T("LocalService")); if (!bService) return S_OK; key.SetStringValue(_T("LocalService"), m_szServiceName); // Create service if (!Install()) { return E_FAIL; } return S_OK; } BOOL Install() throw() { if (IsInstalled()) { return TRUE; } // Get the executable file path TCHAR szFilePath[MAX_PATH + _ATL_QUOTES_SPACE]; DWORD dwFLen = ::GetModuleFileName(NULL, szFilePath + 1, MAX_PATH); if( dwFLen == 0 || dwFLen == MAX_PATH ) { return FALSE; } // Quote the FilePath before calling CreateService szFilePath[0] = _T('\"'); szFilePath[dwFLen + 1] = _T('\"'); szFilePath[dwFLen + 2] = 0; SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCM == NULL) { return FALSE; } SC_HANDLE hService = ::CreateService( hSCM, m_szServiceName, m_szServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szFilePath, NULL, NULL, _T("Winmgmt\0\0"), NULL, NULL); if (hService == NULL) { ::CloseServiceHandle(hSCM); return FALSE; } //Service Settings if(!UpdateServiceSetting(hService,szFilePath)) { ::CloseServiceHandle(hSCM); return FALSE; } ::CloseServiceHandle(hService); ::CloseServiceHandle(hSCM); return TRUE; } int WinMain(HINSTANCE hInstance) throw() { HRESULT hr = S_OK; LPTSTR lpCmdLine = GetCommandLine(); if (ParseCommandLine(lpCmdLine, &hr) == true) { hr = Start(hInstance); } return hr; } HRESULT Start(HINSTANCE hInstance) throw() { CRegKey keyAppID; LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ); if (lRes != ERROR_SUCCESS) { m_status.dwWin32ExitCode = lRes; return m_status.dwWin32ExitCode; } CRegKey key; lRes = key.Open(keyAppID, GetAppIdT(), KEY_READ); if (lRes != ERROR_SUCCESS) { m_status.dwWin32ExitCode = lRes; return m_status.dwWin32ExitCode; } TCHAR szValue[MAX_PATH]; DWORD dwLen = MAX_PATH; lRes = key.QueryStringValue(_T("LocalService"), szValue, &dwLen); m_bService = FALSE; if (lRes == ERROR_SUCCESS) m_bService = TRUE; if (m_bService) { SERVICE_TABLE_ENTRY st[] = { { m_szServiceName, _ServiceMain }, { NULL, NULL } }; if (::StartServiceCtrlDispatcher(st) == 0) m_status.dwWin32ExitCode = GetLastError(); return m_status.dwWin32ExitCode; } // local server - call Run() directly, rather than // from ServiceMain() m_status.dwWin32ExitCode = Run(hInstance); return m_status.dwWin32ExitCode; } void ServiceMain(...
VS2010中编译下面的win32项目出错:未定义的标识符"lParam",...
// Open Internet session.HINTERNET hSession = ::InternetOpen("MSDN SurfBear",PRE_CONFIG_INTERNET_ACCESS,NULL,INTERNET_INVALID_PORT_NUMBER,0) ;// Connect to http://www.microsoft.com/.HINTERNET hConnect = ::InternetConnect(hSession,"http://www.microsoft.com/",INTERNET_INVALID_PORT_NUMBER,"","",INTERNET_SERVICE_HTTP,0,0) ;// Request the file /MSDN/MSDNINFO/ from the server.HINTERNET hHttpFile = ::HttpOpenRequest(hConnect,"GET","/MSDN/MSDNINFO/",HTTP_VERSION,NULL,0,INTERNET_FLAG_DONT_CACHE,0) ;// Send the request.BOOL bSendRequest = ::HttpSendRequest(hHttpFile, NULL, 0, 0, 0);// Get the length of the file. char bufQuery[32] ;DWORD dwLengthBufQuery = sizeof(bufQuery);BOOL bQuery = ::HttpQueryInfo(hHttpFile,HTTP_QUERY_CONTENT_LENGTH,bufQuery,&dwLengthBufQuery) ;// Convert length from ASCII string to a DWORD.DWORD dwFileSize = (DWORD)atol(bufQuery) ;// Allocate a buffer for the file. char* buffer = new char[dwFileSize+1] ;// Read the file into the buffer. DWORD dwBytesRead ;BOOL bRead = ::InternetReadFile(hHttpFile,buffer,dwFileSize+1,&dwBytesRead);// Put a zero on the end of the buffer.buffer[dwBytesRead] = 0 ;// Close all of the Internet handles.::InternetCloseHandle(hHttpFile); ::InternetCloseHandle(hConnect) ;::InternetCloseHandle(hSession) ;// Display the file in an edit control.pEditCtrl->SetWindowText(buffer) ; 展开
vs2010中如何输出图形
我这有几个函数你看看 CreateCompatibleDC 函数功能 该函数创建一个与指定设备兼容的内存设备上下文环境(DC)。
通过GetDc()获取的HDC直接与相关设备沟通,而本函数创建的DC,则是与内存中的一个表面相关联。
函数原型 HDC CreateCompatibleDC(HDC hdc); 参数 hdc:现有设备上下文环境的句柄,如果该句柄为NULL,该函数创建一个与应用程序的当前显示器兼容的内存设备上下文环境。
返回值:如果成功,则返回内存设备上下文环境的句柄;如果失败,则返回值为NULL。
Windows NT:若想获得更多错误信息,请调用GetLastError函数。
注释:内存设备上下文环境是仅在内存中存在的设备上下文环境,当内存设备上下文环境被创建时,它的显示界面是标准的一个单色像素宽和一个单色像素高,在一个应用程序可以使用内存设备上下文环境进行绘图操作之前,它必须选择一个高和宽都正确的位图到设备上下文环境中,这可以通过使用CreateCompatibleBitmap函数指定高、宽和色彩组合以满足函数调用的需要。
当一个内存设备上下文环境创建时,所有的特性都设为缺省值,内存设备上下文环境作为一个普通的设备上下文环境使用,当然也可以设置这些特性为非缺省值,得到它的特性的当前设置,为它选择画笔,刷子和区域。
CreateCompatibleDc函数只适用于支持光栅操作的设备,应用程序可以通过调用GetDeviceCaps函数来确定一个设备是否支持这些操作。
当不再需要内存设备上下文环境时,可调用DeleteDc函数删除它。
ICM:如果通过该函数的hdc参数传送给该函数设备上下文环境(Dc)对于独立颜色管理(ICM)是能用的,则该函数创建的设备上下文环境(Dc)是ICM能用的,资源和目标颜色间隔是在Dc中定义。
CreateCompatibleBitmap 函数功能:该函数创建与指定的设备环境相关的设备兼容的位图。
函数原型:HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight); 参数: hdc: 设备环境句柄。
nWidth:指定位图的宽度,单位为像素。
nHeight:指定位图的高度,单位为像素。
返回值:如果函数执行成功,那么返回值是位图的句柄;如果函数执行失败,那么返回值为NULL。
若想获取更多错误信息,请调用GetLastError。
备注:由CreateCompatibleBitmap函数创建的位图的颜色格式与由参数hdc标识的设备的颜色格式匹配。
该位图可以选入任意一个与原设备兼容的内存设备环境中。
由于内存设备环境允许彩色和单色两种位图。
因此当指定的设备环境是内存设备环境时,由CreateCompatibleBitmap函数返回的位图格式不一定相同。
然而为非内存设备环境创建的兼容位图通常拥有相同的颜色格式,并且使用与指定的设备环境一样的色彩调色板。
fillsolidrect void FillSolidRect( int x, int y, int cx, int cy, COLORREF clr ); 参数: lpRec 指向RECT数据结构的指针,包含被填充的矩形的逻辑坐标,可以为该参数传递RECT数据结构或CRect对象的指针。
clr 指定填充矩形使用的颜色。
x 矩形左上角的X逻辑坐标。
y 矩形左上角的Y逻辑坐标。
cx 指定矩形的宽度。
cy 指定矩形的高度。
说明: 调用该成员函数用指定的固体色填充矩形。
FillSolidRect与CDC::FillRect类似,FillSolidRect只能使用固体色(由COLORREF参数决定)。
但FillRect带有画刷,因此可以为矩形填充固体色、抖动色、阴影或使用调色板。
FillRect通常比FillSolidRect慢。
注意:调用FillSolidRect时,以前用SetBkColor设置的背景色,被设置为clr指定的颜色。
Detach detach()函数: MFC类里CMENU类的成员函数。
功能是切断一个CWnd对象和一个有效窗口的联系。
由于WNDCLASS其实和CWnd根本没有什么关系,它们之间只是通过CWnd的成员HWND联系起来的。
Detach的作用是切断一个CWnd对象和一个有效窗口的联系。
因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个联系切断。
当我们建立了一个局部的菜单对象后,比如 在一个窗口类的函数里建立了一个局部菜单对象,当这个窗口函数的生命周期结束时,如果不希望菜单对象也被销毁,就要用detach()函数把菜单句柄和这个菜单对象分离。
这样,当局部的菜单对象被销毁时,它不会销毁一个它不具备拥有权的菜单。
GetClientRect 函数功能 该函数获取窗口客户区的坐标。
客户区坐标指定客户区的左上角和右下角。
由于客户区坐标是相对子窗口客户区的左上角而言的,因此左上角坐标为(0,0) 函数原型 在Win32 SDK, 该API函数原型为 BOOL GetClientRect( HWND hWnd, // 窗口句柄 LPRECT lpRect // 客户区坐标 ); 在MFC中,该函数的原型为void GetClientRect(LPRECT lpRect) const; 参数 hWnd [输入]是程序窗口的句柄。
lpRect [输出]是一个指针,指向一个RECT类型的rectangle结构。
该结构有四个LONG字段,分别为left、top、right和bottom。
GetClientRect将这四个字段设定为窗口显示...
Vs2012的MFC中编写SetTimer函数出错,求解。
如下图:
一下代码经过vc6实测OK写到对话框类头文件里static void CALLBACK EXPORT TimerProc(HWND hWnd, // handle of CWnd that called SetTimerUINT nMsg, // WM_TIMERUINT nIDEvent, // timer identificationDWORD dwTime // system time){CTime t;switch(nIDEvent){case 100:::SetWindowText(AfxGetMainWnd()->GetSafeHwnd(), (LPCTSTR)CString(((t=CTime::GetCurrentTime()),t.Format("%H:%M:%S"))));break;}}写到对话框OnInitDialog里SetTimer(100, 1000, CMfcdlg2014Dlg::TimerProc);KillTimer你自己写吧添加对框类析构函数或WM_CLOSE消息响应函数
win7系统,突然vs2008和vs2010下的C语言都不能屏幕输出中文了,...
是dos窗口设置问题将下面的代码复制到记事本里吧,另存为扩展名为“.reg”的文件,双击导入注册表就完成了 CMD 环境中汉字输入和汉字显示的恢复。
Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]"CodePage"=dword:000003a8小说明一下:十六进制"000003a8"或十进制"936",表示“936 (ANSI/OEM - 简体中文 GBK)”。
十六进制"000001b5"或十进制"437",表示“437 (OEM - 美国)”。
静态函数内如何调用静态成员函数指针数组
直接调用即可啊.... 不知道你提问是什么意思===============================难道我的通过不了?================#include #include using namespace std;void WhatEverFunc(int i){cout}class WhatEverClass{public:static DWORD WINAPI WorkThread(LPVOID lParam);static void (*m_pF[3])(int i);};void (*WhatEverClass::m_pF[3])(int i) = {WhatEverFunc, WhatEverFunc, WhatEverFunc};DWORD WINAPI WhatEverClass::WorkThread(LPVOID lParam){DWORD DworD = 0;while (WaitForSingleObject(GetCurrentThread(), 2000)==WAIT_TIMEOUT){m_pF[(++DworD)%3](DworD);}return 0;}int main(){HANDLE hThread = CreateThread(NULL, 0, WhatEverClass::WorkThread, NULL, 0, NULL);WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);return 0;}
转载请注明出处51数据库 » vs2010 dword winapi
段友812243