Orion9

|
Posted: Thu Oct 01, 2026 13:39 Post subject: |
|
|
| FallenAngel wrote: | Имя сбойного приложения: TOTALCMD64.EXE, версия: 11.58.0.0, метка времени: 0x00000000
Имя сбойного модуля: Autorun.wdx64, версия: 2.2.21.3, метка времени: 0x68ef4c72
Код исключения: 0xc0000005 |
К сожалению, это мало о чем говорит. Ошибка произошла в модуле Autorun, но что именно случилось, не понятно.
| AkulaBig wrote: | | Он работает медленно. |
Не мудрено. У вас сейчас в этой функции 60 раз читается ini, 60 раз проверяется id процесса и 60 раз удаляется файл. И это для каждой подсказки.
| AkulaBig wrote: | | А если прописать FieldIndex, то получается фигня |
FieldIndex = 1 как раз нужен, чтобы сделать иницилизацию только один раз, когда вызывается первое поле подсказки, у меня так и сделано
| Code: | Func ExifHint(FileName, FieldIndex, UnitIndex)
If FieldIndex > gHintLines Then Return
If StrPos(FileGetAttr(FileName), "D") Then Return
Local bCtrl = BitAND(DllCall("GetKeyState", "int", 0x14, "short"), 1)
If Not bCtrl then bCtrl = IsPressed (0x11)
If gHintCaps And Not bCtrl Then Return
If FieldIndex = 1 Then
#ProcessExecGetOutput /C:65001 gHintPipe %gMediaExifX32% ' -G -S -lang ru "%FileName%"'
gHintPipe = GetExifInfo(FileName)
Endif
#Return FixSpaces(StrPart(gHintPipe, auLF, FieldIndex))
Return StrPart(gHintPipe, auLF, FieldIndex)
EndFunc |
Даже этот код можно попробовать оптимизировать, убрав все лишнее: т.е. убрать все, что выше If FieldIndex = 1, в само условие If FieldIndex = 1.
Объект BinaryFile должен быть в статике, чтобы он тоже не создавался 60 раз
| Code: | Static obj = BinaryFile(gExifArgs, "a") |
Free(obj) тогда не нужен.
| AkulaBig wrote: | | Ваш вариант летает как ракета |
Работает он быстро, но не стабильно. Скорее всего файл не успевает удаляться, поэтому не всегда результат в подсказке корректен. Нужно делать дополнительню проверку удаления файла, чтобы гарантировать надежность, но, понятное дело, ценой потери в скорости. Как сказал болван
| Quote: | | Если один и тот же файл постоянно перезаписывается, никогда не доверяйте успешному возврату из DeleteFileW. Либо переименовывайте файл в случайное имя перед удалением (чтобы сразу освободить оригинальное имя), либо используйте цикл с GetFileAttributesW, чтобы дождаться реального исчезновения файла с диска. |
И соответствующий код
 Hidden text | Code: | #Requires AutoHotkey v2.0
/**
* Надежно удаляет файл и ждет, пока его имя полностью освободится в системе.
* @param {String} filePath - Полный или относительный путь к файлу.
* @param {Integer} maxAttempts - Максимальное количество попыток ожидания (по умолчанию 100).
* @returns {Boolean} - true, если файл успешно и окончательно удален; false, если произошла ошибка или вышло время.
*/
ForceDeleteAndVerify(filePath, maxAttempts := 100) {
; 1. Проверяем, существует ли файл вообще
if !FileExist(filePath) {
return true
}
; 2. Пытаемся удалить файл средствами AHK (внутри вызывается DeleteFileW)
try {
FileDelete(filePath)
} catch Error as err {
; Если ошибка "Файл не найден" (код 2), значит файл уже удален
if (err.Extra == 2) {
return true
}
return false ; Другая ошибка (например, Access Denied / код 5)
}
; 3. Цикл ожидания, пока файл физически исчезнет из файловой системы
attempts := 0
while (attempts < maxAttempts) {
; Вызываем GetFileAttributesW через DllCall
; INVALID_FILE_ATTRIBUTES равен 0xFFFFFFFF (или -1 в 32-битном знаковом представлении)
attr := DllCall("Kernel32.dll\GetFileAttributesW", "Str", filePath, "UInt")
if (attr == 0xFFFFFFFF) {
lastError := DllCall("Kernel32.dll\GetLastError", "UInt")
; ERROR_FILE_NOT_FOUND = 2, ERROR_PATH_NOT_FOUND = 3
if (lastError == 2 || lastError == 3) {
return true ; Удаление наконец-то полностью завершено!
}
}
; Если файл все еще заблокирован в состоянии Pending Delete, ждем 10 мс
Sleep(10)
attempts++
}
return false ; Файл так и не исчез за отведенное время
}
; === ПРИМЕР ИСПОЛЬЗОВАНИЯ ===
targetFile := "C:\path\to\your\file.txt" ; Укажите свой путь к файлу
if ForceDeleteAndVerify(targetFile) {
MsgBox("Файл успешно и гарантированно удален! Теперь можно создавать новый с тем же именем.")
; Здесь можно безопасно делать FileAppend или FileOpen с тем же именем
} else {
MsgBox("Не удалось окончательно удалить файл (таймаут или ошибка доступа).")
}
|
| AkulaBig wrote: | | Но кривой вывод |
Вывод не кривой, а сырой (неформатированный). Я так и не понял, что хочу от этой подсказки, поэтому она осталась в недоделанном состоянии. |
|