AkulaBig
Необходимость записи в файл средствами Autorun давно назревала, о чём я писал в топике. Если не ошибаюсь,
Loopback тогда ответил, что с этим есть определенные сложности в реализации, но последние два сообщения добавляют оптимизма.
Раньше приходилось пользоваться жёстким костылем - записывать переменную в буфер обмена и сохранять содержимое на диск с помощью vbs-скрипта. Но это было до того, как в Autorun появилась функция DllCall. Сейчас, наверное, всё можно решить через Win API.
К сожалению, у меня сейчас не те возможности, чтобы во всём детально разобраться, но поскольку я давно хотел сделать такой вызов, то глянул буквально одним глазком:
https://learn.microsoft.com/en-us/windo ... g-to-files
Код: Выделить всё
RegisterCommand 60017 "FileWriteTest"
RegisterCommand 60018 "AssocIniWriteTest"
Func FileWriteTest(lParam)
Local Const GENERIC_WRITE = 0x40000000, CREATE_ALWAYS = 2, FILE_ATTRIBUTE_NORMAL = 128
Local bytes = 0
Local file = COMMANDER_PATH & "\Ini\WriteTest.ini"
Local txt
txt = "Reading From and Writing to Files" & auCRLF & auCRLF & _
"An application reads from and writes to a file by using the ReadFile, ReadFileEx, WriteFile, and WriteFileEx functions." & auCRLF & auCRLF & _
"These functions require a handle to a file to be opened for reading and writing, respectively. They read and write a specified number of bytes at the location indicated by the file pointer. The data is read and written exactly as specified; the functions do not format the data."
Local buf = Buffer(StrLen(txt))
buf.SetStr(txt, 0,"","ANSI")
Local nBytes = StrLen(txt)
#Local nBytes = StrLen(txt) * 2
Local hFile = DllCall("CreateFileW", "wstr", file, "dword", GENERIC_WRITE, "dword", 0, "ptr", 0, "dword", 2, "dword", 128, "ptr", 0, "handle")
#MsgBox("Handle " & hFile)
DllCall("WriteFile", "handle", hFile, 'ptr', buf.ptr, 'dword', buf.size, "dword*", @bytes, 'ptr', 0)
#DllCall("WriteFile", "handle", hFile, 'wstr', txt, 'dword', nBytes, "dword*", @bytes, 'ptr', 0)
DllCall("CloseHandle", "handle", hFile)
MsgBox("Buffer size " & buf.size & auCRLF & "Bytes written " & bytes)
EndFunc
Func AssocIniWriteTest(lParam)
Local Const GENERIC_WRITE = 0x40000000, CREATE_ALWAYS = 2, FILE_ATTRIBUTE_NORMAL = 128
Local bytes = 0
Local ini = COMMANDER_PATH & "\Ini\Associations.ini"
Local file = COMMANDER_PATH & "\Ini\WriteTest.ini"
Local out
ProcessExecGetOutput out %COMSPEC% '/c type "%ini%"'
If StrPos(out, '[-Associations]') > 0 Then
out = StrReplace(out, '[-Associations]', '[Associations]')
Else
out = StrReplace(out, '[Associations]', '[-Associations]')
Endif
Local nBytes = StrLen(out)
Local hFile = DllCall("CreateFileW", "wstr", file, "dword", GENERIC_WRITE, "dword", 0, "ptr", 0, "dword", CREATE_ALWAYS, "dword", FILE_ATTRIBUTE_NORMAL, "ptr", 0, "handle")
DllCall("WriteFile", "handle", hFile, 'str', out, 'dword', nBytes, "dword*", @bytes, 'ptr', 0)
DllCall("CloseHandle", "handle", hFile)
MsgBox("Handle " & hFile & auCRLF & "Bytes written " & bytes)
EndFunc
Код: Выделить всё
TOTALCMD#BAR#DATA
60017
%COMMANDER_EXE%
Тест записи текста в файл
1
-1
Код: Выделить всё
TOTALCMD#BAR#DATA
60018
%COMMANDER_EXE%
Тест переключения Associations.ini в WriteTest.ini
1
-1
В первой функции я эксперементировал с объектом buffer, но он здесь в принципе не нужен, если только не нужно сменить кодировку текста на UTF-8 или что-то такое же специфическое. Для ANSI работает такой вызов:
Код: Выделить всё
DllCall("WriteFile", "handle", hFile, 'str', txt, 'dword', nBytes, "dword*", @bytes, 'ptr', 0)
Если нужен UTF-16, то понадобится в 2 раза больше байт и тип данных 'wstr':
Код: Выделить всё
Local nBytes = StrLen(txt) * 2
DllCall("WriteFile", "handle", hFile, 'wstr', txt, 'dword', nBytes, "dword*", @bytes, 'ptr', 0)
Вторая функция переключает секцию ассоциаций, но результат переключения пишет в другой файл, а не в Associations.ini. Опять же, если нужен Unicode, то должен быть "wstr" и удвоенное количество байт для записи.
Вообщем, можете попробовать, если срочно нужно. Но думаю,
Loopback уже настроился на большой бонус в новой версии )