SetupDLL для удаления папки и реестра ключей - PullRequest
1 голос
/ 15 февраля 2011

Разработка приложения на Compact Framework. net 3.5 c # для Windows Mobile 6.x.

При удалении приложения хотелось бы удалить некоторые ключи в реестре и папку с ее содержимым.

Поиск в интернете Я познакомился с другими советами о том, как использовать проект SetupDLL Cab, и обнаружил, что мне нужно создать проект c ++, реализовать методы

Install_Init - вызывается до начала установки.

Install_Exit - вызывается после установки приложения.

Uninstall_Init - вызывается перед удалением приложения.

Uninstall_Exit - вызывается после удаления приложения.

как описано в ссылке: http://www.christec.co.nz/blog/archives/119

Что ж, моя большая трудность - удалить папку и все ее содержимое и удалить ключ в реестре, используя c ++.

Я пробовал несколько способов найти в Интернете, но ни один даже не компилируется.

Пожалуйста, сейчас более 3 дней я все еще не могу решить эту проблему.

Пример метода в C ++ для удаления рекурсивного каталога:

    bool RemoveDirectory(string path) {
    if (path[path.length()-1] != '\\') path += "\\";
    // first off, we need to create a pointer to a directory
    DIR *pdir = NULL; // remember, it's good practice to initialise a pointer to NULL!
    pdir = opendir (path.c_str());
    struct dirent *pent = NULL;
    if (pdir == NULL) { // if pdir wasn't initialised correctly
        return false; // return false to say "we couldn't do it"
    } // end if
    char file[256];

    int counter = 1; // use this to skip the first TWO which cause an infinite loop (and eventually, stack overflow)
    while (pent = readdir (pdir)) { // while there is still something in the directory to list
        if (counter > 2) {
            for (int i = 0; i < 256; i++) file[i] = '\0';
            strcat(file, path.c_str());
            if (pent == NULL) { // if pent has not been initialised correctly
                return false; // we couldn't do it
            } // otherwise, it was initialised correctly, so let's delete the file~
            strcat(file, pent->d_name); // concatenate the strings to get the complete path
            if (IsDirectory(file) == true) {
                RemoveDirectory(file);
            } else { // it's a file, we can use remove
                remove(file);
            }
        } counter++;
    }

    // finally, let's clean up
    closedir (pdir); // close the directory
    if (!rmdir(path.c_str())) return false; // delete the directory
    return true;
}

Спасибо

1 Ответ

2 голосов
/ 15 февраля 2011

Большая проблема с тем, что я вижу в вашем коде, состоит в том, что это все ASCII (char, strcat и т. Д.), А CE использует Unicode. Я также не совсем понимаю, что вы передаете, например, «строковый» тип - вы должны импортировать некоторые вещи, которые не показаны.

Что вам действительно нужно, так это вызвать FindFirstFile на вашем пути, затем итеративно вызвать DeleteFile и FindNextFile , пока не останется больше файлов. Когда папка пуста, позвоните RemoveDirectory .

Эта реализация выглядит разумно (хотя для «CE» можно не использовать «IsDots»).

EDIT
Оказывается, что реализация, связанная выше, имеет ошибку, когда фактически используется в среде Unicode. Я исправил это, а также сделал его совместимым с CE (при сохранении совместимости с рабочим столом). Вот обновленная версия:

BOOL DeleteDirectory(TCHAR* sPath) {
   HANDLE hFind;    // file handle
   WIN32_FIND_DATA FindFileData;

   TCHAR DirPath[MAX_PATH];
   TCHAR FileName[MAX_PATH];

   _tcscpy(DirPath, sPath);
   _tcscat(DirPath, _T("\\*"));    // searching all files
   _tcscpy(FileName, sPath);
   _tcscat(FileName, _T("\\"));

   // find the first file
   hFind = FindFirstFile(DirPath,&FindFileData);
   if(hFind == INVALID_HANDLE_VALUE) return FALSE;
   _tcscpy(DirPath,FileName);

   bool bSearch = true;
   while(bSearch) {    // until we find an entry
      if(FindNextFile(hFind,&FindFileData)) {
         _tcscat(FileName,FindFileData.cFileName);
         if((FindFileData.dwFileAttributes &
            FILE_ATTRIBUTE_DIRECTORY)) {

            // we have found a directory, recurse
            if(!DeleteDirectory(FileName)) {
                FindClose(hFind);
                return FALSE;    // directory couldn't be deleted
            }
            // remove the empty directory
            RemoveDirectory(FileName);
             _tcscpy(FileName,DirPath);
         }
         else {
            if(FindFileData.dwFileAttributes &
               FILE_ATTRIBUTE_READONLY)
                SetFileAttributes(FindFileData.cFileName, 
                    FindFileData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
                  if(!DeleteFile(FileName)) {    // delete the file
                    FindClose(hFind);
                    return FALSE;
               }
               _tcscpy(FileName,DirPath);
         }
      }
      else {
         // no more files there
         if(GetLastError() == ERROR_NO_MORE_FILES)
         bSearch = false;
         else {
            // some error occurred; close the handle and return FALSE
               FindClose(hFind);
               return FALSE;
         }

      }

   }
   FindClose(hFind);                  // close the file handle

   return RemoveDirectory(sPath);     // remove the empty directory
}
...