2014-08-08 一期笔记

#include "StdAfx.h"
#include "LjlFile.h"
#include <ShellAPI.h>
#include <io.h>
#include <vector>

CLjlFile::CLjlFile(void)
{
 flag=0;
}

CLjlFile::~CLjlFile(void)
{
}


/*!< 递归删除非空目录 */
void CLjlFile::delDirectory(CString strDir)
{
 if(strDir.IsEmpty())
 {
  return;
 }

 /*!< 首先删除文件及子文件夹 */
 CFileFind finder;

 BOOL bFound = finder.FindFile(strDir + L"\\*", 0);
 while(bFound)
 {
  bFound = finder.FindNextFile();
  if(finder.IsDots()) /*!< 是"."或".." */
  {
   continue;
  }

  /*!< 去掉文件(夹)只读等属性 */
  if(finder.IsReadOnly())
  {
   SetFileAttributes(finder.GetFilePath(), FILE_ATTRIBUTE_NORMAL);
  }

  if(finder.IsDirectory())
  {
   delDirectory(finder.GetFilePath());
   RemoveDirectory(finder.GetFilePath());
  }
  else
  {
   DeleteFile(finder.GetFilePath());
  }
 }
 finder.Close();
 RemoveDirectory(strDir);
}


/*!< 递归创建多级目录 */
#define  DIR_NAME_LENGTH 256

void CLjlFile::CreateMyFolder ( CString strFolderPath_t )
{
 wchar_t* strFolderPath;
 strFolderPath = strFolderPath_t.GetBuffer(0);
 TCHAR szDirName[DIR_NAME_LENGTH] = { 0 };
 TCHAR* pData = strFolderPath ;
 TCHAR* pszTemp = szDirName;
 CString str;
 str.Find(L"\\");
 
 while( *pData ) /*!< 递归创建多级目录 */
 {
  if ( ( '\\' == *pData ) || ( '/' == *pData ) )
  {
   if ( ':' != *( pData - 1 ) )
   {
    CreateDirectory( szDirName, NULL );// 依次创建一级目录
   }
  }            

  *pszTemp++ = *pData++;
  *pszTemp = '\0';
 }            

 CreateDirectory( szDirName, NULL );
}

/*!< 复制source中的内容到target中 */
void CLjlFile::myCopyDirectoryFiles(CString source, CString target) 

 CreateDirectory(target, NULL); /*!< 创建目标文件夹 */
 CFileFind finder; 
 CString path; 

 path.Format(L"%s/*.*", source); 
 BOOL bWorking = (BOOL)finder.FindFile(path);

 while(bWorking)
 { 
  bWorking = finder.FindNextFile();

  if(finder.IsDirectory() && !finder.IsDots())  //是文件夹 而且 名称不含 . 或 ..
  { 
   myCopyDirectoryFiles(finder.GetFilePath(), target + L"/" + finder.GetFileName()); //递归创建文件夹+"/"+finder.GetFileName() 
  } 
  else  //是文件,则直接复制
  {  
   CopyFile(finder.GetFilePath(), target + L"/" + finder.GetFileName(), FALSE); 
  }
 } 
}

/*************************************************************************
                proe安装目录检查,若未安装到标准目录,提示用户及修改                            
*************************************************************************/
void CLjlFile::myCheckDirectoryFiles(CString CheckPath, CString& info)
{
 CFileFind finderfiles;
 CString finderpath;

 finderpath.Format(L"%s/*.*", CheckPath); 
 BOOL bWorking = (BOOL)finderfiles.FindFile(finderpath);
 
 if (bWorking)
 {
  info = L"正确";
 }
 else
 {
  info = L"未安装到标准目录";
 }
 return;
}

void CLjlFile::myCheckDirectoryFiles_Modify(CString CheckPath, CString CopyPath, CString info)
{
 if (info == L"正确")
 {
  return;
 }
 CreateMyFolder(CheckPath);
 myCopyDirectoryFiles(CopyPath, CheckPath);
}

