如何使用C ++列出Windows中的子目录?我需要单独使用Windows API的解决方案

时间:2014-01-09 14:10:37

标签: c++ winapi

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365200%28v=vs.85%29.aspx。我刚刚看到这个链接,这个程序将单独打印目录。如何在这个程序中实现一个代码,它还将显示所有子目录?请你以代码的形式提供解决方案。

 #include <windows.h>
    #include <tchar.h> 
    #include <stdio.h>
    #include <strsafe.h>
    #pragma comment(lib, "User32.lib")

    void DisplayErrorBox(LPTSTR lpszFunction);

    int _tmain(int argc, TCHAR *argv[])
    {
       WIN32_FIND_DATA ffd;
       LARGE_INTEGER filesize;
       TCHAR szDir[MAX_PATH];
       size_t length_of_arg;
       HANDLE hFind = INVALID_HANDLE_VALUE;
       DWORD dwError=0;

       // If the directory is not specified as a command-line argument,
       // print usage.

       if(argc != 2)
       {
          _tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
          return (-1);
       }

       // Check that the input path plus 3 is not longer than MAX_PATH.
       // Three characters are for the "\*" plus NULL appended below.

       StringCchLength(argv[1], MAX_PATH, &length_of_arg);

       if (length_of_arg > (MAX_PATH - 3))
       {
          _tprintf(TEXT("\nDirectory path is too long.\n"));
          return (-1);
       }

       _tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);

       // Prepare string for use with FindFile functions.  First, copy the
       // string to a buffer, then append '\*' to the directory name.

       StringCchCopy(szDir, MAX_PATH, argv[1]);
       StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

       // Find the first file in the directory.

       hFind = FindFirstFile(szDir, &ffd);

       if (INVALID_HANDLE_VALUE == hFind) 
       {
          DisplayErrorBox(TEXT("FindFirstFile"));
          return dwError;
       } 

       // List all the files in the directory with some info about them.

       do
       {
          if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
          {
             _tprintf(TEXT("  %s   <DIR>\n"), ffd.cFileName);
          }
          else
          {
             filesize.LowPart = ffd.nFileSizeLow;
             filesize.HighPart = ffd.nFileSizeHigh;
             _tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
          }
       }
       while (FindNextFile(hFind, &ffd) != 0);

       dwError = GetLastError();
       if (dwError != ERROR_NO_MORE_FILES) 
       {
          DisplayErrorBox(TEXT("FindFirstFile"));
       }

       FindClose(hFind);
       return dwError;
    }


    void DisplayErrorBox(LPTSTR lpszFunction) 
    { 
        // Retrieve the system error message for the last-error code

        LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
        DWORD dw = GetLastError(); 

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );

        // Display the error message and clean up

        lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
            (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
        StringCchPrintf((LPTSTR)lpDisplayBuf, 
            LocalSize(lpDisplayBuf) / sizeof(TCHAR),
            TEXT("%s failed with error %d: %s"), 
            lpszFunction, dw, lpMsgBuf); 
        MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

        LocalFree(lpMsgBuf);
        LocalFree(lpDisplayBuf);
    }

1 个答案:

答案 0 :(得分:0)

下面示例的快速工作黑客(需要额外的命令行参数-r)。工作直到路径超过MAX_PATH。用这两个函数替换样本中的main。请注意检查不要递归“。”和“......”。这永远不会结束:)你不必重命名_tmain,但是没有在哪里放置一个断点来结束。

int modified_main(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA ffd;
   LARGE_INTEGER filesize;
   TCHAR szDir[MAX_PATH];
   TCHAR szSubDir[MAX_PATH];// 260 bytes
   TCHAR* temp_argv[3];
   size_t length_of_arg;
   HANDLE hFind = INVALID_HANDLE_VALUE;
   DWORD dwError=0;
   BOOL recursive = FALSE;
   // If the directory is not specified as a command-line argument,
   // print usage.

   if(argc < 2)
   {
      _tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
      return (-1);
   }

   if( (argc > 2) && 
       (('-' == argv[2][0]) && 
        ('r' == argv[2][1])) )
   {
      recursive = TRUE;
   }
   // Check that the input path plus 3 is not longer than MAX_PATH.
   // Three characters are for the "\*" plus NULL appended below.

   StringCchLength(argv[1], MAX_PATH, &length_of_arg);

   if (length_of_arg > (MAX_PATH - 3))
   {
      _tprintf(TEXT("\nDirectory path is too long.\n"));
      return (-1);
   }

   _tprintf(TEXT("\nBegin directory : %s\n\n"), argv[1]);

   // Prepare string for use with FindFile functions.  First, copy the
   // string to a buffer, then append '\*' to the directory name.

   StringCchCopy(szDir, MAX_PATH, argv[1]);
   StringCchCat(szDir, MAX_PATH, TEXT("\\*"));


   // Find the first file in the directory.

   hFind = FindFirstFile(szDir, &ffd);

   if (INVALID_HANDLE_VALUE == hFind) 
   {
      DisplayErrorBox(TEXT("FindFirstFile"));
      return dwError;
   } 

   // List all the files in the directory with some info about them.

   do
   {
      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
         _tprintf(TEXT("  %s   <DIR>\n"), ffd.cFileName);

         if((recursive) && (ffd.cFileName[0]!='.'))
         {
            _sntprintf(szSubDir,MAX_PATH,_T("%s\\%s"),argv[1],ffd.cFileName);
            temp_argv[0]=argv[0];
            temp_argv[1]=szSubDir;/* new dir*/
            temp_argv[2]=_T("-r");
            modified_main(3,temp_argv);
         }
      }
      else
      {
         filesize.LowPart = ffd.nFileSizeLow;
         filesize.HighPart = ffd.nFileSizeHigh;
         _tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
      }
   }
   while (FindNextFile(hFind, &ffd) != 0);



   dwError = GetLastError();
   if (dwError != ERROR_NO_MORE_FILES) 
   {
      DisplayErrorBox(TEXT("FindFirstFile"));
   }

   FindClose(hFind);

   _tprintf(TEXT("\End directory : %s\n\n"), argv[1]);
   return dwError;
}




int _tmain(int argc, TCHAR *argv[])
{
   return modified_main(argc, argv);
}