1 (изменено: Bulef, 2019-10-28 18:59:51)

Тема: AHK: Script Saver

Создал для себя скрипт для создания других скриптов. Работает он с помощью информации о местоположении и названии скрипта, помещаемого в тело самого скрипта. Примером является сам скрипт. Все действия, происходят относительно местоположения основного скрипта. Есть функции логирования версий, логирования копирований, перемещения и функция переименования скриптов. Иконка скрипта в прикреплении. Делался скрипт, с оглядкой на онлайн нотпад Evernote.
https://www.evernote.com/l/AuL75-IzUXBH … cpU-fz2_8/ - Evernote версия скрипта.

; AHK Script Saver
; Версия 1.04
; \AHK Script Saver

/*


Alt + X => Закрыть этот скрипт.

Alt + 1 => Создать скрипт, исходя из блока информации о скрипте.

Alt + 2 => Найти строку в скрипте.

-----

; Это сноска.

Если хотите указать информацию о скрипте, используйте такой формат типа строки.

-----

Первая строчка в виде сноски, определяет имя скрипта.

Формат: "; Имя скрипта".

-----

Остальные строки несущие информацию о скрипте, должны идти в одном блоке со сноской, в которой указано имя скрипта. Любые другие строки информации, кроме имени скрипта, являются необязательными. Порядок необязательных строк, может быть абсолютно любым.

Последняя строчка информации о скрипте, должна отделяться переносом строки от всего остального скрипта. В противном случае, поиск будет осуществляться по всем строкам находящимся в одном блоке. Это не приведёт к ошибкам, но снизит скорость поиска и обработки скриптом строк.

-----

В любой другой сноске подряд, но только после сноски с именем, может быть указана версия. При смене версии, создаётся новый лог изменений скрипта. Больше версия, не влияет ни на что.

Формат: "; Версия 1", или может быть например таким: "; Версия Тестовая 112.50153 Б".

-----

В любой другой сноске подряд, но только после сноски с именем, может быть указана подпапка в которую необходимо поместить скрипт.

Формат: "; \Название папки", или может быть например таким: "; \Название папки\Название подпапки\Название подпапки №2".

-----

В любой другой сноске подряд, но только после сноски с именем, может быть указан способ создания для скрипта. Вы можете отключить функцию перемещения. Это позволит проигнорировать совпадения имени скриптов и запретить появление вопроса о перемещении файлов скрипта - источника, из его папки, в папку, к скрипту - приемнику.

Формат: "; Копировать".

-----

В любой другой сноске подряд, но только после сноски с именем, может быть указано новое имя файла скрипта, если Вы хотите переименовать скрипт. Имя конечной папки, никак не зависит от имени самого скрипта. Не забывайте изменить информацию о скрипте на актуальную после переименования.

Формат: "; Переименовать в Имя скрипта".

-----

Построение скрипта, базируется на том, что редактируемая версия тела скрипта, может храниться независимо от самого скрипта. Допустим, это онлайн хранилище, где удобно хранить, искать и сортировать скрипты. Если исходить из этого, то вносить изменение в файл самого скрипта - будет скорее вредно, так как из-за этого, возникает конфликт с версией, хранящейся независимо от самого скрипта. Информация, берётся исключительно исходя из текста перед глазами в форме "как есть" и отчасти базируется на той информации, которая относится к фактическому местоположению AHK Script Saver скрипта.

-----

В Evernote версии скрипта, ниже будет располагаться иконка скрипта для трея. Поместите её вместе с основным скриптом. Название иконки и скрипта, должны совпадать.

*/

; Начало открывающего блока

#SingleInstance Force
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

SplitPath, A_ScriptName, , , , ScriptName

SetTitleMatchMode, 2

DetectHiddenWindows, On

; Конец открывающего блока

; Начало Exit

GoTo, WrappingAroundExit ; Начало обтекания строк.

#Persistent
!sc02D:: ; Alt + X
ExitApp

WrappingAroundExit: ; Конец обтекания строк.

; Конец Exit

; Начало AHKScriptSaver

Menu, Tray, Icon , %A_ScriptDir%\%ScriptName%.ico

AutoRun = On ; | On | Off |

FileRead, FileContents, %A_ScriptFullPath%
FoundPos := RegExMatch(FileContents, "(\; .*\R)*", ScriptInfo, 1)
FoundPos := RegExMatch(ScriptInfo, "\; \\.*\R", ScriptSubDir, 1)
StringTrimLeft, ScriptSubDir, ScriptSubDir, 2
StringTrimRight, ScriptSubDir, ScriptSubDir, 2

StringReplace, CurrentWorkingDir, A_ScriptDir, %ScriptSubDir% ; Определяем настоящую рабочую директорию.
SetWorkingDir %CurrentWorkingDir%
FoundPos := RegExMatch(CurrentWorkingDir, "[^*\\]*$", CurrentWorkingFolder, 1)

