65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 VC++ 或嵌入式 VC++ 中生成日志文件( 适用于 Pocket PC 或 WinCE 设备)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.52/5 (14投票s)

2006 年 6 月 29 日

CPOL

2分钟阅读

viewsIcon

55672

日志生成函数,包括 COM 错误信息日志记录和 MFC 异常信息日志记录。

引言

早在 2001-2002 年,当我从事一个需要构建一些 Windows 服务的项目时,我需要了解同一服务如何在 Win 2K/XP、Pocket PC 和 Win CE 设备上运行以及如何操作数据的信息。我编写了一些函数,可以将所需的信息记录到文本文件中。该函数可以接受任意数量的参数以记录到日志文件中。

本文介绍如何将所需的信息以及日期和时间戳记录到预定义的文本文件中。

使用代码

下面显示了三个函数,每个函数的详细信息都在函数注释块中提到。

要使用代码,请在此代码中将 CKishoreResearch 替换为您的项目类名,或者您可以将这三个函数放在某个 common.h 文件中,并在您的项目中将它们用作全局函数。

.h文件中,声明如下

// File pointer that will be used
// in the log functions to write to a valid file 
FILE *m_fp;
// Logs the Pointer to a null-terminated
// string of 16-bit Unicode characters 
void log(LPWSTR str, ...);
// Logs the Pointer to a null-terminated string
// of 8-bit Windows (ANSI) characters.
void log(LPSTR str, ...);

.CPP文件中,在类构造函数中,使用以下代码

m_fp = NULL;
m_fp = _wfopen(L"C:\\KishoreLog.txt", L"a");

以下是实际执行日志记录功能的已实现代码

/*
Function        : void log(LPWSTR str, ...)
Return Type     : void
parameters      : LPWSTR,Ellipsis
Use             : Logs the information onto a text file 
                  with any number of input parameters
                : Pointer to a constant null-terminated 
                  string of 16-bit Unicode characters.
Author          : Kishore Gaddam
Date            : 03 December 2002
Version         : 1.0
*/

void CKishoreResearch::log(LPWSTR str, ...)
{
    if (m_fp)
    // m_fp Contains the pointer
    // to the log file to log the information
    {
        va_list arg_ptr;
        va_start(arg_ptr, str);
        SYSTEMTIME st;
        GetLocalTime(&st);
          fwprintf(m_fp, L"[%d/%d/%d - %d:%d:%d:%d]", 
                   st.wMonth, st.wDay, st.wYear, st.wHour, 
                   st.wMinute, st.wSecond, st.wMilliseconds);
        vfwprintf(m_fp, str, arg_ptr);
        fwprintf(m_fp, L"\n");
        fflush(m_fp);
    }
}

/*
Function        : void log(LPSTR str, ...)
Return Type     : void
parameters      : LPSTR,Ellipsis
Use             : Logs the information onto a text file
                  with any number of input parameters
                : Pointer to a null-terminated string 
                  of 8-bit Windows (ANSI) characters.
Author          : Kishore Gaddam
Date            : 03 December 2002
Version         : 1.0
*/

void CKishoreResearch::log(LPSTR str, ...)
{
    if (m_fp)
    // m_fp Contains the pointer
    // to the log file to log the information
    {
        va_list arg_ptr;
        va_start(arg_ptr, str);
        SYSTEMTIME st;
        GetLocalTime(&st);
          fprintf(m_fp, "[%d/%d/%d - %d:%d:%d:%d]", st.wMonth, 
                  st.wDay, st.wYear, st.wHour, st.wMinute, 
                  st.wSecond, st.wMilliseconds);
        vfprintf(m_fp, str, arg_ptr);
        fprintf(m_fp, "\n");
        fflush(m_fp);
    }
}

/*
Function        : ComErrorMessageLog(_com_error &e)
Return Type     : void
parameters      : _com_error
Use             : Logs the COM error information to a text file
Author          : Kishore Gaddam
Date            : 03 December 2004
Version         : 1.0
*/
void CKishoreResearch::ComErrorMessageLog(_com_error &e)
{
    bstr_t bstrSource(e.Source());
    bstr_t bstrDescription(e.Description());

    log( _T("Code = 0x%08lx\n"), e.Error());
    log( _T("Code meaning = %s\n"), e.ErrorMessage());
    log( _T("IErrorInfo.Source = %s\n"), (LPTSTR)bstrSource );
    log( _T("IErrorInfo.Description = %s"), 
           (LPTSTR)bstrDescription );
}

将以上三个函数复制到您的代码中。同样,要使用该代码,请将上述代码中的类 CKishoreResearch 替换为您的项目类名。复制这三个函数后,您可以只调用 log(..) 函数,并传递需要记录到文本文件中的所需信息。

记录常用数据类型

下面列出了一些常用数据类型的示例。

例如,如果您有一个 _bstr_t 数据类型变量,并且您想使用 log 函数记录它的值

//bsSelection is the value that needs
//to be logged into the log file.
_bstr_t bsSelection;
//Make a call to Log function and pass 
//(LPTSTR)bsSelection as the parameter.
log((LPTSTR)bsSelection);

要记录 TCHAR 数据类型的值

TCHAR szSql[256];
log(szSql);

要记录 int 数据类型的值以及一些用户定义的字符串

int nData;
log("Item Select = %d", nData);

要记录多个 UINT 数据类型的值以及一些用户定义的字符串

UINT cbID1,cbID2;
log(L" ID1 is %d and ID2 is %d", cbID1, cbID2);

要记录 TCHAR 数据类型的值以及一些用户定义的字符串

TCHAR *szFolderName
log("Folder: [%s]", szFolderName);

关注点

除了记录所需的信息外,您还可以使用这些函数在异常处理中记录异常的原因。

以下代码将进入 catch 块,以处理 COM 异常

catch(_com_error &e)
{
  ::MessageBox(NULL, (char*)e.Description(), 
               "Application Error", MB_OK|MB_ICONERROR);
  ComErrorMessageLog(e);
  CoUninitialize();
}

以下代码将进入 catch 块,以处理 MFC 中的普通异常

catch(CException* e)
/ Handle all other types of exceptions here.
{
  TCHAR szErr[1024];
  e->GetErrorMessage(szErr, 1024);
  ::MessageBox(NULL, (char*)szErr, "Application Error", 
               MB_OK|MB_ICONERROR);
  log(szErr);
}

嗯,关于使用 log 函数的各种事情可以一直说下去。所以,我将在此停止,让用户使用上面的代码来记录他们的信息。 :)

© . All rights reserved.