Войти

Показать полную графическую версию : PendingFileRenameOperations


semiono
04-05-2010, 01:47
Для того чтобы удалить файл после перезагрузки компьютера Windows использует PendingFileRenameOperations.
В разделе реестра HKLM\SYSTEM\CurrentControlSet\Control\Session Manager создаётся многостроковая переменная PendingFileRenameOperations.
В качестве аргументов в неё записываются имена файлов с их расположением которые надо переименовать в нуль!
Этот механизм используют и инсталяторы в том же числе. Но использовать встроенную возможность в InnoSetup не всегда удобно.
Там в таком случае выводится окно с сообщением выполнить перезагрузку, или что-то другое ещё я уж не помню.
Возможно и не было проблеммы, но я как любитель тихой установки сразу же отказался от этого и придумал альтернативу.

Программа на ассемблере, пример из реальной моей сборки.

MoveFileEx32.asm:
include '%fasm%\win32ax.inc'

section '.code' code readable executable

start:
invoke ExpandEnvironmentStrings,lpDrv,lpStr1,400h
invoke lstrcat,lpStr1,File1
invoke MoveFileEx,lpStr1,NULL,MOVEFILE_DELAY_UNTIL_REBOOT
exit:
invoke ExitProcess,0

section '.data' data readable writeable

lpDrv db '%ProgramFiles%',0

File1 db '\HprSnap\HSTxtCap',0

lpStr1 db ?

MoveFileEx64.asm:
include '%fasm%\win64ax.inc'

section '.code' code readable executable

start:
invoke ExpandEnvironmentStrings,lpDrv,lpStr1,400h
invoke lstrcat,lpStr1,File1
invoke MoveFileEx,lpStr1,NULL,MOVEFILE_DELAY_UNTIL_REBOOT

invoke ExpandEnvironmentStrings,lpDrv,lpStr2,400h
invoke lstrcat,lpStr2,File2
invoke MoveFileEx,lpStr2,NULL,MOVEFILE_DELAY_UNTIL_REBOOT
exit:
invoke ExitProcess,0

section '.data' data readable writeable

lpDrv db '%ProgramFiles%',0

File1 db '\HprSnap\HSTxtCap',0
File2 db '\HprSnap\HSTxtCap64',0

lpStr1 db ?
lpStr2 db ?

section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL'
include '%fasm%\api\kernel32.inc'

Почему два кода? Потому что 32-битный код запишет Program Files (x86) в x64 системе.
Ну впрочем можно с переменными окружения разобраться, однако если инсталлер зделан на две платформы,
то 64-битный код всёравно нельзя использовать в x86.

Я не программист сразу предупреждаю. :)

Почему ассемблер? Потому-что скачать 849 kilobytes и установить очень легко. Это вам не Microsoft Visual Studio! :)
flat assembler 1.68 for Windows http://flatassembler.net/download.php


Использовать программу можно для различных целей, кому как удобнее. Работает код корректно!
Записать же руками задачу в реестр довольно сложно с подсчётами нулей всегда проблемы возникают.
Особенно если запись добовляется многократно из разных инсталяторов к примеру.
В InnoSetup я пытался в [registry] multisz через всякие комбинации {break} и {olddata} зделать, ничего из этого не вышло.

Для использования программы в InnoSetup пишем следущее (в качестве примера):
; ...
[Run]
Filename: "{tmp}\MoveFileEx.exe"; Flags: nowait

[Cod.e]
procedure InitializeWizard();
begin
try
DeleteFile(ExpandConstant('{pf}\HprSnap\HSTxtCap'))
RenameFile(ExpandConstant('{pf}\HprSnap\HSTxtCap.dll'),ExpandConstant('{pf}\HprSnap\HSTxtCap'))
except
Beep; Exit;
end;

if IsWin64 then
try
DeleteFile(ExpandConstant('{pf}\HprSnap\HSTxtCap64'))
RenameFile(ExpandConstant('{pf}\HprSnap\HSTxtCap64.dll'),ExpandConstant('{pf}\HprSnap\HSTxtCap64'))
except
Beep; Exit;
end;
end;
; ...

[Files]
; ...
Source: "T:\MoveFileEx32.exe"; DestDir: "{tmp}"; DestName: "MoveFileEx.exe"; Flags: ignoreversion overwritereadonly touch; Check: not IsWin64; Permissions: admins-full
Source: "T:\MoveFileEx64.exe"; DestDir: "{tmp}"; DestName: "MoveFileEx.exe"; Flags: ignoreversion overwritereadonly touch; Check: IsWin64; Permissions: admins-full




© OSzone.net 2001-2012