GoTo WrappingAroundAHKScriptSaver ; Начало обтекания строк.

!1:: ; Alt + 1
Send ^{sc01E} ; Ctrl + A

GoSub, CopyAndCheck

FoundPos := RegExMatch(Clipboard, "(\; .*\R)*", ScriptInfo, 1)
FoundPos := RegExMatch(ScriptInfo, "\; .*\R", ScriptTitle, 1)
FoundPos := RegExMatch(ScriptInfo, "\; Версия.*\R", ScriptVersion, 1)
StringReplace, ScriptVersion, ScriptVersion, Версия
FoundPos := RegExMatch(ScriptInfo, "\; \\.*\R", SubDir, 1)
FoundPos := RegExMatch(ScriptInfo, "\; Копировать\R", CopyOptions, 1)
FoundPos := RegExMatch(ScriptInfo, "\; Переименовать в.*\R", RenameOption, 1)
StringReplace, RenameOption, RenameOption, Переименовать в

StringTrimLeft, ScriptTitle, ScriptTitle, 2
StringTrimRight, ScriptTitle, ScriptTitle, 2

If ScriptVersion =
   ScriptVersion = 1
Else
{
   StringTrimLeft, ScriptVersion, ScriptVersion, 3
   StringTrimRight, ScriptVersion, ScriptVersion, 2
}

If SubDir <>
{
   StringTrimLeft, SubDir, SubDir, 3
   StringTrimRight, SubDir, SubDir, 2
    BsSubDir = \
   FolderInfo = `nПодпапка: %BsSubDir%%SubDir%`n
}
Else
   FolderInfo = `nРабочая папка: \%CurrentWorkingFolder%`n

If CopyOptions <>
{
   StringTrimLeft, CopyOptions, CopyOptions, 2
   StringTrimRight, CopyOptions, CopyOptions, 2
}

If RenameOption <>
{
   StringTrimLeft, RenameOption, RenameOption, 3
   StringTrimRight, RenameOption, RenameOption, 2
   FinalTitle = %RenameOption%
}
Else
   FinalTitle = %ScriptTitle%


If CopyOptions = Копировать
   AdditionalOperations = С созданием.
Else
If RenameOption <>
   GoTo AHKScriptSaver1
Else
If CopyOptions =
   GoTo AHKScriptSaver1

