首页
社区
课程
招聘
[原创][开源]杀毒软件的框架设计
发表于: 2015-11-14 15:29 22802

[原创][开源]杀毒软件的框架设计

2015-11-14 15:29
22802
首先推荐下上个帖子  有兴趣移步 哈哈 
网络编程通信方面:
http://bbs.pediy.com/showthread.php?p=1402027#post1402027

病毒查杀代码来自[部分更改]:
http://bbs.pediy.com/showthread.php?t=204845

服务管理代码来自][添加禁止/启动服务]:
http://bbs.pediy.com/showthread.php?t=205382

开始进入正题。 为了阅读体验,我源码尽量少贴,只贴关键性代码(我认为的)并不是故意  
环境VS2012 WIN10 X64

界面【具体操作有动画效果】:









  • 全面体检:
  •                  我们负责索引病毒查杀、软件卸载、启动项管理、垃圾清理、内存优化这几个类便是。
    HomePage.h     HomePage.cpp
    [索引即可,并不关键]
    

  • 病毒查杀:
  •                  采用MD5查杀,MD5计算来自网络,所以开源的好处就是可以帮助需要帮助的人。
    MDC的值为CHAR*类型  我们自己需要个病毒库,或云端、或本地,我并没有,所以也无法上传病毒库啦,但我怎么确定功能是否有效呢? 很简单,我们把计算好的.EXE\.TXT.MP3.AVI.XXX任意类型的MD5值认定为病毒! 然后查杀。这么一说是不是感觉so easy!
                      好了 既然简单也就没什么好说的了。
    全盘查杀:
    VirusScanner.h     VirusScanner.cpp
    
    DWORD WINAPI VirusScanner::AllProc(LPVOID lpThreadParameter)
    {
      m_this->isInThead=true;
      WCHAR DiskName[MAX_PATH] = {0};
      GetLogicalDriveStrings(MAX_PATH,DiskName);
      int i = 0,j=0;
      for (; DiskName[i]!='\0'&& i < MAX_PATH; i++,j++)
      {
        m_this->TraverseFolder(DiskName,L".txt.exe.dll");
        i+=wcslen(&DiskName[i]);
        
      }
      if (!m_this->m_ButtonState)
      {
    
      m_this->  m_BackgroundPic=IDB_BITMAP5;//背景图片
      m_this->  MovebkPic(m_this->m_BackgroundPic);
      m_this->  m_ButtonState=true;
      m_this->  isInThead=false;
    
        //  m_AllKill.ShowWindow(SW_SHOW);
        //  m_AssignButton.ShowWindow(SW_SHOW)
      m_this->  m_StartupVirus1.ShowWindow(SW_SHOW);
      m_this->  m_StartupVirus2.ShowWindow(SW_SHOW);
      }
      return 0;
    }
    


    闪电查杀:
    DWORD WINAPI VirusScanner::LightningProc(LPVOID lpThreadParameter)
    {
      //C:\\Program Files (x86)   C:\\Program Files  D:\Program Files
      m_this->isInThead=true;
      WCHAR DiskName[MAX_PATH][MAX_PATH] = {
                _T("C:\\Program Files (x86)"),    //闪电杀毒查杀的范围
                _T("C:\\Program Files"),
                _T("D:\\Program Files"),
                _T("D:\\Program Files (x86)"),
                _T("E:\\Program Files"),
                _T("E:\\Program Files (x86)"),
      };
      int i = 0;
      for (; i<7; i++)
      {
        m_this->TraverseFolder(DiskName[i],L".txt.exe.dll.mp3.avi");  //填写要扫描的类型
      }
      if (!m_this->m_ButtonState)
      {
    
      m_this->  m_BackgroundPic=IDB_BITMAP5;//背景图片
      m_this->  MovebkPic(m_this->m_BackgroundPic);
      m_this->  m_ButtonState=true;
      m_this->  isInThead=false;
        //  m_AllKill.ShowWindow(SW_SHOW);
        //  m_AssignButton.ShowWindow(SW_SHOW)
      m_this->  m_StartupVirus1.ShowWindow(SW_SHOW);
      m_this->  m_StartupVirus2.ShowWindow(SW_SHOW);
      }
      return 1;
    }
    


    指定位置查杀:
    索引AssignKill.h     AssignKill.cpp
    

    它们都用到的关键性函数:
    WIN32_FIND_DATAW findFileData={0};
      TCHAR szFind[MAX_PATH] = {_T("\0")};
      CString pipei=filetype;//pipei 匹配O(∩_∩)O~
      BOOL bRet;
      CString fileRootPath = szName;
      CString filePath = fileRootPath+_T("\\*.*");
      HANDLE hwnd=FindFirstFile(filePath,&findFileData);
      if (hwnd==INVALID_HANDLE_VALUE)//没找到文件
      {
        MessageBox(_T("该文件路径不存在"),_T("错误"),NULL);
        return;
      }
      while (true)
      {
        if (_tcscmp(findFileData.cFileName,_T("."))==0||
          _tcscmp(findFileData.cFileName,_T(".."))==0 )
        {
          bRet=FindNextFile(hwnd,&findFileData);
          if (!bRet)
          {
            break;
          }
          continue;
        }
        CString path = fileRootPath+ _T("\\")+ findFileData.cFileName;
        int index = path.ReverseFind(_T('.'));
        CString pix  = path.Right(path.GetLength()-index);
        if (pipei.Find(pix)!=-1)
        {
          char *MD5="bacf0d5cec1d91f252b42c39d0bea5ca";//你认为的文件是病毒的MD5的值  
    
          CStringA ff(path);
          char * h = md5FileValue(ff.GetBuffer());
          if (strcmp(h,MD5)==0)
          {
            //DeleteFile(path);
            MessageBox(L"已查杀");
          }
        }
        if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          _tcscpy_s(szFind,MAX_PATH,szName);
          _tcscat_s(szFind,_T("\\"));
          _tcscat_s(szFind,findFileData.cFileName);
          TraverseFolder(szFind,pipei);
        }
        bRet=FindNextFile(hwnd,&findFileData);
        if (bRet==0)
        {
          break;
        }
    
      }
    


  • 服务管理:
  •                 用函数遍历服务ListControl显示   
    ServiceManagement.h     ServiceManagement.cpp
    [上个帖子有介绍]
    


  • 软件卸载:
  •                  这个操作关乎到注册表,所以我们要用到注册表相关函数 找到主键遍历子键删除键值就OK啦。
    UninstallTool.h     UninstallTool.cpp.cpp
    //加载软件信息
    void UninstallTool::UninstallIndex()
    {
      LONG nRet=RegOpenKeyEx(RootKey,lpSubKey,0,KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,&hkResult);
      if (nRet!=ERROR_SUCCESS)
      {
        return ;
      }
      DWORD dwIndex=0;
      //循环遍历子键
      while (true)
      {
    
        DWORD dwKeyLen=MAX_KEY_LENGTH;
        //WCHAR szNewKeyName[MAX_PATH]={};
        TCHAR szNewKeyName[MAX_KEY_LENGTH] ;
        nRet=RegEnumKeyEx(hkResult,dwIndex,szNewKeyName,&dwKeyLen,NULL,NULL,NULL,NULL);
        if (nRet!=ERROR_SUCCESS)
        {
          break;    //可断点检查相应错误
        }
        //通过得到的子键组合新的子键路径
        WCHAR strMidReg[MAX_PATH]={};
        swprintf_s(strMidReg,L"%s%s%s",lpSubKey,L"\\",szNewKeyName);
        //打开新的子键获取句柄
        HKEY hkValueKey=0;
        RegOpenKeyEx(RootKey,strMidReg,0,KEY_QUERY_VALUE,&hkValueKey);
        //获取键值
        DWORD dwNameLen=255;
        DWORD dwtype;
        RegQueryValueEx(hkValueKey,L"DisplayName",0,&dwtype,(LPBYTE)SoftInfo.szSoftName,&dwNameLen);//软件名
        if(m_VecSoftInfo.size()>1)
        {
          if ((wcscmp(SoftInfo.szSoftName,m_VecSoftInfo[m_VecSoftInfo.size()-1].szSoftName)==0))
          {
            dwIndex++;
            continue;
          }
        }
        m_UniListCtrl.InsertItem(0,SoftInfo.szSoftName);
        dwNameLen=255;//如果没有重新赋值 下一次将获取不到路径 
        dwtype=0;           //也许dwtype并不要但是 重新赋值并无坏处吧
        RegQueryValueEx(hkValueKey,L"UninstallString",0,&dwtype,(LPBYTE)SoftInfo.szSoftUniPath,&dwNameLen);//卸载路径
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"DisplayIcon",0,&dwtype,(LPBYTE)SoftInfo.szSoftIco,&dwNameLen);//光标路径
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"DisplayVersion",0,&dwtype,(LPBYTE)SoftInfo.szSoftVer,&dwNameLen);//版本号
        m_UniListCtrl.SetItemText(0,1,SoftInfo.szSoftVer);
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"Publisher",0,&dwtype,(LPBYTE)SoftInfo.szSoftVenrel,&dwNameLen);//发布厂商
        m_UniListCtrl.SetItemText(0,3,SoftInfo.szSoftVenrel);
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"InstallDate",0,&dwtype,(LPBYTE)SoftInfo.szSoftDate,&dwNameLen);//安装日期
        m_UniListCtrl.SetItemText(0,2,SoftInfo.szSoftDate);
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"URLInfoAbout",0,&dwtype,(LPBYTE)SoftInfo.szURLInfo,&dwNameLen);//网站
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"HelpLink",0,&dwtype,(LPBYTE)SoftInfo.HelpLink,&dwNameLen);//网站
        dwNameLen=255;
        dwtype=0;
        RegQueryValueEx(hkValueKey,L"InstallLocation",0,&dwtype,(LPBYTE)SoftInfo.szSoftInsPath,&dwNameLen);//安装路径
        dwNameLen=255;
        dwIndex++;
        m_VecSoftInfo.push_back(SoftInfo);
      }
    }
    


  • 启动项管理:
  •                  这里里面最难的就是那个ListControl自绘,我们要在相应行创建按钮并响应相关消息
    处理这个消息。其实写完了回头看,就会有种并不是很难的感觉。 这个有明显BUG就是切换界面并不刷新界面,当然了 这个程序软件有很多很多BUG,细节处理的问题或其它,毕竟只做5天,也没时间在做下去了,要开始下个阶段的学习了
    void StartupManager::initListBox()
    {
      LONG nRet=RegOpenKeyEx(RootKey,lpStartupSubKey,0,KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,&hkStartupResult);
      if (nRet!=ERROR_SUCCESS)
      {
        return ;
      }
    
      DWORD dwIndex=0;
      //循环遍历子键
      while (true)
      {
        
        DWORD dwKeyLen=MAX_KEY_LENGTH;
    
        nRet=RegEnumValue(hkStartupResult,dwIndex,info.szNewKeyName,&dwKeyLen,NULL,NULL,(PBYTE)info.szNewValueName,&dwKeyLen);
        if (nRet!=ERROR_SUCCESS)
        {
          break;    //可断点检查相应错误
        }
        TCHAR SynthesisStr[2048];    //合成字符串
        _stprintf_s(SynthesisStr,_T("[%s]%s"),info.szNewKeyName,info.szNewValueName);
        m_StartupListCtrl.InsertItem(dwIndex,SynthesisStr);
        m_StartupListCtrl.createItemButton(dwIndex, 
                          2,    //点击按钮(在第二例)处理的值  未做
                          this->GetSafeHwnd() );    //创建按钮
        dwIndex++;
        m_VecStartupInfo.push_back(info);    
      }
      RegCloseKey(hkStartupResult);
    
    }
    

  • 垃圾清理:
  •                  这里用到2个最主要的关键函数SHDeleteKey()及SHDeleteValue()和其它删除函数用法主要是传路径设置好权限该false的false 该NULL的NULL。也应该没什么太大的难度
    CleanSpace.h     CleanSpace.cpp
    /**清理垃圾回收站*/
    VOID CleanSpace::CleanRubbishStation()
    {
      SHEmptyRecycleBin(NULL, NULL, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
    }
    /**清理运行记录*/
    VOID CleanSpace::CleanRunHistory()
    {
      SHDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU"));
    }
    
    /**清理文档记录*/
    VOID CleanSpace::CleanDocumentHistory()
    {
      CString strPath;                           
    
      BOOL bSuccess = SHGetSpecialFolderPath(NULL, strPath.GetBuffer(MAX_PATH), CSIDL_RECENT, FALSE);
      strPath.ReleaseBuffer();
      if (bSuccess)
      {
        EmptyDirectory(strPath);
      }
    
      SHDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs"));
    }
    /**清理上次用户登录记录*/
    VOID CleanSpace::CleanPrevUserHistory()
    {
      SHDeleteValue(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), 
        TEXT("DefaultUserName"));
      SHDeleteValue(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), 
        TEXT("AltDefaultUserName"));
      SHDeleteValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Winlogon"), 
        TEXT("DefaultUserName"));
    }
    

  • 内存优化:
  •                  我们在这清理内存并获得占用内存 关键代码也就几句吧。
    void MemoryOptimizer::ClenMemory()
    {
      MEMORYSTATUSEX stcMemStatusEx={};
      stcMemStatusEx.dwLength=sizeof(stcMemStatusEx);
      GlobalMemoryStatusEx(&stcMemStatusEx);
      DWORDLONG preUsedMem=stcMemStatusEx.ullTotalPhys-stcMemStatusEx.ullAvailPhys;
      m_Memzhanyong =(double)preUsedMem/1024/1024/1000;
    
      hh.Format(L"%0.2lf",m_Memzhanyong);
      //清理内存
      DWORD dwPIDList[1000]={0};
      DWORD bufSize=sizeof(dwPIDList);
      DWORD dwNeedSize=0;
      EnumProcesses(dwPIDList,bufSize,&dwNeedSize);
      for (DWORD i=0;i<dwNeedSize/sizeof(DWORD);i++)
      {
        HANDLE hProcess=OpenProcess(  PROCESS_SET_QUOTA,false,dwPIDList[i]);
        SetProcessWorkingSetSize(hProcess,-1,-1);
      }
      // 获取清理后的内存状态
      GlobalMemoryStatusEx(&stcMemStatusEx);
      DWORDLONG afterCleanUsedMem=stcMemStatusEx.ullTotalPhys-stcMemStatusEx.ullAvailPhys;
      m_delMemory=(preUsedMem-afterCleanUsedMem)/1024/1024;    //已删除内存
      hd.Format(L"%d",m_delMemory);
    
    
    }
    



    其它诸如:
    按钮自绘:
    ImageButton.h    ImageButton.cpp     全部
    
    ListControl按钮自绘:
    ListButton.h     ListButton.cpp            应用在启动项管理
    MyListCtrl.h      MyListCtrl.cpp            应用在启动项管理
    
    ListControl自绘 :
    ListCtrl.h     ListCtrl.cpp    应用在服务启动及软件卸载
    
    MD5值计算:
    Md5.h     Md5.cpp              网上开源  应用在病毒查杀
    
    flash控件:
    shockwaveflash1.h     shockwaveflash1.cpp  创建flash控件自动生成  应用在内存优化
    
    combo box控件:
    MyListBox.h     MyListBox.cpp         自绘失败 MyListCtrl与ListButton代替  不过代码未删
    
    TabControl控件:
    TabControl.h     TabControl.cpp     这个就不用多说啦  其实第二天我想放弃的 但是整个框架都搭建好了 又由于时间不够  我就放弃了 其实这个地方可以做成腾讯电脑管家下方显示的样式
    
    好了 应该都介绍完了。
    


     版主大大能给个优秀精华就好了 哈哈

    这几天做的挺累的  下午饭都不吃在教室写  晚上叫外卖 然后 晚上9:30下课 有俩天到了10点半左右我还在加班  然后回宿舍被宿舍阿姨关在外面 使劲按门铃才给开  好忧伤。。。
    现在在北京 过年回深圳


    待会上传源码吧 我休息会儿  编辑了大半个小时

    ---------------------------------------
    源码(分卷) :
    电脑管家.part01.rar
    电脑管家.part02.rar
    电脑管家.part03.rar
    电脑管家.part04.rar
    电脑管家.part05.rar
    百度云盘:
    【源码】链接: http://pan.baidu.com/s/1ntjGTlf密码: 4f1n
    【资源】链接:http://pan.baidu.com/s/1qOTD8 密码: hbi8

    有的资源单个3、4MB我都直接用了。。造成程序很大。你们也可以不用 反正资源这个东西可以随便改
    转载注明出处

    [培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

    上传的附件:
    收藏
    免费 4
    支持
    分享
    最新回复 (43)
    雪    币: 2422
    活跃值: (3578)
    能力值: ( LV9,RANK:140 )
    在线值:
    发帖
    回帖
    粉丝
    2
    这种界面不乱吗。。
    2015-11-14 15:32
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    3
    哈哈 主要爱火影  这个也并不是真正给用户去用的      无伤大雅了
    2015-11-14 15:51
    0
    雪    币: 341
    活跃值: (133)
    能力值: ( LV7,RANK:110 )
    在线值:
    发帖
    回帖
    粉丝
    4
    我感觉里面男男女女躺着的关系挺乱的哈哈哈。没看过火影不懂
    2015-11-14 15:56
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    5
    哈哈  没看过火影的的确会有这种感觉
    我老师 第一次看的反应是:"我擦 这么色情。。。。。"
    2015-11-14 16:00
    0
    雪    币: 16444
    活跃值: (2463)
    能力值: ( LV9,RANK:147 )
    在线值:
    发帖
    回帖
    粉丝
    6
    主要是佐助看起来好....其它都比较正常
    2015-11-14 16:03
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    7
    嗯 没有那种冷冽的气质 反而...
    2015-11-14 16:09
    0
    雪    币: 62
    活跃值: (52)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    8
    楼主,有进程防火墙功能么?

    如打开QQLIVE,这货老在右下角提示电脑速度慢,垃圾需要清理神马的

    限制这种程序启动
    2015-11-14 16:20
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    9
    方法一 下载ADSAFE
    方法二 就是不用它时候禁用网络
    方法二 写个程序禁止 可以从注册表或进程入手
    2015-11-14 17:00
    0
    雪    币: 8865
    活跃值: (2379)
    能力值: ( LV12,RANK:760 )
    在线值:
    发帖
    回帖
    粉丝
    10
    火影...充界面顶了~!
    2015-11-14 17:43
    0
    雪    币: 359
    活跃值: (809)
    能力值: ( LV4,RANK:50 )
    在线值:
    发帖
    回帖
    粉丝
    11
    支持开源精神了。。
    火影很好看啊;~~同道中人;我刚入行快半年了。
    2015-11-14 22:06
    0
    雪    币: 62
    活跃值: (52)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    12
    电脑上的腾讯视频,不让他联网?这个广告是腾讯视频后台下载的一个程序启动后的界面,忽悠你点击后下载腾讯全家桶,ADSAFE是拦不下的。

    所以,真正有用的是HOOK CreateProcessInternalW,这类程序启动时禁止

    想自己写又功力不够
    2015-11-15 10:12
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    13
    嘿嘿 感谢V校
    2015-11-15 11:23
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    14
    不用的时候禁止它联网呗  
    或者细致一点来讲 一般软件开启都有几个进程 然后有一个进程是专门负责弹窗广告的 把它干掉

    具体来写 我是没时间的
    2015-11-15 11:33
    0
    雪    币: 14
    活跃值: (73)
    能力值: ( LV2,RANK:15 )
    在线值:
    发帖
    回帖
    粉丝
    15
    界面代码比查杀代码要好,MD5值检测让我感觉有点时空穿越的感觉,用fastcoll就可以了.还不如取特征值来的实在.
    2015-11-15 11:58
    0
    雪    币: 6890
    活跃值: (8944)
    能力值: ( LV17,RANK:797 )
    在线值:
    发帖
    回帖
    粉丝
    16
    你单独发你的杀毒软件的核心或许比较受欢迎,整个项目太大了。
    2015-11-15 15:49
    0
    雪    币: 69
    活跃值: (242)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    wmg
    17
    杀毒软件现在没那么火了
    2015-11-15 22:24
    0
    雪    币: 86
    活跃值: (10)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    18
    拿来学习一下
    2015-11-16 22:22
    0
    雪    币: 201
    活跃值: (10)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    19
    不错挺好
    2015-11-26 14:33
    0
    雪    币: 58
    活跃值: (72)
    能力值: ( LV5,RANK:70 )
    在线值:
    发帖
    回帖
    粉丝
    20
    不错,鼓励下。
    2015-11-27 11:26
    0
    雪    币: 6
    活跃值: (19)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    21
    谢谢楼主分享技术贴。
    2015-11-27 12:31
    0
    雪    币: 74
    活跃值: (703)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    22
    mark,学习下
    2015-11-27 13:06
    0
    雪    币: 11
    活跃值: (10)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    23
    郁闷用vs2012编译源码时报如下错误,
    >C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(1268,5): error MSB6006: “rc.exe”已退出,代码为 27。
    3>  注册.vcxproj -> C:\Users\Admin\Desktop\电脑管家\Debug\注册.exe
    2015-12-9 15:00
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    24
    资源丢失 你是不是没下载资源
    2015-12-9 15:09
    0
    雪    币: 11
    活跃值: (10)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    25
    您说的资源指的是您上传的那资源压缩包吗,如果是,那解压后怎么放在源代码目录里然后进行编译呢,
    2015-12-9 15:46
    0
    游客
    登录 | 注册 方可回帖
    返回
    //