powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Деинсталлятор
17 сообщений из 17, страница 1 из 1
Деинсталлятор
    #39827623
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В оснастке "Установка и удаление программ" зарегистрирован .exe - файл.
Который после запуска выполняет некоторые действия по деинсталляции, в соответствии со сценарием.

Как деинсталлятор в итоге удаляет сам себя?

Посмотрел, как сделано в NSIS и в Inno - жуть. Создается копия деинсталлятора в темп - директории, эта копия запускается и отрабатывает сценарий. А оригинал живет и радует имитацией активности вышеупомянутую оснастку, ждет завершения отработки сценария деинсталляции копией. Получив сигнал о завершении, оригинал завершается, оснастка фиксирует момент завершения. На самом деле, копия продолжает работать, дождавшись завершения работы оригинала, копия удаляет оригинал и директорию, в которой то размещается. Масса забавных телодвижений и мутного когда, ну да ладно.
А удаление копии (и хлама, используемого ею - плагинов. например) вешается на систему: в реестр, в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager, в переменную PendingFileRenameOperations заносится список файлов для удаления при перезагрузке. Удаление иногда выполняется, иногда - нет.
В темп - директории - масса мусора, в итоге.

Вопрос: почему не всегда удаляются файлы из списка PendingFileRenameOperations и как сделать, чтобы они удалялись всегда?
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827648
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18.06.2019 12:13, ёёёёё пишет:
> как сделать, чтобы они удалялись всегда?

не использовать Win
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827721
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёё> Вопрос: почему не всегда удаляются файлы

Мало ли что в винде могло пойти не так.
Лежат себе в Темре и лежат, всё равно
удалятся с очередной "чисткой файлов".

> как сделать, чтобы они удалялись всегда?

Забей.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827771
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёё,

1. Можно попробовать создавать temp-файл с флагом FILE_FLAG_DELETE_ON_CLOSE, правда я не знаю получится ли его запустить потом - там есть условия для его повторного открытия.

2. Можно написать деинсталлятор на .NET и потом запустить его из оперативки , соответственно он сможет удалить всё что угодно.

3. Удалить самого себя, после удаления приложения, через cmd-файл (они могут удалять сами себя).

....

ёёёёёВопрос: почему не всегда удаляются файлы из списка PendingFileRenameOperations и как сделать, чтобы они удалялись всегда?

Они не удаляются при некорректном завершении работы системы или при запуске какой-нибудь "особо умной" программы, которая использует этот список в своих целях и просто перезаписывает его, наплевав на то что там что-то было. Соответственно исправить это нельзя никак.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827782
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18.06.2019 14:48, alekcvp пишет:
> Можно попробовать создавать temp-файл с флагом FILE_FLAG_DELETE_ON_CLOSE, правда я не знаю получится ли его запустить потом - там есть условия для его повторного открытия.

не взлетит.
для того чтоб система его грохнула при закрытии, нужно чтоб заинтересованный процесс открывал
этот файл с флагом FILE_SHARE_READ или FILE_SHARE_WRITE или FILE_SHARE_DELETE.
а винда сама по себе, по доброй воле, при запуске экзешников этого не делает.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827784
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

FILE_FLAG_DELETE_ON_CLOSE - к сожалению, нельзя. В соответствии с мсдн такой файл должен открываться с опцией FILE_SHARE_DELETE, а запуск процессов из образов с такой опцией не делается.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827786
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
наверное, дешевле всего в темп-директорию выбрасывать крошечный файл-икзешник, который запускать по завершении инсталлятора, для подчистки. А сам файлик-чистильщик помечать на последующее удаление при перезагрузке, а если не сработает - то и да, фик с ним, пара килобайт в мусорке будет валяться.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827792
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёё,

Можно ещё перед завершением деинсталлера вызвать "cmd.exe /c timeout /t 5 && del /q <exefile>" со скрытым окном и сразу завершить свой процесс. Через 5 секунд cmd-шник его удалит.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827793
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpМожно ещё перед завершением деинсталлера вызвать "cmd.exe /c timeout /t 5 && del /q <exefile>" со скрытым окном и сразу завершить свой процесс. Через 5 секунд cmd-шник его удалит.
Правда в старых виндах (XP точно) работать не будет.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827800
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёё,

был ещё фокус с файловыми потоками, не проверял правда давно, будет ли на той же 10-ке работать и как на него антивирусы агрятся
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827829
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpМожно ещё перед завершением деинсталлера вызвать "cmd.exe /c timeout /t 5 && del /q <exefile>" со скрытым окном и сразу завершить свой процесс. Через 5 секунд cmd-шник его удалит.
Правда в старых виндах (XP точно) работать не будет.