AHKScriptSaver1:
{
   AdditionalOperations = С созданием.
   Loop, %ScriptTitle%.ahk, 0, 1
   {
       If A_LoopFileDir <>
       {
           SourcePath = %A_LoopFileDir%
           BsSourcePath = \
       }
       MsgBox, 4, , Рабочая директория: %CurrentWorkingDir%`n`nНайденное совпадение источника: \%A_LoopFileFullPath%`n`nХотите переместить все файлы по шаблону "%ScriptTitle%" и папки по шаблону "%ScriptTitle%_" к приемнику: %BsSubDir%%SubDir%%BsSubDir%%FinalTitle%.ahk`n`n`nВы можете включить игнорирование функции перемещения для нужного скрипта, добавив: "; Копировать" в информацию о скрипте.
       IfMsgBox, Yes
       {
           MoveContents = Yes
           AdditionalOperations = `nС перемещением файлов и папок от источника: \%A_LoopFileFullPath%`nК приемнику: %BsSubDir%%SubDir%%BsSubDir%%FinalTitle%.ahk
           Break
       }
       Else
       {
           SourcePath =
           AdditionalOperations = С созданием.
           Continue
        }
   }
}

If RenameOption <>
{
    If AdditionalOperations = С созданием.
    {
        MsgBox, 0, , Переименование в %RenameOption%.ahk уже произошло. Исправьте информацию о скрипте на актуальную.
        Return
    }
    Else
        GoTo AHKScriptSaver2
}
Else
    GoTo AHKScriptSaver2

AHKScriptSaver2:
MsgBox, 4, , Название: %FinalTitle%.ahk`nВерсия: %ScriptVersion%%FolderInfo%Тип копирования: %AdditionalOperations%
IfMsgBox Yes
{
    IfNotExist, %SubDir%
       FileCreateDir, %SubDir%
    FileDelete, %SubDir%%BsSubDir%%FinalTitle%.ahk
   
    If MoveContents = Yes
   {
       FileDelete, %SourcePath%%BsSourcePath%%ScriptTitle%.ahk
       FileMove, %SourcePath%%BsSourcePath%%ScriptTitle%.*, %SubDir%%BsSubDir%%FinalTitle%.*, 1
       
       Loop, %SourcePath%%BsSourcePath%%ScriptTitle%_*, 2, 0
       {
           StringReplace, SubTitle, A_LoopFileName, %ScriptTitle%
           FileMoveDir, %A_LoopFileFullPath%, %SubDir%%BsSubDir%%FinalTitle%%SubTitle%, 2
       }
        SubTitle =
        MoveContents =
        SourcePath =
        BsSourcePath =
   }

   FileAppend, %Clipboard%, %SubDir%%BsSubDir%%FinalTitle%.ahk
   IfNotExist, %SubDir%%BsSubDir%%FinalTitle%_VersionsLog\%FinalTitle% Ver. %ScriptVersion%
       FileCreateDir, %SubDir%%BsSubDir%%FinalTitle%_VersionsLog\%FinalTitle% Ver. %ScriptVersion%
   FormatTime, FileTimeString, , yy'Y'.MM'M'.dd'D'.HH'H'.mm'Min'
   FileAppend, Имя: %FinalTitle%`n`nВерсия: %ScriptVersion%`n`nВремя: %TimeString%`n`n`nТело скрипта:`n`n%Clipboard%`n`n`n`n, %SubDir%%BsSubDir%%FinalTitle%_VersionsLog\%FinalTitle% Ver. %ScriptVersion%\%ScriptTitle%_%FileTimeString%_Ver. %ScriptVersion%.txt
   If AutoRun = On
    {
        Run, %SubDir%%BsSubDir%%FinalTitle%.ahk
        WinKill, %ScriptTitle%.ahk, , , ,
    }
   Return
}
Else
   Return

WrappingAroundAHKScriptSaver: ; Конец обтекания строк.

; Конец AHKScriptSaver

; FindString

GoTo, WrappingAroundFindString ; Начало обтекания строк.

!2:: ; Alt + 2
{
    Gui, Add, Text, , Пожалуйста, введите номер нужной строки:`nПосле этого, выделите первую строку.
    Gui, Add, Edit, W40 ym vStringNumber
    Gui, Add, Button, xp+45 Default, OK
    Gui, Show
    Return

    ButtonOK:
    Gui, Submit
    Gui, Destroy
    KeyWait, LButton, D

    StringNumber -= 1
    LoopNumber = %StringNumber%
    Loop
    {
        LoopNumber -= 1
        Sleep 10
        Send {sc150} ; Arrow down
        If LoopNumber = 0
        {
            Sleep 10
            Send +{sc150}
            Break
        }
        Else
            Continue
    }
    Return
}

WrappingAroundFindString: ; Конец обтекания строк.

; Конец FindString

; Начало CopyAndCheck

CopyLog = Full ; | Full | Restricted | Off |

CopyErrorTime = 300

GoTo WrappingAroundCopyAndCheck ; Начало обтекания строк.

; Зачем вообще нужен CopyAndCheck?
; Основной проблемой с копированием из различных приложений с помощью AHK, является занесение в AHK предыдущего буфера обмена, даже с учётом того, что ClipWait уже подтвердил наличие изменения буфера обмена.
; Также, случается периодическое несрабатывание отправки нажатий, и ещё, в AHK может вернуться пустой буфер обмена.
; Этот скрипт, будет повторять копирование до тех пор, пока не будет получено непустое и не соответствующее маркеру текущего цикла повторения значение.
; Периодичность повторения, увеличивается с каждой критической ошибкой. Такими ошибками, является неудачное копирование и возврат пустого буфера обмена.

CopyAndCheck:
BlockInput, On
ToolTip, Подождите. Происходит копирование.
CopyNumber ++
GoSub, ChangeClipTag
ClipKey = ClipTag #%ClipTag%
If CopyLog = Full
{
    FormatTime, FastTimeString, , HH:mm.ss'S'
    LogTextAdd = Время: %FastTimeString%`n`nClipKey: %ClipKey%`n`nВремя отложенного копирования: %CopyErrorTime% ms.
    LogText = %LogText%`n`n%LogTextAdd%
}
Clipboard = %ClipKey%
ClipWait

Loop ; Ожидание ClipKey в буфере обмена.
{
    If Clipboard = %ClipKey%
        Break
    Else
    {
        CopyError = Буфер обмена не занёс ClipKey.
        If CopyLog = Full
        {
            LogTextAdd = Ошибка копирования: %CopyError% Номер итерации: %A_Index%.
            LogText = %LogText%`n`n%LogTextAdd%
        }
        Sleep 10
        Continue
    }
}

Send ^{sc02E} ; Ctrl + C
ClipWait

SetTimer, RepeatCopy, %CopyErrorTime%
Loop ; Ожидание текста в буфере обмена.
{
    If Clipboard = %ClipKey%
    {
        CopyError = Буфер обмена не заменил ClipKey.
        If CopyLog = Full
        {
            LogTextAdd = Ошибка копирования: %CopyError% Номер итерации: %A_Index%.
            LogText = %LogText%`n`n%LogTextAdd%
        }
        Sleep 10
        Continue
    }
    Else
    {
        If Clipboard =
        {
            CopyError = В буфере обмена пустота.
            SetTimer, RepeatCopy, Off
            CopyErrorTime += 700
            If CopyLog = Full
            {
                LogTextAdd = Ошибка копирования: %CopyError%
                LogText = %LogText%`n`n%LogTextAdd%
            }
            Sleep %CopyErrorTime%
            GoTo CopyAndCheck ; Повторяем цикл заново.
        }
        Else
        {
            CopyError = Успешно.
            SetTimer, RepeatCopy, Off
            If CopyLog in Full,Restricted
            {
                FormatTime, TimeString
                FormatTime, FileTimeString, , yy'Y'.MM'M'.dd'D'.HH'H'
                FormatTime, FileTimeString2, , mm'Min'
                IfNotExist, %A_ScriptDir%\%ScriptName%_CopyLog\%ScriptName%_%FileTimeString%_CopyLog
                FileCreateDir, %A_ScriptDir%\%ScriptName%_CopyLog\%ScriptName%_%FileTimeString%_CopyLog
            }
            If CopyLog = Full
            {
                FormatTime, FastTimeString, , HH:mm.ss'S'
                LogTextAdd = %CopyError%`n`nВремя: %FastTimeString%
                LogText = %LogText%`n`n%LogTextAdd%
                FileAppend, Номер копии: %CopyNumber%`n`nВремя: %TimeString%`n`n`nКопирование № %CopyNumber%`n`nЛоги копирования:%LogText%`n`n`nКопирование № %CopyNumber%`n`nБуфер обмена:`n`n%Clipboard%`n`n`n`n, %A_ScriptDir%\%ScriptName%_CopyLog\%ScriptName%_%FileTimeString%_CopyLog\%ScriptName%_%FileTimeString2%_CopyLog.txt
                LogText =
            }
            Else
            If CopyLog = Restricted
                FileAppend, Номер копии: %CopyNumber%`n`nВремя: %TimeString%`n`n`nКопирование № %CopyNumber%`n`nБуфер обмена:`n`n%Clipboard%`n`n`n`n, %A_ScriptDir%\%ScriptName%_CopyLog\%ScriptName%_%FileTimeString%_CopyLog\%ScriptName%_%FileTimeString2%_CopyLog.txt
            CopyErrorTime = 300
            BlockInput, Off
            ToolTip
            Break
        }
    }
}
Return

RepeatCopy:
CopyError = Копирование не удалось.
CopyErrorTime += 700
If CopyLog = Full
{
    FormatTime, FastTimeString, , HH:mm.ss'S'
    LogTextAdd = Ошибка копирования: %CopyError%`n`nВремя: %FastTimeString%`n`nClipKey: %ClipKey%`n`nВремя отложенного копирования: %CopyErrorTime% ms.
    LogText = %LogText%`n`n%LogTextAdd%
}

Send ^{sc02E} ; Ctrl + C
ClipWait

SetTimer, RepeatCopy, Off
SetTimer, RepeatCopy, %CopyErrorTime%
Return

ChangeClipTag:
Loop
{
    Random, ClipTagNew , 10, 99
    If ClipTagNew = %ClipTag%
        Continue
    Else
    {
       ClipTag = %ClipTagNew%
        Break
    }
}
Return

WrappingAroundCopyAndCheck: ; Конец обтекания строк.

; Конец CopyAndCheck

Есть проблема с функцией поиска строк. Никак не могу понять, почему строки фактически не сходятся со строкой, на ошибку в которой указывает AHK.

Post's attachments

AHK Script Saver.ico 110.46 kb, 2 downloads since 2019-10-28 

You don't have the permssions to download the attachments of this post.

2

Re: AHK: Script Saver

Bulef пишет:

логирования версий, логирования копирований, перемещения и функция переименования скриптов.

Добро пожаловать в клуб пользователей систем версионирования! Я лично пользуюсь системой от товарища Линуса, уверен и вы туда придете со временем. Некоторый порог входа конечно есть, но в итоге она заменит вам ваш велосипед, облако, и будет даже удобнее.

3 (изменено: Bulef, 2019-10-29 10:51:48)

Re: AHK: Script Saver

stealzy пишет:
Bulef пишет:

логирования версий, логирования копирований, перемещения и функция переименования скриптов.

Добро пожаловать в клуб пользователей систем версионирования! Я лично пользуюсь системой от товарища Линуса, уверен и вы туда придете со временем. Некоторый порог входа конечно есть, но в итоге она заменит вам ваш велосипед, облако, и будет даже удобнее.

Спасибо за ответ. Я предполагал, что изобрёл велосипед.
А где можно почитать про это? Я только Торвальдса Линуса знаю. Про него идёт речь?

4

Re: AHK: Script Saver

Да, про него .