Часто задаваемые вопросы и ответы по C/C++/Visual C++
Последнее обновление: 27.08.2003
FAQ по C/C++/Visual C++
Работа с сетью
Как создать ярлык
Вариант SUnteXx'a
Составители: SUnteXx, Leprecon
Как удалить прогу из самой себя
A: (SUnteXx)
Оригинальная ссылка: нету

#include <windows.h>
#include <stdio.h>

const char BATSTRING[] = "del \"%s\n\
:Repeat\n\
del \"%s\"\n\
if exist \"%s\" goto Repeat\n\
:Repeat1\n\
del \"%s\"\n\
"; // Наша константа

int WINAPI WinMain (HINSTANCE    hInstance, 
                        HINSTANCE    hPrevInstance, 
                        LPSTR        lpszCmdParam, 
                        int            nCmdShow) 
// Здесь может быть любая другая ф-ция.
// Эта ф-ция взята для примера!
{
    HANDLE hFile;

// Далее выделяем много памяти - лишним не будет %)
    char szFilePath[MAX_PATH] = {"\0"};
    char szFileBat[MAX_PATH] = {"\0"};
    char szFileExe[MAX_PATH] = {"\0"};

    char sz[600]; // Строка-помошник...

    unsigned int iTmp;
    char* lpTmp;

    GetModuleFileName(hInstance, szFileExe, sizeof(szFileExe)); // Получаем путь к запущенному ехешнику

    if (GetShortPathName(szFileExe, sz, _MAX_PATH)) // Преобразуем в имя файла в досовский вид
        strcpy(szFileExe, sz);
    
    for (iTmp = 0, lpTmp = szFileExe + strlen(szFileExe)-1; iTmp < strlen(szFileExe); lpTmp--, iTmp++)
    {
        if (!strncmp(lpTmp, "\\", 1))
            break;
    }

    strncpy(szFilePath, szFileExe, lpTmp - szFileExe);
    strcat(szFilePath, "\\");

    GetTempPath(MAX_PATH, sz); // Получаем путь к TEMP-папке
    sprintf(szFileBat, "%sSystem.bat", (strlen(sz))?sz:szFilePath);

    DWORD dwBytesWritten;

    SetFileAttributes(szFileBat, FILE_ATTRIBUTE_NORMAL); // Если файл существует, то изменим его аттрибуты на нормальные

    hFile = CreateFile((LPCTSTR)szFileBat,
                                            GENERIC_WRITE,
                                            FILE_SHARE_WRITE,
                                            NULL,
                                            CREATE_ALWAYS,
                                            FILE_ATTRIBUTE_NORMAL,
                                            (HANDLE)NULL); // Создаем по-новой файл ("зачем?" - ком. внутреннего голоса)

    if (!hFile)
    {
        MessageBox(NULL, "Облом", "Факн щет, файла нет и не будет", MB_OK | MB_ICONSTOP);
        return 0;
    }

    sprintf(sz, BATSTRING, szFileExe, szFileExe, szFileExe, szFileBat, szFileBat);

    HINSTANCE h;

    BOOL bError = (!WriteFile(hFile, sz, strlen(sz), &dwBytesWritten, NULL)
                    || strlen(sz) != dwBytesWritten);

    if (bError)
    {
        MessageBox(NULL, "Облом", "Факн щет, текст в файл не удалось записать", MB_OK | MB_ICONSTOP);
        return 0;
    }

    SetFileAttributes(szFileExe, FILE_ATTRIBUTE_ARCHIVE);
    SetFileAttributes(szFileBat, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN); // "прячем" файл

// Тут можно поиздеваться над юзером, мол не спи, я щаззз удалюсь

    CloseHandle(hFile); // Специально закрываем файл перед запуском батника, чтобы юзер не удалил файл раньше времени

    SetFileAttributes(szFileBat, FILE_ATTRIBUTE_NORMAL); // Делаем файл нормальным

    h = ShellExecute(NULL, "open", szFileBat, NULL, NULL, SW_HIDE); // Запускаем батник
    return 0; // И закрываемся
}
Наш батник (файл *.bat) составлен так, что он будет выполняться непрерывно и проверять, удалился ли ехешник или нет. Если нет, то цикл повторяется. Так что после запуска батника остается только закрыть нашу прогу и она удалиться автоматически!




Вырезку из MSDN прислал Codemaster.



HOWTO: Move Files That Are Currently in Use
ID: Q140570

