Search code examples
.net-3.5compact-frameworksetup-projectcabwindows-mobile-6

SetupDLL to remove a folder and a key register


Develop an application on Compact Framework. net 3.5 c# for Windows Mobile 6.x.

In uninstalling the application would like to remove some keys in the register and a folder with its contents.

Searching the internet I met other tips on how to use the SetupDLL Cab project and discovered that I have to create a c + + project, implement the methods

Install_Init - called before installation begins.

Install_Exit - called after an application is installed.

Uninstall_Init - called before an application is uninstalled.

Uninstall_Exit - called after an application is uninstalled.

as described in the link: http://www.christec.co.nz/blog/archives/119

Well my great difficulty is to remove a folder and all its contents and delete a key in the register using c++.

I've tried several methods to find on the internet but none even compiles.

Please, now more than 3 days I'm still unable to solve this problem.

Sample method in C++ to delete recursive directory:

    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;
}

Thanks


Solution

  • The big problem with what I'm seeing in your code is that it's all ASCII (char, strcat, etc) and CE uses Unicode. I also don't fully understand your passing of things like a "string" type - you must be importing some things that aren't shown.

    What you really need is to call FindFirstFile in your path, then iteratively call DeleteFile and FindNextFile until there are no more files. Once the folder is empty, call RemoveDirectory.

    This implementation looks reasonable (though the "IsDots" stuff can be omitted for CE).

    EDIT
    Turns out that the implementation linked above has a bug when actually used in a Unicode environment. I've fixed it as well as made it compatible for CE (while maintaining desktop compatibility). Here's teh updated version:

    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
    }