C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: удаление файла из самого себя  (Прочитано 4634 раз)
Stilch
Участник
**

Сказали спасибо: +4/-0
Offline Offline

Сообщений: 46


« : 17 декабря 2010, 00:28:07 »

Люди добрые подскажите плз как можно удалить .exe файл из самого себя
весь нэт перерыл ничего толкового не нашел Непонимающий Непонимающий Непонимающий
Записан
Hammersoft
Участник
**

Сказали спасибо: +23/-2
Offline Offline

Сообщений: 167


« Ответ #1 : 17 декабря 2010, 00:48:34 »

Винда не дает запущенный файл удалить. Переименовать можно.
Записан
S0mbre
Глобальный модератор
***

Сказали спасибо: +1113/-22
Offline Offline

Сообщений: 2137

S0mbre


WWW
« Ответ #2 : 17 декабря 2010, 07:47:50 »

Ну, исхитриться можно, по идее... Например, создать батник с досовским кодом, удаляющим программу, и запустить его при закрытии проги.
Пример простого батника
Код:
@echo off
rem выждать 2 сек. (подождать пока файл точно закроется)
ping -n 1 -w 2000 192.168.254.254 >nul
rem если файл существует, удалить (без подтверждения)
if exist %1 erase /f /q %1

Приведенный батник принимает в качестве параметра полный путь к файлу, кот. надо удалить. В вашем случае при закрытии программы (событие OnDestroy или OnClose на главной форме) выполняете команду
Код
char* BATFILE = "1.bat"; // путь к батнику
char* PARAM = UnicodeString("\"" + Application.ExeName + "\"").t_str(); // параметр батника - путь к нашей проге, кот. убиваем :)
ShellExecute(NULL, "open", BATFILE, PARAM, NULL, SW_HIDE);
 

Ваша прога закрывается, запускается батник, ждет 2 секунды и удаляет файл...
« Последнее редактирование: 17 декабря 2010, 07:54:59 от S0mbre » Записан
olegenty
Администратор
***

Сказали спасибо: +16/-7
Offline Offline

Сообщений: 520


« Ответ #3 : 17 декабря 2010, 08:27:48 »

выкури вот это:
*.h
Код
/////////////////////////////////////////////////////////////////////////////
// Класс для обновления выполняемого EXE файла.
// Информация об источнике обновления находится в INI-файле, передаваемом как параметр
// в секции Update, параметре Source
//
class PACKAGE CSelfUpdate
{
private:
   String  Source     ;
   String  Self       ;
   bool        FilesExists;
   bool        SetupUpdate;
public:
   // Информация об источнике обновления читается из INI файла
   // Self - собственно обновляемый файл
   // Section - наименование секции
   CSelfUpdate(const String Self,
               const String IniFileName,
               const String Section,
               const String SetupUpdateParameter,
               const String SetupSourceParameter,
               const String SourceParameter);
 
   // Указывается путь к более новому файлу
   CSelfUpdate(const String Self,
               const String Path);
   void Execute(const String AppTitle);
};
 
*.cpp
Код
CSelfUpdate::CSelfUpdate(const String Self,
                        const String IniFileName,
                        const String Section,
                        const String SetupUpdateParameter,
                        const String SetupSourceParameter,
                        const String SourceParameter):
                        Self(Self),
                        Source(NULL),
                        SetupUpdate(false),
                        FilesExists(false)
{
   auto_ptr<TIniFile> f = auto_ptr<TIniFile>(new TIniFile(IniFileName));
   SetupUpdate = f->ReadBool(Section, SetupUpdateParameter, false);
   if (SetupUpdate)
   {
       Source = f->ReadString(Section, SetupSourceParameter, "");
   } else
   {
       Source = f->ReadString(Section, SourceParameter, "") +
                "\\" + ExtractFileName(Self);
   }
   FilesExists = FileExists(Self) && FileExists(Source);
}
 
CSelfUpdate::CSelfUpdate(const String Self,
                        const String Path):
                        Self(Self),
                        Source(Path),
                        SetupUpdate(false),
                        FilesExists(false)
{
   //auto_ptr<TIniFile> f = auto_ptr<TIniFile>(new TIniFile(IniFileName));
   //SetupUpdate = f->ReadBool(Section, SetupUpdateParameter, false);
   FilesExists = FileExists(Self) && FileExists(Source);
}
 
