可以得到的本地信息有: 硬盘序列号, 网卡号, 本地IP
稍后整理。
资料:
用WMI得IP
http://www.codeproject.com/KB/dialog/IP_Address_WMI.aspx WMI Sample Get IP address
得ip的3种方法
Finding IP Address Information http://www.codeproject.com/KB/IP/obafindingipinformation.aspx
Wake On LAN (WOL) http://www.codeproject.com/KB/IP/WOL.aspx
/**
* 这种方法得本地IP, 简单实用
*/
Get all IP numbers of your machine and how to pass through an authenticating proxy http://www.codeproject.com/KB/IP/getipnr.aspx
// GetLocalPcInfo.cpp : Defines the entry point for the console application. // #include "stdafx.h" /** * 在预编译选项下定义了 _WIN32_DCOM */ #include <comdef.h> #include <wbemidl.h> #pragma comment(lib, "wbemuuid.lib") #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif / // The one and only application object CWinApp theApp; using namespace std; SCODE GetLocalIP1st(CStringArray & csArrIP); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else { INT n = 0; CStringArray csArrIP; if((S_OK != GetLocalIP1st(csArrIP)) || (csArrIP.GetSize() <= 0)) { printf("没有得到本地IP/n"); } else { printf("本地IP列表:/n"); for(n = 0; n < csArrIP.GetSize(); n++) { printf("%s/n", csArrIP.GetAt(n)); } /** run results 本地IP列表: 192.168.1.134 192.168.171.1 192.168.160.1 */ /** * 多个IP情况的产生原因: 有多个网卡 * 多个网卡可以是物理网卡和虚拟网卡 * 虚拟网卡由软件安装的驱动产生, 例如vmware, vpn */ } } getchar(); return nRetCode; } SCODE GetLocalIP1st(CStringArray & csArrIP) { BOOL bGetIPOK = FALSE; ULONG uRc = 0; LONG lLowerBound = 0; LONG lUpperBound = 0; PCHAR pcIP = NULL; HRESULT hr; BSTR bstrNamespace = (L"root//cimv2"); BSTR * pbstrIP = NULL; VARIANT vtProp; SAFEARRAY *sa = NULL; IWbemLocator * pLoc = NULL; IWbemServices * pSvc = NULL; IEnumWbemClassObject * pEnumerator = NULL; IWbemClassObject * pClassObject = NULL; csArrIP.RemoveAll(); CoInitialize(NULL); /** * Security needs to be initialized in XP first * and this was the major problem why it was not working in XP. */ if(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0) != S_OK) return S_FALSE; if(CoCreateInstance (CLSID_WbemAdministrativeLocator, NULL , CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER , IID_IUnknown , (PVOID *)&pLoc) != S_OK) return S_FALSE; if(pLoc->ConnectServer(bstrNamespace, // Namespace NULL, // Userid NULL, // PW NULL, // Locale 0, // flags NULL, // Authority NULL, // Context &pSvc) != S_OK) return S_FALSE; hr = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hr)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return S_FALSE; } while (pEnumerator) { hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObject, &uRc); if(FAILED(hr)) break; if(0 == uRc) break; hr = pClassObject->Get(L"IPEnabled", 0, &vtProp, 0, 0); if(FAILED(hr)) break; if(vtProp.boolVal) { hr = pClassObject->Get(L"IPAddress", 0, &vtProp, 0, 0); if(FAILED(hr)) break; sa = vtProp.parray; hr = SafeArrayGetLBound( sa, 1, &lLowerBound); if(FAILED(hr)) break; hr = SafeArrayGetUBound( sa, 1, &lUpperBound); if(FAILED(hr)) break; hr = SafeArrayAccessData(sa, (void HUGEP**)&pbstrIP); if(FAILED(hr)) break; pcIP = _com_util::ConvertBSTRToString(*pbstrIP); if(pcIP) { csArrIP.Add(pcIP); bGetIPOK = TRUE; delete pcIP; pcIP = NULL; } hr = SafeArrayUnaccessData(sa); } } return bGetIPOK ? S_OK : S_FALSE; }
使用COM方法来取的IP的方法极其不好, CoInitialize(NULL), CoInitializeSecurity, CoUninitialize(), 在一个进程中只能顺序调用一次.
如果主程序或依赖的ocx, dll中,有多次调用CoInitialize,CoInitializeSecurity, 会导致COM操作失败. 如果都是自己写的程序好能控制,如果有同事或第三方的组件,那就不能保证每次的COM操作都成功.
/** * CoInitialize */ Typically, the COM library is initialized on a thread only once. Subsequent calls to CoInitialize or CoInitializeEx on the same thread will succeed, as long as they do not attempt to change the concurrency model, but will return S_FALSE. To close the COM library gracefully, each successful call to CoInitialize or CoInitializeEx, including those that return S_FALSE, must be balanced by a corresponding call to CoUninitialize. However, the first thread in the application that calls CoInitialize(0) or CoInitializeEx(COINIT_APARTMENTTHREADED) must be the last thread to call CoUninitialize(). If the call sequence is not in this order, then subsequent calls to CoInitialize on the STA will fail and the application will not work. Because there is no way to control the order in which in-process servers are loaded or unloaded, it is not safe to call CoInitialize, CoInitializeEx, or CoUninitialize from the DllMain function. /** * CoInitializeSecurity */ Registers security and sets the default security values for the process. This function is called exactly once per process, either explicitly or implicitly. It can be called by the client, server, or both. For legacy applications and other applications that do not explicitly call CoInitializeSecurity, COM calls this function implicitly with values from the registry. If you set process-wide security using the registry and then call CoInitializeSecurity, the AppID registry values will be ignored, and the CoInitializeSecurity values will be used