timeout можно заменить на ping
...
Рейтинг: 0 / 0
Деинсталлятор
    #39827832
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x1ca4064timeout можно заменить на ping
Нельзя, при отсутствии сетевых адаптеров она моментально вылетит с ошибкой.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39828246
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёё...
Вопрос: почему не всегда удаляются файлы из списка PendingFileRenameOperations и как сделать, чтобы они удалялись всегда?
Вроде как победил.

Дело в следующем.

Значение REG_MULTI_SZ есть список юникодных строк, разделенных символом с кодом #0. В конце файла должен быть еще один (можно и больше, чем один) символ #0 (можно и больше, чем один).
Строки в PendingFileRenameOperations должны начинаться с последовательности символом "\??\", затем - имя файла или директории, которую следует удалить или переименовать при перезагрузке ОС. В конце строки должен находиться символ #0.
Далее должна размещаться строка с именем, в которое файл переименовывается. Если файл/директория не переименовываются, а удаляются, то строка должна быть пустой, то есть состоять из одного символа #0.

Значение PendingFileRenameOperations имеет тип REG_MULTI_SZ. Delphi с ним "искаропки" не умеет работать. Как минимум - Delphi 2007 не умеет.
Написал пару хелперов:
хелперы для REG_MULTI_SZ
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
unit RegHelpers;
interface
uses
  Registry;
type
  TRegistryHelper = class helper for TRegistry
    public
  function ReadMultiSz(const aName: string): string;
function WriteMultiSz(const aName: string; const aValue: string): boolean;
end;

implementation

uses
  Math, Windows;

{ TRegistryHelper }

function TRegistryHelper.ReadMultiSz(const aName: string): string;
var
  fBuffer: array of char;
  fCharsInBuffer: Integer;
  i: Integer;
  fSize: Integer;
  z: integer;
  fTmpStr: string;
begin
  fSize := Max(0, GetDataSize(aName));
  SetLength(Result, fSize);
  if fSize > 0 then begin
    fCharsInBuffer := ReadBinaryData(aName, Result[1], fSize);
    SetLength(Result, fCharsInBuffer);
  end;
end;

function TRegistryHelper.WriteMultiSz(const aName: string;
  const aValue: string): boolean;
begin
  result := RegSetValueEx(CurrentKey, pchar(aName), 0, REG_MULTI_SZ,
   PChar(aValue), Length(aValue)) = 0;
end;
end.




Как пользоваться. Например, добавляем себя и свою директорию в список PendingFileRenameOperations:
Как пользоваться
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
uses
...
  Windows,
  Registry,
  RegHelpers in 'RegHelpers.pas';

procedure MarkInRegistry();
var
  fMSZ: string;
  fR: TRegistry;
const
  c_SMKey = 'SYSTEM\CurrentControlSet\Control\Session Manager';
  c_PendOpName = 'PendingFileRenameOperations';

begin
  fR := TRegistry.Create;
  try
    fR.RootKey := HKEY_LOCAL_MACHINE;
    fR.OpenKey(c_SMKey, False);
    fMSZ := fR.ReadMultiSz(c_PendOpName);
    if (Length(fMSZ) > 0) and (fMSZ[Length(fMSZ)] <> #0) then
      fMSZ := fMSZ + #0;

    fMSZ := fMSZ + '\??\' + ParamStr(0) + #0#0#0#0; // Удаляем себя
    fMSZ := fMSZ + '\??\' + ExtractFilePath(ParamStr(0)) + #0#0#0#0; // Удаляем свою директорию

    fR.WriteMultiSz(c_PendOpName, fMSZ);
  finally
    fR.Free;
  end;

end;



Проверено в WinXP, Win7 и Win10.
х32 и x64.


Естественно, приложение должно иметь права записи в HKLM.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39828281
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно еще задействовать ветку HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce.
Занести в нее, например, значение
Код: powershell
1.
rmdir /Q директория
...
Рейтинг: 0 / 0
Деинсталлятор
    #39828313
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёёёёёёё...
Вопрос: почему не всегда удаляются файлы из списка PendingFileRenameOperations и как сделать, чтобы они удалялись всегда?
Вроде как победил.

Дело в следующем.

....

Естественно, приложение должно иметь права записи в HKLM.
На что только не идут люди, чтобы не читать справку по WinAPI

MoveFileEx :
If dwFlags specifies MOVEFILE_DELAY_UNTIL_REBOOT and lpNewFileName is NULL, MoveFileEx registers the lpExistingFileName file to be deleted when the system restarts. If lpExistingFileName refers to a directory, the system removes the directory at restart only if the directory is empty.
...
Рейтинг: 0 / 0
Деинсталлятор
    #39828339
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

точно.

"Для бешеной собаки семь вёрст не крюк" - (с).
...
Рейтинг: 0 / 0
Деинсталлятор
    #39829066
Balaganov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно удалять через файл .cmd и самой последней его строкой записать "del %0". В итоге он самоудалится.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Деинсталлятор
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]