The information in this article applies to:

Microsoft Win32 Application Programming Interface (API), included with:
Microsoft Windows 95
Microsoft Windows NT, versions 3.51, 4.0


SUMMARY
Sometimes Win32 applications need to delete, rename, or move files that are currently being used by the system. One common example is that setup programs need to remove themselves from the user's hard disk when they are finished setting up a software package. Sometimes, they also need to move device drivers that are currently being used by the system. Applications need help from the operating system to delete or move these files.

Windows 95 and Windows NT each provide a unique method for helping applications to remove, replace, or rename files and directories that are in use. Although the two platforms differ in how they implement these methods, both share an overall strategy where the application specifies which files to process, and the system processes them when it reboots. This article explains how applications can use the method provided by each Windows platform.


MORE INFORMATION

Moving Files in Windows NT
Win32-based applications running on Windows NT should use MoveFileEx() with the MOVEFILE_DELAY_UNTIL_REBOOT flag to move, replace, or delete files and directories currently being used. The next time the system is rebooted, the Windows NT bootup program will move, replace, or delete the specified files and directories.

To move or replace a file or directory that is in use, an application must specify both a source and destination path on the same volume (for example, drive C:). If the destination path is an existing file, it will be overwritten. If the destination path is an existing directory, it will not be overwritten and both the source and destination paths will remain unchanged. Here is an example call to move or replace a file or move a directory:
   // Move szSrcFile to szDstFile next time system is rebooted
   MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT); 
To delete a file or directory, the application must set the destination path to NULL. If the source path is a directory, it will be removed only if it is empty. Note that if you must use MoveFileEx() to remove files from a directory, you must reboot the computer before you can call MoveFileEx() to remove the directory. Here is an example of how to delete a file or empty a directory:
   // Delete szSrcFile next time system is rebooted
   MoveFileEx(szSrcFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); 
Moving Files in Windows 95
Windows 95 does not implement MoveFileEx(), but does provide an alternate way for all Win32-based, 16-bit Windows-based, and MS-DOS-based applications to move, replace, or delete files (but not directories) that are currently in use. This capability is implemented through the [rename] section of a file named Wininit.ini. If Wininit.ini is present in the Windows directory, Wininit.exe processes it when the system boots. Once Wininit.ini has been processed, Wininit.exe renames it to Wininit.bak.

The syntax of the [rename] section is:

DestinationFileName=SourceFileName
DestinationFileName and SourceFileName must reside on the same volume and be short (8.3) file names because Wininit.ini is processed before the protected mode disk system is loaded, and long file names are only available when the protected mode disk system is running. Destination and source files specified in Wininit.ini with long file names are ignored.

The [rename] section can have multiple lines with one file per line. To delete a file, specify NUL as the DestinationFileName. Here are some entry examples:

[rename]
NUL=C:\TEMP.TXT
C:\NEW_DIR\EXISTING.TXT=C:\EXISTING.TXT
C:\NEW_DIR\NEWNAME.TXT=C:\OLDNAME.TXT
C:\EXISTING.TXT=C:\TEMP\NEWFILE.TXT


The first line causes Temp.txt to be deleted. The second causes Existing.txt to be moved to a new directory. The third causes Oldname.txt to be moved and renamed. The fourth causes an existing file to be overwritten by Newfile.txt.

Applications should not use WritePrivateProfileString() to write entries to the [rename] section because there can be multiple lines with the same DestinationFileName, especially if DestinationFileName is "NUL." Instead, they should add entries by parsing Wininit.ini and appending the entries to the end of the [rename] section.

NOTE: Always use a case-insensitive search to parse Wininit.ini because the title of the [rename] section and the file names inside it may have any combination of uppercase and lowercase letters.

Applications that use Wininit.ini should check for its existence in the Windows directory. If Wininit.ini is present, then another application has written to it since the system was last restarted. Therefore, the application should open it and add entries to the [rename] section. If Wininit.ini isn't present, the application should create it and add to the [rename] section. Doing so ensures that entries from other applications won't be deleted accidentally by your application.

To undo a file rename operation before the system is rebooted, you must remove the corresponding line from the [rename] section of the Wininit.ini file.

Additional query words: update install setup

Содержание Обсудить на форуме « Предыдущая статья | Следующая статья »
Перейти к FAQ:  
FAQ составлен по материалам Форума на Исходниках.Ру.
Copyright © 2002 by Sources.ru. All rights reserved.