void CSelfUpdate::Execute(const String AppTitle)
{
   if (!FilesExists) return;
   if (SetupUpdate)
   {
       MessageBox(NULL,
                  "Найдено обновление программы. Будет запущен устанавливающий модуль. По окончании его работы запустите программу вновь.",
                  AppTitle.c_str(),
                  MB_APPLMODAL + MB_ICONINFORMATION);
       spawnlp(P_OVERLAY, Source.c_str(), "", NULL);
   } else
   {
       typedef CFileVersion V;
       if (!(V(Self) < V(Source))) return;
       String OldFileName = ChangeFileExt(Self, ".old");
       if(FileExists(OldFileName) && !DeleteFile(OldFileName)) return;
       RenameFile(Self, OldFileName);
       CopyFile(Source.c_str(), Self.c_str(), false);
       spawnlp(P_OVERLAY, Self.c_str(), "", NULL);
   }
}
 

Метод Execute - там exe перетирается новой версией прямо во время самовыполнения.
Записан
S0mbre
Глобальный модератор
***

Сказали спасибо: +1113/-22
Offline Offline

Сообщений: 2137

S0mbre


WWW
« Ответ #4 : 17 декабря 2010, 08:58:37 »

Мой код короче Улыбка

Подправил немного... Код BAT файла:
Код:
@echo off
rem Выждаем 2 сек...
ping -n 1 -w 2000 192.168.254.254 >nul
rem Если существует файл, передаваемый в параметр, удалить его без подтверждения
if exist %1 erase /f /q %1
rem ...И удалить сам BAT-файл!
erase /f /q "%~dp0\1.bat"

Код кнопки "Удалить меня" в приложении
Код
char* BATFILE = "c:\\1.bat"; // путь к батнику
char* PARAM = UnicodeString("\"" + Application->ExeName + "\"").t_str(); // параметр батника - путь к нашей проге, кот. убиваем :)
ShellExecute(NULL, "open", BATFILE, PARAM, NULL, SW_HIDE);
Application->Terminate();
 

Работает 100% - проверял. Совет: если не работает, попробуйте увеличить время паузы в BAT файле (т.е. не 2000 мсек, а например 3000) - это время, необходимое для программы, чтобы закрыться перед тем, как будет удалена.
Записан
olegenty
Администратор
***

Сказали спасибо: +16/-7
Offline Offline

Сообщений: 520


« Ответ #5 : 17 декабря 2010, 10:24:21 »

а мой без батника  Улыбка
Записан
S0mbre
Глобальный модератор
***

Сказали спасибо: +1113/-22
Offline Offline

Сообщений: 2137

S0mbre


WWW
« Ответ #6 : 17 декабря 2010, 11:09:20 »

а мой без батника  Улыбка

Улыбка +1
Записан
S0mbre
Глобальный модератор
***

Сказали спасибо: +1113/-22
Offline Offline

Сообщений: 2137

S0mbre


WWW
« Ответ #7 : 17 декабря 2010, 11:12:28 »

Я как-то тоже реализовывал перезапуск программы из самой себя. Но для этого я просто накатал скрипт на AutoIt (то же самое можно сделать через batch файл), который закрывает прогу и открывает ее заново. И вызывал этот скрипт. Решение более "ламерское"  Веселый но не так много гемора.
Записан
olegenty
Администратор
***

Сказали спасибо: +16/-7
Offline Offline

Сообщений: 520


« Ответ #8 : 17 декабря 2010, 11:47:10 »

вызов spawnlp - вроде не гемор. обёртка в виде класса только для удобства, чтобы каждый раз всеми проверками не заморачиваться.
Записан
S0mbre
Глобальный модератор
***

Сказали спасибо: +1113/-22
Offline Offline

Сообщений: 2137

S0mbre


WWW
« Ответ #9 : 17 декабря 2010, 12:40:08 »

Улыбка согласен. Однако же человек спрашивал про удаление EXE, а не замещение его в памяти...
Записан
Stilch
Участник
**

Сказали спасибо: +4/-0
Offline Offline

Сообщений: 46


« Ответ #10 : 17 декабря 2010, 15:20:06 »

спс за помощь. все получилось.  Смеющийся Смеющийся Смеющийся Смеющийся
использую вариант S0mbre
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в: