当前位置:编程学习 > VC++ >>

VS源文件提取工具vsjuicer 实现细节

程序的主体框架如下列代码所示:

//by btwsmile 
 
#include "stdafx.h" 
#include "juice.h" 
 
// entry 
int _tmain(int argc, _TCHAR* argv[]) 

    CJuice juicer(argc, argv); 
    juicer.Process(); 
    return 0; 

不难看出,真正进行处理的是CJuice类对象juicer。CJuice类定义在juice.h头文件中,它包含的成员变量有:

PTSTR m_pszWrongSyntax; 
PTSTR m_pszInvalidPath; 
PTSTR m_pszHelp; 
int m_argc; 
PTSTR* m_argv; 
// complete delete 
BOOL m_bComplete; 
// report 
DWORD m_dwFileCount; 
DWORD m_dwFolderCount; 
__int64 m_nFileSize; 
DWORD m_dwMilliseconds; 
// enum type 
enum { 
    VSJT_WRONGSYNTAX = 1, 
    VSJT_INVALIDPATH, 
    VSJT_QUERYHELP, 
    VSJT_JUICE 
}; 
前3个变量是字符串指针对象,它们是输出到屏幕上的提示信息。比如,当用户键入的命令有错误,则输出m_pszWrongSyntax提示语法错误。

m_argc和m_argv由main函数指定,它来自用户的输入。比如,用户键入命令vsj /help,此时m_argc = 2,而m_argv含两个字符串,即"vsj"和"/help"。
bool变量m_bComplete表示是否彻底删除文件和目录,缺省为FALSE,只有用户键入命令时使用了/C开关才将它置为TRUE。彻底删除的文件和目录不会进入回收站。

随后的4个整数变量是一些运行统计数据,依次表示:删除的文件计数、删除的目录计数、节省的磁盘空间以及操作所用的时间。

最后是一个匿名枚举,表示用户键入命令的意图。

CJuice类首先要实现自己的构造方法,在构造方法中初始化成员变量。

// constructor 
CJuice(int argc, PTSTR* argv) : m_argc(argc), m_argv(argv), m_bComplete(FALSE), 
    m_dwFileCount(0), m_dwFolderCount(0), m_nFileSize(0), m_dwMilliseconds(0) 

    m_pszWrongSyntax = _T("Command syntax is incorrect."); 
    m_pszInvalidPath = _T("Invalid directory path."); 
    m_pszHelp = _T("\nVisual Studio Juicer (c)2012 by btwsmile") 
                _T("\nDelete insignificant files and directories of visual studio solutions.") 
                _T("\n\nVSJ path [/C]") 
                _T("\n\npath\tDirctory path containing visual studio solutions.") 
                _T("\n/C\tCompletely delete files and directories.") 
                _T("\n\nThis command only delete") 
                _T("\n(1) files with extension .sdf, .suo and .aps") 
                _T("\n(2) directories named ipch, debug and release."); 

为了代码美观一点,3个字符串指针对象的初始化并未放在初始化列表中,这样做也并不会损害程序的效率。

main函数构造了CJuice类对象后,立马调用了Process方法,因此,CJuice需向外提供Process方法。定义如下所示:

// process 
void Process() 

    int uRet = check_arguments(); 
    switch(uRet) { 
    case VSJT_WRONGSYNTAX: 
        display(m_pszWrongSyntax); break; 
    case VSJT_INVALIDPATH: 
        display(m_pszInvalidPath); break; 
    case VSJT_QUERYHELP: 
        display(m_pszHelp); break; 
    case VSJT_JUICE: 
        m_dwMilliseconds = ::GetTickCount(); 
        juice(m_argv[1]);  
        m_dwMilliseconds = ::GetTickCount() - m_dwMilliseconds; 
        report(); 
    }; 

首先调用了私有方法check_arguments,判断用户键入命令的意图,然后对不同情况进行响应。display方法的作用是打印传入的字符串参数,实现很简单:

// display message 
void display(PTSTR psz) 

    _tprintf(_T("%s\n"), psz); 

juice是程序的核心方法,它将对目录进行提取处理,删除那些多余的中间文件。而report方法的作用是打印vsjuicer运行相关的统计数据。

下面依次来看check_arguments,juice以及report方法的实现。首先是check_arguments,其定义如下列代码所示:

// check arguments 
UINT check_arguments() 

    if(m_argc < 2 || m_argc > 3) 
        return VSJT_WRONGSYNTAX; 
    if(m_argc == 2) { 
        if( ::lstrcmpi(m_argv[1], _T("/?")) == 0 || 
            ::lstrcmpi(m_argv[1], _T("/help")) == 0) 
            return VSJT_QUERYHELP; 
        return is_path_valid() ? VSJT_JUICE : VSJT_INVALIDPATH; 
    } 
    if(::lstrcmpi(m_argv[2], _T("/c")) != 0) 
        return VSJT_WRONGSYNTAX; 
    else m_bComplete = TRUE; 
    return is_path_valid() ? VSJT_JUICE : VSJT_INVALIDPATH; 

对用户键入的命令进行检查,也就是检查命令参数是否正确。vsjuicer仅仅支持3条命令:

vsj /?或vsj /help
vsj path
vsj path /c
因此m_argc只能是2或3,接着再分别对参数个数为2和3两种情况分别进行判断。check_arguments调用了私有方法is_path_valid,其作用是检查path是否有效,其定义为:

// is path valid 
BOOL is_path_valid() 

    if(!::PathFileExists(m_argv[1])) 
        return FALSE; 
    if(::PathIsDirectory(m_argv[1]) != FILE_ATTRIBUTE_DIRECTORY) 
        return FALSE; 
    return TRUE; 

is_path_valid方法调用两个API函数来实现。

如果用户键入命令的意图是对path目录下的文件进行清理,check_arguments方法的返回值就是VSJT_JUICE。接着,juice方法就会被调用。前面已经说过,juice方法是程序最重要的部分,其实现相对复杂一些,我们先理一理思路:

path目录下既包括普通文件,也包括子目录。
对普通文件来说,我们只需判断其后缀名是否为.sdf,.suo或.aps。如果是则删除之,否则就保留它。
对于子目录来说,首先要判断它的名字是否为ipch,debug或release。如果是则直接删除整个文件,否则就进入该目录,递归进行处理。
基于这样的思路,juice方法将是一个递归方法,传入参数pszPath是目录的全路径。juice方法的代码如下,稍微有一点复杂,随后我会对它进行说明。

// juice 
void juice(PTSTR pszPath) 
{        
    // delete folder if matched 
   

补充:软件开发 , Vc ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,