/************************************************************************
                  比较两列内容  config.pro启动项检查                        
************************************************************************/
std::vector<CString> vacbegin1;   // 存储第一个文本的第一列
std::vector<CString> vacbegin2;   // 存储第一个文本的第二列
std::vector<CString> vacend1;     // 存储第二个文本的第一列
std::vector<CString> vacend2;     // 存储第二个文本的第二列
std::vector<CString> vactotal;    // 存储第一个文本的一二两列
std::vector<int> m_spacebeginarr; // 存储第一个文本每一行的末位空格数
std::vector<int> m_spaceendarr;   // 存储第二个文本每一行的末位空格数

void CLjlFile::ReadBeginTxt( CString Path)
{
 vacbegin1.clear();
 vacbegin2.clear();
 m_spacebeginarr.clear();
 int beginnum = 0;
 CString csLine, csLineEnd, textbegin, textend;
 try
 {
  CStdioFile file(Path, CFile::modeRead | CFile::typeText);
  setlocale(LC_CTYPE, "chs");

  int begintxtLine = 0;
  while(file.ReadString(csLine))
  {
   if (csLine =="")
   {
    vacbegin1.push_back(L"`");
    vacbegin2.push_back(L"`");
    m_spacebeginarr.push_back(beginnum);
   }
   else
   {
    CString m_spacebegin = csLine;
    int m_spacebegincount = 0;

    while (m_spacebegin.Right(1) == " ")
    {
     m_spacebegincount++;
     m_spacebegin = m_spacebegin.Left(csLine.GetLength()-1);
     csLine = m_spacebegin;
    }

    if ((csLine.Find(L"!") != -1) || (csLine.Find(L"def_layer") != -1) || (csLine.Find(L"mapkey") != -1))
    {
     vacbegin1.push_back(L"`");
     vacbegin2.push_back(L"`");
     m_spacebeginarr.push_back(beginnum);
     continue;
    }

    int lineLenth = (int)wcslen(csLine);
    int nfrist = csLine.Find(L" "); 
    int i = 0;
    while(1)
    {
     if(nfrist != -1)
     {
      textbegin = csLine.Left(nfrist);

      if (i == 0 && !textbegin.IsEmpty())
      {
       vacbegin1.push_back(textbegin);
       i++;
      }

      textbegin = csLine.Right(lineLenth-nfrist-1); //减掉 1 为了去掉空格
      csLine = textbegin;
      if (csLine == "")
      {
       break;
      }
      nfrist = csLine.Find(L" ");
      lineLenth = csLine.GetLength();
     }
     else
     {
      vacbegin2.push_back(textbegin);
      break;
     }
    }

    //m_spacebeginarr[begintxtLine] = m_spacebegincount;
    m_spacebeginarr.push_back(m_spacebegincount);
    begintxtLine++;
   }
  }
  file.Close();
 }
 catch(...)
 {  
  AfxMessageBox(L"打开文件错");
 }
}

void CLjlFile::ReadEndTxt(CString Path)
{
 vacend1.clear();
 vacend2.clear();
 m_spaceendarr.clear();
 int endnum = 0;
 CString csLine, csLineEnd, textbegin, textend;
 try
 {
  CStdioFile file(Path, CFile::modeRead | CFile::typeText);
  setlocale(LC_CTYPE, "chs");

  int endtxtLine = 0;
  while(file.ReadString(csLine))
  {
   if (csLine == "")
   {
    continue;
   }
   CString m_spacebegin = csLine;
   int m_spaceendcount = 0;
   while (m_spacebegin.Right(1) == " ")
   {
    m_spaceendcount++;
    m_spacebegin = m_spacebegin.Left(csLine.GetLength()-1);
    csLine = m_spacebegin;
   }

   if ((csLine.Find(L"!") != -1) || (csLine.Find(L"def_layer") != -1) || (csLine.Find(L"mapkey") != -1))
   {
    continue;
   }

   int lineLenth = (int)wcslen(csLine);
   int nfrist = csLine.Find(L" "); 
   int i = 0;
   while(1)
   {
    if(nfrist != -1)
    {
     textbegin = csLine.Left(nfrist);


     if (i == 0 && !textbegin.IsEmpty())
     {
      vacend1.push_back(textbegin);
      i++;
     }

     textbegin = csLine.Right(lineLenth-nfrist-1); //减掉 1 为了去掉空格
     csLine = textbegin;
     if (csLine == "")
     {
      break;
     }
     nfrist = csLine.Find(L" ");
     lineLenth = csLine.GetLength();
    }
    else
    {
     vacend2.push_back(textbegin);
     break;
    }
   }
   //m_spaceendarr[endtxtLine] = m_spaceendcount;
   m_spaceendarr.push_back(m_spaceendcount);
   endtxtLine++;
  }
  file.Close();
 }
 catch(...)
 {  
  AfxMessageBox(L"打开文件错");
 }
}

