有一段函数,获取是否安装Excel驱动CString CExport::GetExcelDriver()
{
    char szBuf[2001];
    WORD cbBufMax = 2000;
    WORD cbBufOut;
    char *pszBuf = szBuf;
    CString sDriver;

    // 获取已安装驱动的名称(涵数在odbcinst.h里)
    if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
        return "";
    
    // 检索已安装的驱动是否有Excel...
    do
    {
        if (strstr(pszBuf, "Excel") != 0)
        {
            //发现 !
            sDriver = CString(pszBuf);
            break;
        }
        pszBuf = strchr(pszBuf, '\0') + 1;
    }
    while (pszBuf[1] != '\0');

    return sDriver;
}
能否讲讲SQLGetInstalledDrivers()函数以及各参数什么意思。这段程序我就看不明白怎么能获取Excel驱动。

解决方案 »

  1.   

    SQLGetInstalledDrivers取得所有驱动到缓冲区,再用一个do while循环匹配字符串啊,有excel字样表示有安装。。
      

  2.   

    这个道理我倒是明白,但具体怎么实现的就不明白了。SQLGetInstalledDrivers()各参数代表什么。还有,strstr()函数 strstr("Hello World","Wor")=World.那么
    if (strstr(pszBuf, "Excel") != 0)
            {
                //发现 !
                sDriver = CString(pszBuf);
                break;
            }
    这一段代码并没有将strstr的返回值记录下来,但是pszBuf却等于"Microsoft Excel Driver(*.xls)",这怎么来的?
      

  3.   


    JadeScManager::JadeScManager():m_hMag(NULL),m_lpBase(NULL),m_dwError(0),m_scLock(NULL)
    {
    m_hMag = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if(m_hMag == NULL)
    m_dwError = GetLastError();
    }JadeScManager::JadeScManager(LPCTSTR lpMachineName,LPCTSTR lpDatabaseName)
      :m_hMag(NULL),m_lpBase(NULL),m_dwError(0),m_scLock(NULL)
    {
    m_hMag = OpenSCManager(lpMachineName,lpMachineName,SC_MANAGER_ALL_ACCESS);
    if(m_hMag == NULL)
    m_dwError = GetLastError();
    }JadeScManager::~JadeScManager()
    {
    if(m_hMag != NULL)
    CloseServiceHandle(m_hMag);
    if(m_lpBase != NULL)
    {
    if(HeapFree(GetProcessHeap(),0,(void*)m_lpBase))
    m_lpBase = NULL;
    }
    }DWORD JadeScManager::QueryWin32Service(DWORD dwSvrType,DWORD dwState,DWORD &dwBytesNeeded,
      DWORD &dwCount,LPENUM_SERVICE_STATUS *lpBase)
    {
    if(m_hMag == NULL)
    return m_dwError;
    if(m_lpBase != NULL)
    {
    *lpBase = m_lpBase;
    return JADE_HEAP_USED;
    }
    DWORD dwResumeHandle = 0,dwReturned = 0;
    HANDLE hHeap = GetProcessHeap();
    __try
    {
    m_lpBase = (LPENUM_SERVICE_STATUS)HeapAlloc(hHeap,HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS
    ,sizeof(ENUM_SERVICE_STATUS));
    m_dwError = EnumServicesStatus(m_hMag,dwSvrType,dwState,m_lpBase,sizeof(ENUM_SERVICE_STATUS),
         &dwBytesNeeded,&dwReturned,&dwResumeHandle);
    //绝大部都应该是0
    if(m_dwError == 0)
    {
    m_dwError= GetLastError();
    if(m_dwError == 234)
    {
    //表示分配的空间过短
    m_lpBase = (LPENUM_SERVICE_STATUS)HeapReAlloc(hHeap,HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS,
    (void*)m_lpBase,dwBytesNeeded);
    }
    else
    {
    *lpBase = NULL;
    dwBytesNeeded = 0;
    dwCount = 0;
    if(HeapFree(hHeap,0,m_lpBase))
    m_lpBase = NULL;
    return m_dwError;
    }
    }
    m_dwError = EnumServicesStatus(m_hMag,dwSvrType,dwState,m_lpBase,dwBytesNeeded,
       &dwBytesNeeded,&dwCount,&dwResumeHandle);
    if(m_dwError == 0)
    {
    *lpBase = NULL;
    dwBytesNeeded = 0;
    dwCount = 0;
    if(HeapFree(hHeap,0,m_lpBase))
    m_lpBase = NULL;
    return (m_dwError = GetLastError()); //操作有误
    }
    //
    *lpBase = m_lpBase;
    }
    __except(ExceptCode(GetExceptionCode(),GetExceptionInformation()))
    {
    lpBase = NULL;
    dwBytesNeeded = 0;
    dwCount = 0;
    if(m_lpBase != NULL)
    {
    if(HeapFree(hHeap,0,m_lpBase))
    m_lpBase = NULL;
    }
    return GetExceptionCode();
    }
    return 0;
    }DWORD JadeScManager::ReleaseQuery(LPENUM_SERVICE_STATUS lpBase)
    {
    __try
    {
    if(m_lpBase != NULL)
    {
    if(HeapFree(GetProcessHeap(),0,(void*)m_lpBase))
    {
    m_lpBase = NULL;
    lpBase = NULL;
    }
    else
    return GetLastError();
    }
    }
    __except(ExceptCode(GetExceptionCode(),GetExceptionInformation()))
    {

    return GetExceptionCode();
    }
    return 0;
    }DWORD JadeScManager::OpenService(JadeService &lpSvr,LPCTSTR lpSvrName,DWORD dwAccess)
    {
    if(m_hMag == NULL)
    return m_dwError;
    lpSvr.m_hSvr = ::OpenService(m_hMag,lpSvrName,dwAccess);
    if(lpSvr.m_hSvr == NULL)
    {
    return (lpSvr.m_dwError = GetLastError());
    }
    return 0;
    }
      

  4.   


    for(;nIndex<dwCount;nIndex++)
    {
    JadeScManager::JadeService *jSvr = new JadeScManager::JadeService;
    DWORD dwNeeded = 0,dwSvrCount = 0;
    LPQUERY_SERVICE_CONFIG lpQuerySvrCfg = NULL,lpSvrBuf = NULL;
    lpBuf = lpEnumSvrs + nIndex;
    szIndex.Format("%d",nIndex);
    pListView.InsertItem(nIndex,szIndex,-1);
    pListView.SetItem(nIndex,1,LVIF_TEXT|LVIF_IMAGE,lpBuf->lpDisplayName,0,0,0,0);
    pListView.SetItemText(nIndex,2,lpBuf->lpServiceName);
    switch(lpBuf->ServiceStatus.dwServiceType)
    {
    case SERVICE_FILE_SYSTEM_DRIVER:
    pListView.SetItemText(nIndex,5,_T("系统文件驱动"));
    break;
    case SERVICE_KERNEL_DRIVER:
    pListView.SetItemText(nIndex,5,_T("系统驱动"));
    break;
    case SERVICE_WIN32_OWN_PROCESS:
    pListView.SetItemText(nIndex,5,_T("进程内服务"));
    break;
    case SERVICE_WIN32_SHARE_PROCESS:
    pListView.SetItemText(nIndex,5,_T("进程间共享服务"));
    break;
    default:
    pListView.SetItemText(nIndex,5,_T("交互式服务"));
    }
    switch(lpBuf->ServiceStatus.dwCurrentState)
    {
    case SERVICE_RUNNING:
    pListView.SetItemText(nIndex,3,_T("正在运行"));
    break;
    case SERVICE_START_PENDING:
    pListView.SetItemText(nIndex,3,_T("正在启动"));
    break;
    case SERVICE_STOPPED:
    pListView.SetItemText(nIndex,3,_T("以停止"));
    break;
    case SERVICE_STOP_PENDING:
    pListView.SetItemText(nIndex,3,_T("正在停止"));
    break;
    case SERVICE_PAUSED:
    pListView.SetItemText(nIndex,3,_T("已暂停"));
    break;
    case SERVICE_PAUSE_PENDING:
    pListView.SetItemText(nIndex,3,_T("暂停未完成"));
    break;
    case SERVICE_CONTINUE_PENDING:
    pListView.SetItemText(nIndex,3,_T("恢复未完成"));
    break;
    }
    dwError = m_jScMag.OpenService(*jSvr,lpBuf->lpServiceName,SERVICE_ALL_ACCESS);
    if(dwError == 0)
    {
    jSvr->QuerySvrCfg(&lpQuerySvrCfg,dwNeeded,dwSvrCount);
    if(lpQuerySvrCfg != NULL)
    {
    switch(lpQuerySvrCfg->dwStartType)
    {
    case SERVICE_AUTO_START:
    pListView.SetItemText(nIndex,4,_T("自动"));
    break;
    case SERVICE_BOOT_START:
    pListView.SetItemText(nIndex,4,_T("系统载入启动"));
    case SERVICE_DEMAND_START:
    pListView.SetItemText(nIndex,4,_T("手动"));
    break;
    case SERVICE_DISABLED:
    pListView.SetItemText(nIndex,4,_T("禁用"));
    break;
    case SERVICE_SYSTEM_START:
    pListView.SetItemText(nIndex,4,_T("手动启动驱动"));
    break;
    }
    }
    }
    pListView.SetItemData(nIndex,(DWORD)jSvr);
    }
      

  5.   

    strstr函数返回的是子字符串在父字符串中首次出现的位置。。所以
    if (strstr(pszBuf, "Excel") != 0) 
            { 
                //发现 ! 
                sDriver = CString(pszBuf); 
                break; 
            }表示的意思是如果字符串中找到Excel文字的位置不为零(为零表示没有匹配到子字符串)的话,则返回已找到
      

  6.   

    BOOL SQLGetInstalledDrivers(
       LPSTR   lpszBuf,
       WORD   cbBufMax,
       WORD *   pcbBufOut);ArgumentslpszBuf[Output]
    List of descriptions of the installed drivers. For information about the list structure, see “Comments.”cbBufMax[Input]
    Length of lpszBuf.pcbBufOut[Output]
    Total number of bytes (excluding the null-termination byte) returned in lpszBuf. If the number of bytes available to return is greater than or equal to cbBufMax, the list of driver descriptions in lpszBuf is truncated to cbBufMax minus the null-termination character. The pcbBufOut argument can be a null pointer.ReturnsThe function returns TRUE if it is successful, FALSE if it fails.
      

  7.   

    楼上几个说的没听明白。
    1,char *pszBuf = szBuf;但是在函数if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))之后szBuf并未把值传递给*pszBuf,那后面的pszBuf值哪来的?
    2,pszBuf = strchr(pszBuf, '\0') + 1; 这句话什么意思,起什么作用。
      

  8.   

    pszBuf = strchr(pszBuf, '\0') + 1;这句不就是吗? 把pszBuf这个指针的位置改变,相应的子字符串也就改变了..这句的意思是在pszBuf串中找到字符'\0'出现的首位置,把把这个位置往后移动一位后的位置赋给pszBuf ..举个pszBuf的例子你可能就明白了:
    Excel Driver0Access Driver0FoxPro Driver...