void CLjlFile::ReadBeginTotalTxt(CString Path)
{
 vactotal.clear();
 CString csLine;
 try
 {
  CStdioFile file( Path, CFile::modeRead | CFile::typeText );
  setlocale(LC_CTYPE, "chs");

  while(file.ReadString(csLine))
  {
   vactotal.push_back(csLine);
  }
  file.Close();
 }
 catch(...)
 {  
  AfxMessageBox(L"打开文件错");
 }
}

void CLjlFile::ReadBeginEndTxtCompare()
{
 for (int k = 0; k < (int)vacend1.size(); k++)
 {
  for (int i = 0; i < (int)vactotal.size(); i++)
  {
   if (vactotal[i] == "")
   {
    continue;
   }

   if ((vactotal[i].Find(L"!") != -1) || (vactotal[i].Find(L"def_layer") != -1) || (vactotal[i].Find(L"mapkey") != -1))
   {
    continue;
   }
   if ( !wcscmp(vacbegin1[i], vacend1[k]))
   {
    if (!wcscmp(vacbegin2[i], vacend2[k]))
    {
     continue;
    }
    else
    {
     
     CString LeftString = vactotal[i].Left(vactotal[i].GetLength() - vacbegin2[i].GetLength() - m_spacebeginarr[i]);
     CString str;
     str.Format(L"%s%s", LeftString, vacend2[k]);
     while (m_spaceendarr[i])
     {
      str += L" ";
      m_spaceendarr[i]--;
     }
     vactotal[i].Replace(vactotal[i], str);
    }
   }
  }
 }
}

/*!< 写容器内容到文件中*/
void CLjlFile::WriteBeginTxtFinal( CString m_BeginPath )
{
 CString csLine;
 CStdioFile files(m_BeginPath, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
 setlocale(LC_CTYPE, "chs");

 for (int j = 0; j < (int)vactotal.size(); j++)
 {
  if ( j < (int)vactotal.size() - 1 )
  {
   vactotal[j] += "\n";
  }
  files.Seek(0, CFile::end);
  files.WriteString(vactotal[j]); 
 }
 files.Flush();
 files.Close();
 //AfxMessageBox(L"更新完成!");
}

void CLjlFile::ReadBeginEndTxtCompare(CString& info)
{
 for (int k = 0; k < (int)vacend1.size(); k++)
 {
  for (int i = 0; i < (int)vactotal.size(); i++)
  {
   if (vactotal[i] == "")
   {
    continue;
   }

   if ((vactotal[i].Find(L"!") != -1) || (vactotal[i].Find(L"def_layer") != -1) || (vactotal[i].Find(L"mapkey") != -1))
   {
    continue;
   }
   if ( !wcscmp(vacbegin1[i], vacend1[k]))
   {
    if (!wcscmp(vacbegin2[i], vacend2[k]))
    {
     info = L"正确";
     continue;
    }
    else
    {
     info = L"与标准启动项不匹配";
     return;
    }
   }
  }
 }
}

void CLjlFile::WriteBeginTxtFinal_Modify(CString m_BeginPath, CString info)
{
 if (wcscmp(info, L"正确"))
 {
  ReadBeginEndTxtCompare();
  WriteBeginTxtFinal(m_BeginPath);
 }
}

/************************************************************************/
/*                            获取文件的信息                                   */
/************************************************************************/
void CLjlFile::myCheckedFileInformation( CString source, CString dest, CString FileName )
{
 CFileFind sourcefinder;
 CFileFind destfinder; 
 CString sourcepath, destpath, readpath, writepath;

 CString source_File_Time;
 ULONGLONG source_File_Size;
 CTime source_time_value;
 CString dest_File_Time;
 ULONGLONG dest_File_Size;
 CTime dest_time_value;
 int k = 0;


 sourcepath.Format(L"%s\\*.*", source);
 destpath.Format(L"%s\\*.*", dest);
 readpath.Format(L"%s\\%s", dest, FileName);
 writepath.Format(L"%s\\%s", source, FileName);

 ReadBeginTotalTxt(readpath);

 BOOL destWorking = (BOOL)destfinder.FindFile(destpath);
 while (destWorking)
 {
  destWorking = destfinder.FindNextFile();
  CString m_dest_FileName = destfinder.GetFileName();
  if (m_dest_FileName == FileName)
  {
   destfinder.GetLastWriteTime(dest_time_value);
   dest_File_Size = destfinder.GetLength();
   break;
  }
 }

 BOOL sourceWorking = (BOOL)sourcefinder.FindFile(sourcepath);
 while(sourceWorking)
 { 
  sourceWorking = sourcefinder.FindNextFile();
  CString m_FileName = sourcefinder.GetFileName();
  
  if (m_FileName != FileName)
  {
   continue;
  }

  sourcefinder.GetLastWriteTime(source_time_value);
  source_File_Size = sourcefinder.GetLength();

  if ((source_File_Size != dest_File_Size) || (source_time_value != dest_time_value))
  {
   k = AfxMessageBox(L"与标准文件不匹配,是否覆盖?", MB_OKCANCEL);
   switch(k)
   {
   case 1:
    WriteBeginTxtFinal(writepath);
    break;
   case 2:
    break;
   default:
    break;
   }
  }
  return ;
 }
 k = AfxMessageBox(L"没有所需要的文件,是否复制标准文件?", MB_OKCANCEL);
 switch(k)
 {
 case 2:
  break;
 case 1:
  //WriteBeginTxtFinal(writepath);
  CopyFile(readpath, writepath, FALSE);
  break;
 default:
  break;
 }
 return ;
}

void CLjlFile::myCheckedFileInformation( CString source, CString dest, CString FileName, CString& info )
{
 CFileFind sourcefinder;
 CFileFind destfinder; 
 CString sourcepath, readpath, writepath;

 CString source_File_Time;
 ULONGLONG source_File_Size;
 CTime source_time_value;
 CString dest_File_Time;
 ULONGLONG dest_File_Size;
 CTime dest_time_value;
 int k = 0;
 info = L"正确";


 sourcepath.Format(L"%s\\*.*", source);
 readpath.Format(L"%s\\%s", dest, FileName);
 writepath.Format(L"%s\\%s", source, FileName);

 BOOL destWorking = (BOOL)destfinder.FindFile(readpath);
 if (destWorking)
 {
  destfinder.GetLastWriteTime(dest_time_value);
  dest_File_Size = destfinder.GetLength();
 }

 BOOL sourceWorking = (BOOL)sourcefinder.FindFile(sourcepath);
 while(sourceWorking)
 { 
  sourceWorking = sourcefinder.FindNextFile();
  CString m_FileName = sourcefinder.GetFileName();

  if (m_FileName != FileName)
  {
   continue;
  }

  sourcefinder.GetLastWriteTime(source_time_value);
  source_File_Size = sourcefinder.GetLength();

  if ((source_File_Size != dest_File_Size) || (source_time_value != dest_time_value))
  {
   info = L"与标准文件不匹配";
   return;
  }
 }
 info = L"没有所需要的文件";
 return ;
}

void CLjlFile::myCheckedFileInformation_Modify( CString source, CString dest, CString FileName, CString info )
{
 CString readpath, writepath;
 readpath.Format(L"%s\\%s", dest, FileName);
 writepath.Format(L"%s\\%s", source, FileName);

 if (!wcscmp(info, L"正确"))
 {
  return;
 }
 else if (!wcscmp(info, L"与标准文件不匹配"))
 {
  ReadBeginTotalTxt(readpath);
  WriteBeginTxtFinal(writepath);
 }
 else if (!wcscmp(info, L"没有所需要的文件"))
 {
  CopyFile(readpath, writepath, FALSE);
 }
 return;
}

/*!< MDS文件目录检查 */
std::vector<CString> vaccheckpath; // 存储不标准文件路径
std::vector<CString> vacrightpath; // 存储标准文件路径
std::vector<CString> vacdifferentpath; // 存储与标准文件不同的文件路径

void CLjlFile::myCheckedSourceDirectoryFiles( CString source, CString m_source, CString& info)
{
 CFileFind finder; 
 CString path, strcatstring; 

 path.Format(L"%s/*.*", source); 
 BOOL bWorking = (BOOL)finder.FindFile(path);

 if (bWorking == 0)
 {
  info = L"路径不存在";
  return;
 }
 while(bWorking)
 { 
  bWorking = finder.FindNextFile();

  if (!finder.IsDots() && finder.IsDirectory())
  {
   myCheckedSourceDirectoryFiles(finder.GetFilePath(), m_source, info);
  }
  else
  {
   int m_len = m_source.GetLength();
   int len = source.GetLength();
   strcatstring = source.Right(len - m_len - 1);
   if (!wcscmp(source, m_source))
   {
    vaccheckpath.push_back(finder.GetFileName());
   }
   else
   {
    vaccheckpath.push_back(strcatstring + L"\\" + finder.GetFileName());
   }
  }
 }
}

void CLjlFile::myStatusTargetDirectoryFiles( CString target, CString m_target )
{
 CFileFind finder; 
 CString path, strcatstring; 

 path.Format(L"%s/*.*", target); 
 BOOL bWorking = (BOOL)finder.FindFile(path);

 while(bWorking)
 { 
  bWorking = finder.FindNextFile();

  if (!finder.IsDots() && finder.IsDirectory())
  {
   myStatusTargetDirectoryFiles(finder.GetFilePath(), m_target);
  }
  else
  {
   int m_len = m_target.GetLength();
   int len = target.GetLength();
   strcatstring = target.Right(len - m_len - 1);
   if (!wcscmp(target, m_target))
   {
    vacrightpath.push_back(finder.GetFileName());
   }
   else
   {
    vacrightpath.push_back(strcatstring + L"\\" + finder.GetFileName());
   }
  }
 }
}

void CLjlFile::myCopyFilesCompareToChecked( CString source, CString target )
{
 for (int i = 0; i < (int)vacdifferentpath.size(); i ++)
 {
  CString path, strcatstring; 

  path.Format(L"%s\\%s", source, vacdifferentpath[i]); 

  int npos = path.Find(L"\\");
  while (npos != -1)
  {
   strcatstring += path.Left(npos) + L"\\";
   path = path.Right(path.GetLength() - npos - 1);
   npos = path.Find(L"\\");
  }

  CreateMyFolder(strcatstring);
  CopyFile(target + L"\\" + vacdifferentpath[i], source + L"\\" + vacdifferentpath[i], FALSE);
 }
}

/*************************************************************
   MDS文件目录检查,是否缺少某些文件
*************************************************************/
void CLjlFile::myCheckedAndStatusDirectoryFilesCompare( CString source, CString m_source, CString target, CString m_target, CString& info )
{
 vaccheckpath.clear();
 vacrightpath.clear();

 myCheckedSourceDirectoryFiles(source, m_source, info);
 myStatusTargetDirectoryFiles(target, m_target);

 if (wcscmp(info, L"路径不存在"))
 {
  for (int status = 0; status < (int)vacrightpath.size(); status ++)
  {
   for (int checkcount = 0; checkcount < (int)vaccheckpath.size(); checkcount ++)
   {
    if (!wcscmp(vaccheckpath[checkcount], vacrightpath[status]))
    {
     break;
    }
    if ((wcscmp(vaccheckpath[checkcount], vacrightpath[status])) && (checkcount < (int)vaccheckpath.size() - 1))
    {
     continue;
    }
    if ((wcscmp(vaccheckpath[checkcount], vacrightpath[status])) && (checkcount = (int)vaccheckpath.size() - 1))
    {
     vacdifferentpath.push_back(vacrightpath[status]);
    }
   }
  }

  if ( vacdifferentpath.empty() )
  {
   info = L"正确";  
  }
  else
  {
   info = L"与标准路径不匹配";
  }
  return;
 }
}

void CLjlFile::myCheckedAndStatusDirectoryFilesCompare_Modify( CString source, CString target, CString info )
{
 if (!wcscmp(info, L"路径不存在"))
 {
  CreateMyFolder(source);
  myCopyDirectoryFiles(target, source);
  return;
 }
 if (!wcscmp(info, L"正确"))
 {
  return;
 }
 if (!wcscmp(info, L"与标准路径不匹配"))
 {
  myCopyFilesCompareToChecked(source, target);
 }
}

/***********************************************************
 检查MDA服务器名称 // hwnd 传参为 this->GetSafeHwnd()
***********************************************************/
void CLjlFile::myCheckMDAServersPath(CString& Path, HWND hwnd)
{
 TCHAR MyDir[MAX_PATH];

 SHGetSpecialFolderPath(hwnd, MyDir, CSIDL_APPDATA, 0);
 Path.Format(L"%s\\PTC\\ProENGINEER\\Wildfire\\.wf\\.Settings\\config.fld", MyDir);
}

void CLjlFile::myCheckMDAServersName( CString Path, CString& info )
{
 ReadBeginTotalTxt(Path); /*!< 将内容读到vactotal容器中*/

 for ( int i = 0; i < (int)vactotal.size(); i ++ )
 {
  CString str = L"label=";
  CString statusstr = L"\"mda\" ";
  int str_len = str.GetLength();
  if ( ( vactotal[i].Find(L"servers_nodes_info_ENTRY") != -1 ) && ( vactotal[i].Find(str) != -1 ) )
  {
   CString strcatstring, str_left, str_right;
   int npos = vactotal[i].Find( str );
   strcatstring = vactotal[i].Left( npos + str_len );
   str_right = vactotal[i].Right( vactotal[i].GetLength() - str_len - npos );
   npos = str_right.Find(L"online=");
   str_left = str_right.Left( npos );
   str_right = str_right.Right( str_right.GetLength() - npos );
   if ( str_left != statusstr )
   {
    info = L"MDA服务名器称不正确";
    vactotal[i] = strcatstring + statusstr + str_right ;
   }
   else
   {
    info = L"正确";
   }
  }
 }
}

void CLjlFile::myCheckMDAServersName_Modify( CString Path, CString info )
{
 if (!wcscmp(info, L"MDA服务名器称不正确"))
 {
  WriteBeginTxtFinal(Path);
 }
}

/*!<获取注册表中的安装信息,检查productview插件是否正确安装 */
#define MY_BUFSIZE 132
BOOL CLjlFile::ShowProductviewInformation(CString& info)
{
 HKEY hSubKey; 
 CString pathfull;
 long lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SoftWare\\PTC\\ProductView Express"), 0, KEY_READ, &hSubKey);

 if(ERROR_SUCCESS == lResult)
 {
  TCHAR s_Executable[256] = { 0 };
  TCHAR s_InstallationPath[256] = { 0 };

  DWORD typeSZ = REG_SZ;
  DWORD typeDWORD = REG_DWORD;
  DWORD dw_Executable = MY_BUFSIZE;
  DWORD dw_InstallationPath = MY_BUFSIZE;

  if ( (::RegQueryValueEx(hSubKey, _T("Executable"), 0, &typeSZ, (LPBYTE)s_Executable, &dw_Executable) == ERROR_SUCCESS) &&
   (::RegQueryValueEx(hSubKey, _T("InstallationPath"), 0, &typeSZ, (LPBYTE)s_InstallationPath, &dw_InstallationPath) == ERROR_SUCCESS) )
  { 
   pathfull.Format(L"%sbin\\pvexpress.exe", s_InstallationPath);

   CFileFind finder;
   BOOL bWorking = finder.FindFile(pathfull);
   if (bWorking)
   {
    info = L"正确";
   }
   else
   {
    info = L"插件未正确安装";
   }
  }
  else
  {
   info = L"插件未正确安装";
  }
  RegCloseKey(hSubKey);
  return TRUE;
 }
 info = L"插件未正确安装";
 RegCloseKey(hSubKey);
 return FALSE;
}

void CLjlFile::ShowProductviewInformation_Modify(HWND hWnd, CString Path, CString info)
{
 if (!wcscmp(info, L"插件未正确安装"))
 {
  ShellExecute(hWnd, L"open", Path, NULL, NULL, SW_SHOWNORMAL);
 }
}
//ShellExecute

 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值