超时退出，不弹出提示

超时退出，不弹出提示

;自动输入用户名/密码信息
<KeePassAutoType>:
{
	If not WinExist("ahk_exe KeePass.exe")
	{
		WinGetClass, class, A

		pid := OpenKeePass()
		if pid = 0
			return

		;检测直到确认打开了数据库
		data :=""
		IniRead data, %ConfigPath%, KeePass_Config, DataPath, ""
		if data = ""
		{
			msgbox, 尚未配置KeePass的数据路径：KeePass_Config/DataPath
			return
		}
		file := ""
		Loop, parse, data, `\
		{
		    file := A_LoopField
		}
		WinWait ,%file% - KeePass ahk_class WindowsForms10.Window.8.app.0.33c0d9d,,9
		;超时退出
		if ErrorLevel
			return

		winhide,ahk_class WindowsForms10.Window.8.app.0.33c0d9d
		WinActivate,ahk_class %class%
	}

	AutoType()
	return
}

<KeePassOpen>:
{
	if not WinExist("ahk_exe KeePass.exe")
		OpenKeePass()

	WinShow , ahk_class WindowsForms10.Window.8.app.0.33c0d9d
	WinActivate ,ahk_class WindowsForms10.Window.8.app.0.33c0d9d
	return
}

;打开KeePass
OpenKeePass(){
	app := ""
	IniRead app, %ConfigPath%, KeePass_Config, AppPath, ""
	if app = ""
	{
		msgbox, 尚未配置KeePass的执行路径：KeePass_Config/Path
		return 0
	}

	data :=""
	IniRead data, %ConfigPath%, KeePass_Config, DataPath, ""
	if data = ""
	{
		msgbox, 尚未配置KeePass的数据路径：KeePass_Config/DataPath
		return 0
	}

	Run, %app% %data%

	pid := 0
	Loop,4
	{
		Process, Exist, KeePass.exe
		pid := ErrorLevel
		if pid
			return pid
		Sleep,500
	}

	if pid = 0
	{
		MsgBox 未能启动KeePass，请参考帮助文件配置启动参数
		return 0
	}

	return pid
}

AutoType(){
	app := ""
	IniRead app, %ConfigPath%, KeePass_Config, AppPath, ""
	if app = ""
	{
		msgbox, 尚未配置KeePass的执行路径：KeePass_Config/Path
		return 0
	}

	Run, %app% -auto-type
}

;自动输入用户名/密码信息
<KeePassAutoType>:
{
	If not WinExist("ahk_exe KeePass.exe")
	{
		WinGetClass, class, A

		pid := OpenKeePass()
		if pid = 0
			return

		;检测直到确认打开了数据库
		data :=""
		IniRead data, %ConfigPath%, KeePass_Config, DataPath, ""
		if data = ""
		{
			msgbox, 尚未配置KeePass的数据路径：KeePass_Config/DataPath
			return
		}
		file := ""
		Loop, parse, data, `\
		{
		    file := A_LoopField
		}
		WinWait ,%file% - KeePass ahk_class WindowsForms10.Window.8.app.0.33c0d9d,,9
		if ErrorLevel
		{
			msgbox error
			return
		}

		winhide,ahk_class WindowsForms10.Window.8.app.0.33c0d9d
		WinActivate,ahk_class %class%
	}

	AutoType()
	return
}

<KeePassOpen>:
{
	if not WinExist("ahk_exe KeePass.exe")
		OpenKeePass()

	WinShow , ahk_class WindowsForms10.Window.8.app.0.33c0d9d
	WinActivate ,ahk_class WindowsForms10.Window.8.app.0.33c0d9d
	return
}

;打开KeePass
OpenKeePass(){
	app := ""
	IniRead app, %ConfigPath%, KeePass_Config, AppPath, ""
	if app = ""
	{
		msgbox, 尚未配置KeePass的执行路径：KeePass_Config/Path
		return 0
	}

	data :=""
	IniRead data, %ConfigPath%, KeePass_Config, DataPath, ""
	if data = ""
	{
		msgbox, 尚未配置KeePass的数据路径：KeePass_Config/DataPath
		return 0
	}

	Run, %app% %data%

	pid := 0
	Loop,4
	{
		Process, Exist, KeePass.exe
		pid := ErrorLevel
		if pid
			return pid
		Sleep,500
	}

	if pid = 0
	{
		MsgBox 未能启动KeePass，请参考帮助文件配置启动参数
		return 0
	}

	return pid
}

AutoType(){
	app := ""
	IniRead app, %ConfigPath%, KeePass_Config, AppPath, ""
	if app = ""
	{
		msgbox, 尚未配置KeePass的执行路径：KeePass_Config/Path
		return 0
	}

	Run, %app% -auto-type
}


Updated the location of the installer.

Updated the location of the installer.

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
SetTitleMatchMode, RegEx

; Uninstall any previous versions...
uninstaller = %A_SYSTEMDRIVE%\python\Removepywin32.exe

IfExist, %uninstaller%
{
    Sleep, 1000
	Run, "%uninstaller%" -u "%A_SYSTEMDRIVE%\python\pywin32-wininst.log"

	WinWait, Please confirm,, 30
	IfWinExist
	{
		BlockInput, On
		Sleep, 250
		WinActivate
		Send, {ALTDOWN}y{ALTUP}
		BlockInput, Off
	}

	WinWait, Uninstall Finished,, 30
	IfWinExist
	{
		BlockInput, On
		Sleep, 250
		WinActivate
		Send, {ENTER}
		BlockInput, Off
	}
}

; Install
installer = %A_Temp%\python\pywin32.exe
Sleep, 1000
Run, %installer%

WinWaitActive, Setup,, 30
IfWinExist
{
    Loop, 3
    {
        BlockInput, On
        Sleep, 250
        WinActivate, Setup
        Send, {ALTDOWN}n{ALTUP}
    }
}

WinWaitActive, Setup,Postinstall script finished, 60
IfWinExist
{
    BlockInput, On
    Sleep, 250
    WinActivate, Setup
    Send, {ENTER}
}

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
SetTitleMatchMode, RegEx

; Uninstall any previous versions...
uninstaller = %A_SYSTEMDRIVE%\python\Removepywin32.exe

IfExist, %uninstaller%
{
    Sleep, 1000
	Run, "%uninstaller%" -u "%A_SYSTEMDRIVE%\python\pywin32-wininst.log"

	WinWait, Please confirm,, 30
	IfWinExist
	{
		BlockInput, On
		Sleep, 250
		WinActivate
		Send, {ALTDOWN}y{ALTUP}
		BlockInput, Off
	}

	WinWait, Uninstall Finished,, 30
	IfWinExist
	{
		BlockInput, On
		Sleep, 250
		WinActivate
		Send, {ENTER}
		BlockInput, Off
	}
}

; Install
installer = %A_Temp%\chocolatey\python\pywin32.exe
Sleep, 1000
Run, %installer%

WinWaitActive, Setup,, 30
IfWinExist
{
    Loop, 3
    {
        BlockInput, On
        Sleep, 250
        WinActivate, Setup
        Send, {ALTDOWN}n{ALTUP}
    }
}

WinWaitActive, Setup,Postinstall script finished, 60
IfWinExist
{
    BlockInput, On
    Sleep, 250
    WinActivate, Setup
    Send, {ENTER}
}


changed vim launch to emacs launch...

changed vim launch to emacs launch...

It is a dark day indeed.

;Replaces the default Win+E shortcut with XYplorer
#e::
run C:\Program Files (x86)\XYplorer\XYplorer.exe
return

;Ctrl + Alt + R -- reloads current script
^!r::Reload

;Alt + Win + E -- Opens this file
!#e::
EnvGet, HOME, HOMEPATH
run "gvim" "%HOME%\.dotfiles\autohotkey-scripts\my_keyboard_shortcuts.ahk"
Return

;shortcuts for Vim

Capslock::Ctrl

OpenWithVim() ;opens current file in vim if using XYPlorer, else opens vim
{
	EnvGet, DROPBOX, DB_HOME
	oldClipboard = %clipboard%
	IfWinActive, ahk_class ThunderRT6FormDC
	{
		SendInput ^p
		Sleep, 100
		Run, "runemacs" "%clipboard%"
		clipboard = %oldClipboard%
	}
	Else
	{
		Run, "runemacs", C:\users\nate
	}
}

Pause::
OpenWithVim()
Return

Insert::
OpenWithVim()
Return

;Replaces the default Win+E shortcut with XYplorer
#e::
run C:\Program Files (x86)\XYplorer\XYplorer.exe
return

;Ctrl + Alt + R -- reloads current script
^!r::Reload

;Alt + Win + E -- Opens this file
!#e::
EnvGet, HOME, HOMEPATH
run "gvim" "%HOME%\.dotfiles\autohotkey-scripts\my_keyboard_shortcuts.ahk"
Return

;shortcuts for Vim

Capslock::Ctrl

OpenWithVim() ;opens current file in vim if using XYPlorer, else opens vim
{
	EnvGet, DROPBOX, DB_HOME
	oldClipboard = %clipboard%
	IfWinActive, ahk_class ThunderRT6FormDC
	{
		SendInput ^p
		Sleep, 100
		Run, "gvim" "%clipboard%"
		clipboard = %oldClipboard%
	}
	Else
	{
		Run, "gvim" +star, C:\users\nate
	}
}

Pause::
OpenWithVim()
Return

Insert::
OpenWithVim()
Return


added bit detection

added bit detection

; ===================================================================================
; AHK Version .........: 1.1.22.04
; Version .............: 1.00 (AHK)
; Release Date ........: 2015-08-22
; GitHub ..............: https://github.com/chao-samu/demo-file-renamer
; Author ..............: chao-samu
;------------------------------------------------------------------------------------
; Script Name..........: demo file renamer
; Description .........: Integrate mapname into demofile (*.dem).
;						 Support: TF2, CS 1.6, CS:S and CS:GO
; License..............: MIT License (https://github.com/chao-samu/demo-file-renamer/blob/master/LICENSE)
; ===================================================================================

#NoEnv
#NoTrayIcon
SendMode Input
SetWorkingDir %A_ScriptDir%
PrgName := "Demo file renamer"
PrgVersion := "1.00 (AHK)"
If (A_PtrSize = 4)
{
	BitVersion := "x86"
}
else
{
	BitVersion := "x64"
}

Menu, helpmenu, Add, Help , MenuHelp
Menu, helpmenu, Add
Menu, helpmenu, Add, About, MenuAbout
Menu, topmenu, Add, &Help, :helpmenu
Gui, Menu, topmenu

Gui, Add, Button, x12 y180 w90 h20 , Cancel
Gui, Add, Button, x212 y180 w90 h20 , Start
Gui, Add, Text, x12 y120 w290 h20 vtext_prog, Extracting mapname
Gui, Add, ListBox, x12 y30 w290 h30 vRenamingMask AltSubmit gpressListBox, OLDNAME_MAPNAME||MAPNAME_OLDNAME|YYYY-MM-DD_MAPNAME_OLDNAME|YYYY-MM-DD_OLDNAME_MAPNAME
Gui, Add, Text, x12 y10 w290 h20 , Choose renaming mask
Gui, Add, Text, x12 y70 w290 h40 vtext_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "samurai-vs-ninja_de_dust2.dem"

Gui, Add, Progress, x12 y140 w290 h10 Backgroundsilver vProgressBar
; Generated using SmartGUI Creator for SciTE
Gui, Show, w323 h221, %PrgName%
return

MenuHelp:
Gui, Help:+owner1
Gui +Disabled
Gui, Help:Add, Text,,
((
What can do this Tool?
This tool was manly made to extract out the mapname of
GoldSrc- and Source Engine demofiles and place it in the name of the demofile itself.

Which kind of demofiles this tool can handle?
Currently this tool support Counter-Strike 1.6, Counter-Strike Source,
Counter-Strike Global Office and Team Fortress 2 demofiles.

How to use?
1. Select your renaming mask you want
2. Press start and select in the following window your folder with the supported demofiles
    (please note, all demofiles with the ending "dem" in this folder will be renamed, subfolder
    are not included).
    In a protected folder (like "ProgramFiles") you have to start this program in admin mode!
3. Press OK and wait until you will hopefully be happy :)
)
Gui, Help:Add, Button, Default, OK
Gui, Help:Show, w450 h230, Help
return

MenuAbout:
Gui, About:+owner1
Gui +Disabled
Gui, About:Add, Link,, %PrgName% - Version %PrgVersion% `n`nTool compiled with: AHK %A_AhkVersion% %BitVersion% `n`nLook for updates:`n<a href="https://github.com/chao-samu">https://github.com/chao-samu</a>`n`nMade by chao-samu
Gui, About:Add, Button, Default, OK
Gui, About:Show, w250 h150, About
return

HelpButtonOK:
HelpGuiClose:
HelpGuiEscape:
AboutButtonOK:
AboutGuiClose:
AboutGuiEscape:
Gui, 1:-Disabled
Gui Destroy
return

pressListBox:
	Gui, Submit, NoHide
	if (RenamingMask = 1)
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "samurai-vs-ninja_de_dust2.dem"
	else if (RenamingMask = 2)
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "de_dust2_samurai-vs-ninja.dem"
	else if (RenamingMask = 3)
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "2007-05-03_de_dust2_samurai-vs-ninja.dem"
	else
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "2007-05-03_samurai-vs-ninja_de_dust2.dem"
return

ButtonStart:
FormatTime, current_time
folder_demofiles := ""
filelist := ""
filelist_failed := ""
counter_files := ""
counter_failed := ""
counter_successfully := ""
logfile_counter := 1
GuiControl, Disable, Start
GuiControl, Disable, RenamingMask
GuiControlGet, RenamingMask
FileSelectFolder, folder_demofiles,, 0, Please select your folder where your demofiles are. `nAll files with the ending *.dem will be renamed.
if ErrorLevel=0
{
	SetWorkingDir %folder_demofiles%
	Loop, Files, *.dem
	{
		counter_files += 1
	}
	If counter_files ;not empty or zero
	{
		counter_files_quotient := 100 / counter_files

		if (RenamingMask = 1)
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					filelist := filelist . A_LoopFileName . "`t" . FileNameNoExt . "_" . Mapname . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		else if (RenamingMask = 2)
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					filelist := filelist . A_LoopFileName . "`t" . Mapname . "_" .  FileNameNoExt . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		else if (RenamingMask = 3)
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					FormatTime, mod_date, %A_LoopFileTimeModified%, yyyy-MM-dd
					filelist := filelist . A_LoopFileName . "`t" . mod_date . "_" . Mapname . "_" . FileNameNoExt . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		else
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					FormatTime, mod_date, %A_LoopFileTimeModified%, yyyy-MM-dd
					filelist := filelist . A_LoopFileName . "`t" . mod_date . "_" . FileNameNoExt . "_" . Mapname . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		GuiControl, Disable, Cancel
		GuiControl,, text_prog, Renaming Files
		Loop, Parse, filelist, `n
		{
			 filelist_array := StrSplit(A_LoopField, A_Tab)
			 Source :=  filelist_array[1]
			 Destination :=  filelist_array[2]
			 FileMove, %Source%, %Destination%
		}
		If filelist_failed
		{
			logfile_name := "Demofile_renamer_logfile.txt"
			logfile := "Renaming from " current_time " in " A_WorkingDir " `n`nThe following files aren't renamed because the map wasn't found in the demofile: `n`n" . filelist_failed . "`n`nWhat you can do: `n- Execute the demofile in your game or `n- Open the file in an editor and search for the word ""maps"" `n`nBe sure the demofile is a CS 1.6, CS:S, CS:GO or TF2 demofile."

			IfExist, %A_ScriptDir%\%logfile_name%
			{
			filetrue := "A"
				while (filetrue <> "")
				{
				logfile_counter +=1
				logfile_name := "Demofile_renamer_logfile(" . logfile_counter . ").txt"
				filetrue := FileExist(logfile_name)
				}
				FileAppend, %logfile%, %A_ScriptDir%\%logfile_name%
			}
			else
			{
				FileAppend, %logfile%, %A_ScriptDir%\%logfile_name%
			}

			counter_successfully := counter_files - counter_failed
			logfile_path := A_WorkingDir . "\" . logfile_name
			msgbox % counter_successfully " out of " counter_files " files were successfully renamed. `n" "There are " counter_failed " that aren't renamed. `n`nLogfile is generated, please look for further information in logfile: `n" logfile_path
		}
		else
		{
			MsgBox, 0, , All demofiles successfully renamed!
		}
		GuiControl,, ProgressBar, 0
		GuiControl,, text_prog, Extracting mapname
		GuiControl, Enable, RenamingMask
		GuiControl, Enable, Cancel
		GuiControl, Enable, Start
		return
	}
	else
	{
		MsgBox % "No files found!"
		GuiControl,, ProgressBar, 0
		GuiControl, Enable, RenamingMask
		GuiControl, Enable, Cancel
		GuiControl, Enable, Start
		return
	}
}
else
{
	GuiControl,, ProgressBar, 0
	GuiControl, Enable, RenamingMask
	GuiControl, Enable, Start
	return
}

ButtonCancel:
GuiClose:
ExitApp

; ===================================================================================
; AHK Version .........: 1.1.22.04
; Version .............: 1.00 (AHK)
; Release Date ........: 2015-08-22
; GitHub ..............: https://github.com/chao-samu/demo-file-renamer
; Author ..............: chao-samu
;------------------------------------------------------------------------------------
; Script Name..........: demo file renamer
; Description .........: Integrate mapname into demofile (*.dem).
;						 Support: TF2, CS 1.6, CS:S and CS:GO
; License..............: MIT License (https://github.com/chao-samu/demo-file-renamer/blob/master/LICENSE)
; ===================================================================================

#NoEnv
#NoTrayIcon
SendMode Input
SetWorkingDir %A_ScriptDir%
If %A_PtrSize% = 4
{
BitVersion := "x86"
}
else
{
BitVersion := "x64"
}
PrgVersion := "1.00 (AHK)"
PrgName := "Demo file rename tool"

Menu, helpmenu, Add, Help , MenuHelp
Menu, helpmenu, Add
Menu, helpmenu, Add, About, MenuAbout
Menu, topmenu, Add, &Help, :helpmenu
Gui, Menu, topmenu

Gui, Add, Button, x12 y180 w90 h20 , Cancel
Gui, Add, Button, x212 y180 w90 h20 , Start
Gui, Add, Text, x12 y120 w290 h20 vtext_prog, Extracting mapname
Gui, Add, ListBox, x12 y30 w290 h30 vRenamingMask AltSubmit gpressListBox, OLDNAME_MAPNAME||MAPNAME_OLDNAME|YYYY-MM-DD_MAPNAME_OLDNAME|YYYY-MM-DD_OLDNAME_MAPNAME
Gui, Add, Text, x12 y10 w290 h20 , Choose renaming mask
Gui, Add, Text, x12 y70 w290 h40 vtext_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "samurai-vs-ninja_de_dust2.dem"

Gui, Add, Progress, x12 y140 w290 h10 Backgroundsilver vProgressBar
; Generated using SmartGUI Creator for SciTE
Gui, Show, w323 h221, %PrgName%
return

MenuHelp:
Gui, Help:+owner1
Gui +Disabled
Gui, Help:Add, Text,,
((
What can do this Tool?
This tool was manly made to extract out the mapname of
GoldSrc- and Source Engine demofiles and place it in the name of the demofile itself.

Which kind of demofiles this tool can handle?
Currently this tool support Counter-Strike 1.6, Counter-Strike Source,
Counter-Strike Global Office and Team Fortress 2 demofiles.

How to use?
1. Select your renaming mask you want
2. Press start and select in the following window your folder with the supported demofiles
    (please note, all demofiles with the ending "dem" in this folder will be renamed, subfolder
    are not included).
    In a protected folder (like "ProgramFiles") you have to start this program in admin mode!
3. Press OK and wait until you will hopefully be happy :)
)
Gui, Help:Add, Button, Default, OK
Gui, Help:Show, w450 h230, Help
return

MenuAbout:
Gui, About:+owner1
Gui +Disabled
Gui, About:Add, Link,, %PrgName% - Version %PrgVersion% `n`nTool compiled with: AHK %A_AhkVersion% %BitVersion% `n`nLook for updates:`n<a href="https://github.com/chao-samu">https://github.com/chao-samu</a>`n`nMade by chao-samu
Gui, About:Add, Button, Default, OK
Gui, About:Show, w250 h150, About
return

HelpButtonOK:
HelpGuiClose:
HelpGuiEscape:
AboutButtonOK:
AboutGuiClose:
AboutGuiEscape:
Gui, 1:-Disabled
Gui Destroy
return

pressListBox:
	Gui, Submit, NoHide
	if (RenamingMask = 1)
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "samurai-vs-ninja_de_dust2.dem"
	else if (RenamingMask = 2)
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "de_dust2_samurai-vs-ninja.dem"
	else if (RenamingMask = 3)
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "2007-05-03_de_dust2_samurai-vs-ninja.dem"
	else
	GuiControl,, text_example, Example: `n"samurai-vs-ninja.dem" will be renamed to "2007-05-03_samurai-vs-ninja_de_dust2.dem"
return

ButtonStart:
FormatTime, current_time
folder_demofiles := ""
filelist := ""
filelist_failed := ""
counter_files := ""
counter_failed := ""
counter_successfully := ""
logfile_counter := 1
GuiControl, Disable, Start
GuiControl, Disable, RenamingMask
GuiControlGet, RenamingMask
FileSelectFolder, folder_demofiles,, 0, Please select your folder where your demofiles are. `nAll files with the ending *.dem will be renamed.
if ErrorLevel=0
{
	SetWorkingDir %folder_demofiles%
	Loop, Files, *.dem
	{
		counter_files += 1
	}
	If counter_files ;not empty or zero
	{
		counter_files_quotient := 100 / counter_files

		if (RenamingMask = 1)
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					filelist := filelist . A_LoopFileName . "`t" . FileNameNoExt . "_" . Mapname . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		else if (RenamingMask = 2)
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					filelist := filelist . A_LoopFileName . "`t" . Mapname . "_" .  FileNameNoExt . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		else if (RenamingMask = 3)
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					FormatTime, mod_date, %A_LoopFileTimeModified%, yyyy-MM-dd
					filelist := filelist . A_LoopFileName . "`t" . mod_date . "_" . Mapname . "_" . FileNameNoExt . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		else
		{
			Loop, Files, *.dem
			{
				counter_prog := counter_files_quotient * A_Index
				GuiControl,, ProgressBar, %counter_prog%
				FileRead, demofile, %A_LoopFileName%
				RegExMatch(demofile, "maps[\/\\].+\.bsp", mapstring)
				mapstring := Format("{1:s}", mapstring)
				If (InStr(mapstring, "maps") and InStr(mapstring, "bsp"))
				{
					RegExMatch(mapstring, "(?<=maps[\/\\]).+(?=\.bsp)", Mapname)
					SplitPath, A_LoopFileName,,,, FileNameNoExt
					FormatTime, mod_date, %A_LoopFileTimeModified%, yyyy-MM-dd
					filelist := filelist . A_LoopFileName . "`t" . mod_date . "_" . FileNameNoExt . "_" . Mapname . "." . A_LoopFileExt . "`n"
				}
				else
				{
					filelist_failed := filelist_failed . A_LoopFileName . "`n"
					counter_failed += 1
				}
			}
		}
		GuiControl, Disable, Cancel
		GuiControl,, text_prog, Renaming Files
		Loop, Parse, filelist, `n
		{
			 filelist_array := StrSplit(A_LoopField, A_Tab)
			 Source :=  filelist_array[1]
			 Destination :=  filelist_array[2]
			 FileMove, %Source%, %Destination%
		}
		If filelist_failed
		{
			logfile_name := "Demofile_renamer_logfile.txt"
			logfile := "Renaming from " current_time " in " A_WorkingDir " `n`nThe following files aren't renamed because the map wasn't found in the demofile: `n`n" . filelist_failed . "`n`nWhat you can do: `n- Execute the demofile in your game or `n- Open the file in an editor and search for the word ""maps"" `n`nBe sure the demofile is a CS 1.6, CS:S, CS:GO or TF2 demofile."

			IfExist, %A_ScriptDir%\%logfile_name%
			{
			filetrue := "A"
				while (filetrue <> "")
				{
				logfile_counter +=1
				logfile_name := "Demofile_renamer_logfile(" . logfile_counter . ").txt"
				filetrue := FileExist(logfile_name)
				}
				FileAppend, %logfile%, %A_ScriptDir%\%logfile_name%
			}
			else
			{
				FileAppend, %logfile%, %A_ScriptDir%\%logfile_name%
			}

			counter_successfully := counter_files - counter_failed
			logfile_path := A_WorkingDir . "\" . logfile_name
			msgbox % counter_successfully " out of " counter_files " files were successfully renamed. `n" "There are " counter_failed " that aren't renamed. `n`nLogfile is generated, please look for further information in logfile: `n" logfile_path
		}
		else
		{
			MsgBox, 0, , All demofiles successfully renamed!
		}
		GuiControl,, ProgressBar, 0
		GuiControl,, text_prog, Extracting mapname
		GuiControl, Enable, RenamingMask
		GuiControl, Enable, Cancel
		GuiControl, Enable, Start
		return
	}
	else
	{
		MsgBox % "No files found!"
		GuiControl,, ProgressBar, 0
		GuiControl, Enable, RenamingMask
		GuiControl, Enable, Cancel
		GuiControl, Enable, Start
		return
	}
}
else
{
	GuiControl,, ProgressBar, 0
	GuiControl, Enable, RenamingMask
	GuiControl, Enable, Start
	return
}

ButtonCancel:
GuiClose:
ExitApp


Use Gui -Caption to hide title

Use Gui -Caption to hide title

#NoEnv
#SingleInstance, Force
#NoTrayIcon

FileEncoding, utf-8
SendMode Input

; 自动生成的命令文件
global g_SearchFileList := A_ScriptDir . "\SearchFileList.txt"
; 配置文件
global g_ConfFile := A_ScriptDir . "\RunZ.ini"

if !FileExist(g_ConfFile)
{
    if (FileExist(g_ConfFile ".EasyIni.bak"))
    {
        MsgBox, % "发现上次写入配置的备份文件：`n"
            . g_ConfFile . ".EasyIni.bak"
            . "`n确定则将其恢复，否则请手动检查文件内容再继续"
        FileMove, % g_ConfFile ".EasyIni.bak", % g_ConfFile
    }
    else
    {
        FileCopy, %g_ConfFile%.help.txt, %g_ConfFile%
    }
}

global g_Conf := class_EasyINI(g_ConfFile)

; 不能是 RunZ.ahk 的子串，否则按键绑定会有问题
global g_WindowName := "RunZ "
; 所有命令
global g_Commands
; 当搜索无结果时使用的命令
global g_FallbackCommands
; 编辑框当前内容
global g_CurrentInput
; 当前匹配到的第一条命令
global g_CurrentCommand
; 当前匹配到的所有命令
global g_CurrentCommandList
; 是否启用 TCMatch
global g_EnableTCMatch = TCMatchOn(g_Conf.Config.TCMatchPath)
; 列表第一列的首字母或数字
global g_FirstChar := Asc(g_Conf.Gui.FirstChar)
; 在列表中显示的行数
global g_DisplayRows := g_Conf.Gui.DisplayRows
; 在列表中显示的文字列数（多出的会被截断）
global g_DisplayCols := g_Conf.Gui.DisplayCols
; 命令使用了显示框
global g_UseDisplay
; 历史命令
global g_HistoryCommands
; 运行命令时临时设置，避免因为自身退出无法运行需要提权的软件
global g_DisableAutoExit
; 当前输入命令的参数，数组，为了方便没有添加 g_ 前缀
global Arg

if (FileExist(g_SearchFileList))
{
    LoadFiles()
}
else
{
    GoSub, ReloadFiles
}

Gui, Font, % "s" g_Conf.Gui.FontSize, % g_Conf.Gui.FontName
Gui, Add, Edit, % "gProcessInputCommand vSearchArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
Gui, Add, Edit, % "ReadOnly vDisplayArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.DisplayAreaHeight
        , % SearchCommand("", true)
if (g_Conf.Gui.ShowCurrentCommand)
{
    Gui, Add, Edit, % "ReadOnly"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
}
if (g_Conf.Gui.HideTitle)
{
    Gui -Caption
}
Gui, Show, , % g_WindowName

if (g_Conf.Config.WindowAlwaysOnTop)
{
    WinSet, AlwaysOnTop, On, A
}

if (g_Conf.Config.ExitIfInactivate)
{
    OnMessage(0x06, "WM_ACTIVATE")
}

Hotkey, IfWinActive, % g_WindowName
; 如果是 ~enter，有时候会响
Hotkey, enter, RunCurrentCommand
Hotkey, ^j, ClearInput
Hotkey, f1, Help
Hotkey, f2, EditConfig
Hotkey, esc, ExitRunZ
Hotkey, ^d, OpenCurrentFileDir
Hotkey, ^x, DeleteCurrentFile
Hotkey, ^s, ShowCurrentFile
Hotkey, ^r, ReloadFiles
Hotkey, ^h, DisplayHistoryCommands
Hotkey, ^b, DecreaseRank
Hotkey, ^b, DecreaseRank

if (g_Conf.Config.RunInBackground)
{
    Hotkey, esc, WindowMin
}

Loop, % g_DisplayRows
{
    key := Chr(g_FirstChar + A_Index - 1)
    ; lalt +
    Hotkey, <!%key%, RunSelectedCommand1
    ; tab +
    Hotkey, ~%key%, RunSelectedCommand2
    ; shift +
    Hotkey, ~+%key%, IncreaseRank
}

if (g_Conf.Config.SaveInputText && g_Conf.Auto.InputText != "")
{
    Send, % g_Conf.Auto.InputText
}

if (g_Conf.Config.SaveHistory)
{
    g_HistoryCommands := Object()
    LoadHistoryCommands()
}

return

GuiClose:
    GoSub, ExitRunZ
return

ExitRunZ:
    saveConf := false

    if (g_Conf.Config.SaveInputText)
    {
        g_Conf.DeleteKey("Auto", "InputText")
        g_Conf.AddKey("Auto", "InputText", g_CurrentInput)
        saveConf := true
    }

    if (g_Conf.Config.SaveHistory)
    {
        g_Conf.DeleteSection("History")
        g_Conf.AddSection("History")

        for index, element in g_HistoryCommands
        {
            g_Conf.AddKey("History", index, element)
        }

        saveConf := true
    }

    if (g_Conf.AutoRank)
    {
        saveConf := true
    }

    if (saveConf)
    {
        g_Conf.Save()

        Loop
        {
            if (!FileExist(g_ConfFile))
            {
                MsgBox, 配置文件 %g_ConfFile% 写入后丢失，请检查磁盘并点确定来重试
            }
            else
            {
                break
            }
        }

        /*
        应该没有这个问题，备用
        FileGetSize, oldFileSize, %g_ConfFile%
        FileCopy, %g_ConfFile%, %g_ConfFile%.auto.bak
        g_Conf.Save()
        ;...
        FileGetSize, newFileSize, %g_ConfFile%
        if (oldFileSize - newFileSize >= 50)
        {
            MsgBox, % "配置文件 " g_ConfFile
                . "`n减小了 " oldFileSize - newFileSize " 字节"
                . "`n如有疑问请不要退出或重新启动 RunZ，以免配置丢失"
                . "`n配置文件已备份到"
                . "`n" . g_ConfFile . ".auto.bak"
        }
        */
    }

    ExitApp
return

WindowMin:
    WinMinimize, A
return

GenerateSearchFileList()
{
    FileDelete, %g_SearchFileList%

    searchFileType := g_Conf.Config.SearchFileType

    for dirIndex, dir in StrSplit(g_Conf.Config.SearchFileDir, " | ")
    {
        if (InStr(dir, "A_") == 1)
        {
            searchPath := %dir%
        }
        else
        {
            searchPath := dir
        }

        for extIndex, ext in StrSplit(searchFileType, " | ")
        {
            Loop, Files, %searchPath%\%ext%, R
            {
                if (g_Conf.Config.SearchFileExclude != ""
                        && RegexMatch(A_LoopFileLongPath, g_Conf.Config.SearchFileExclude))
                {
                    continue
                }
                FileAppend, file | %A_LoopFileLongPath%`n, %g_SearchFileList%,
            }
        }
    }
}

ReloadFiles:
    GenerateSearchFileList()

    LoadFiles()
return

ProcessInputCommand:
    GuiControlGet, g_CurrentInput, , SearchArea
    SearchCommand(g_CurrentInput)
return

SearchCommand(command = "", firstRun = false)
{
    static useFallbackCommands
    result := ""
    ; 供去重使用
    fullResult := ""
    commandPrefix := SubStr(command, 1, 1)

    if (commandPrefix == ";" || commandPrefix == ":")
    {
        if (commandPrefix == ";")
        {
            g_CurrentCommand := g_FallbackCommands[1]
        }
        else if (commandPrefix == ":")
        {
            g_CurrentCommand := g_FallbackCommands[2]
        }

        g_CurrentCommandList.Push(g_CurrentCommand)
        result .= "a | " . g_CurrentCommand
        Arg := SubStr(g_CurrentInput, 2)
        DisplaySearchResult(result)
        return result
    }
    ; 用空格来判断参数
    else if (InStr(command, " ") && g_CurrentCommand != "")
    {
        if (useFallbackCommands)
        {
            Arg := command
        }
        else
        {
            Arg := SubStr(command, InStr(command, " ") + 1)
        }
        return
    }

    g_CurrentCommandList := Object()

    order := g_FirstChar

    for index, element in g_Commands
    {
        if (InStr(fullResult, element "`n"))
        {
            continue
        }

        splitedElement := StrSplit(element, " | ")

        if (splitedElement[1] == "file")
        {
            SplitPath, % splitedElement[2], , fileDir, , fileNameNoExt

            ; 只搜索和展示不带扩展名的文件名
            elementToSearch := fileNameNoExt
            elementToShow := "file | " . fileNameNoExt

            if (splitedElement.Length() >= 3)
            {
                elementToSearch .= " " . splitedElement[3]
                elementToShow .= "（" . splitedElement[3] . "）"
            }

            elementToShow := SubStr(elementToShow, 1, g_DisplayCols)

            if (g_Conf.Config.SearchFullPath)
            {
                ; TCMatch 在搜索路径时只搜索文件名，强行将 \ 转成空格
                elementToSearch := StrReplace(fileDir, "\", " ") . " " . elementToSearch
            }
        }
        else
        {
            elementToShow := SubStr(element, 1, g_DisplayCols)
            elementToSearch := splitedElement[2]
        }

        if (MatchCommand(elementToSearch, command))
        {
            fullResult .= element "`n"
            g_CurrentCommandList.Push(element)

            if (order == g_FirstChar)
            {
                g_CurrentCommand := element
            }
            else
            {
                result .= "`n"
            }

            result .= Chr(order++) . " | " . elementToShow

            if (order - g_FirstChar >= g_DisplayRows)
            {
                break
            }
            ; 第一次运行只加载 function 类型
            if (firstRun && (order - g_FirstChar >= g_DisplayRows - 4))
            {
                result .= "`n`n现有 " g_Commands.Length() " 条命令。"
                result .= "`n`n键入内容 搜索，回车 执行第一条，Alt + 字母 执行，F1 帮助，Esc 退出。"

                break
            }
        }
    }

    if (result == "")
    {
        useFallbackCommands := true
        g_CurrentCommand := g_FallbackCommands[1]
        g_CurrentCommandList := g_FallbackCommands
        Arg := g_CurrentInput

        for index, element in g_FallbackCommands
        {
            if (index != 1)
            {
                result .= "`n"
            }

            result .= Chr(g_FirstChar - 1 + index++) . " | " . element
        }
    }
    else
    {
        useFallbackCommands := false
    }

    DisplaySearchResult(result)
    return result
}

DisplaySearchResult(result)
{
    DisplayText(result)

    if (g_CurrentCommandList.Length() == 1 && g_Conf.Config.RunIfOnlyOne)
    {
        GoSub, RunCurrentCommand
    }

    if (g_Conf.Gui.ShowCurrentCommand)
    {
        ControlSetText, Edit3, %g_CurrentCommand%
    }
}

ClearInput:
    ControlSetText, Edit1,
return

RunCurrentCommand:
    if (GetInputState() == 1)
    {
        Send, {enter}
    }

    if (g_CurrentInput != "")
    {
        g_UseDisplay := false

        RunCommand(g_CurrentCommand)
        if (g_Conf.Config.RunOnce && !g_UseDisplay)
        {
            GoSub, ExitRunZ
        }
    }
return

MatchCommand(Haystack, Needle)
{
    if (g_EnableTCMatch)
    {
        return TCMatch(Haystack, Needle)
    }

    return InStr(Haystack, Needle)
}

RunCommand(originCmd)
{
    g_DisableAutoExit := true

    splitedOriginCmd := StrSplit(originCmd, " | ")
    ; 去掉括号内的注释
    cmd := StrSplit(splitedOriginCmd[2], "（")[1]

    if (splitedOriginCmd[1] == "file" || splitedOriginCmd[1] == "url")
    {
        if (InStr(cmd, ".lnk"))
        {
            ; 处理 32 位 ahk 运行不了某些 64 位系统 .lnk 的问题
            FileGetShortcut, %cmd%, filePath
            if (!FileExist(filePath))
            {
                filePath := StrReplace(filePath, "C:\Program Files (x86)", "C:\Program Files")
                if (FileExist(filePath))
                {
                    cmd := filePath
                }
            }
        }

        Run, %cmd%
    }
    else if (splitedOriginCmd[1] == "function")
    {
        if (splitedOriginCmd.Length() >= 3)
        {
            Arg := splitedOriginCmd[3]
        }

        if (IsLabel(cmd))
        {
            GoSub, %cmd%
        }
    }
    else if (splitedOriginCmd[1] == "cmd")
    {
        RunWithCmd(cmd)
    }

    if (g_Conf.Config.SaveHistory && cmd != "DisplayHistoryCommands")
    {
        if (splitedOriginCmd.Length() == 2 && Arg != "")
        {
            g_HistoryCommands.InsertAt(1, originCmd " | " Arg)
        }
        else
        {
            g_HistoryCommands.InsertAt(1, originCmd)
        }

        if (g_HistoryCommands.Length() > g_Conf.Config.HistorySize)
        {
            g_HistoryCommands.Pop()
        }
    }

    if (g_Conf.Config.AutoRank)
    {
        IncreaseRank(originCmd)
    }

    g_DisableAutoExit := false
}

IncreaseRank(cmd, show = false, inc := 1)
{
    splitedCmd := StrSplit(cmd, " | ")

    if (splitedCmd.Length() >= 3 && splitedCmd[1] == "function")
    {
        ; 去掉参数
        cmd := splitedCmd[1]  " | " splitedCmd[2]
    }

    cmdRank := g_Conf.GetValue("Rank", cmd)
    if cmdRank is integer
    {
        g_Conf.DeleteKey("Rank", cmd)
        cmdRank += inc
    }
    else
    {
        cmdRank := inc
    }

    if (cmdRank > 0)
    {
        g_Conf.AddKey("Rank", cmd, cmdRank)
    }
    else
    {
        cmdRank := 0
    }

    if (show)
    {
        ToolTip, 调整 %cmd% 的权重到 %cmdRank%
        SetTimer, RemoveToolTip, 800
    }
}

RunSelectedCommand1:
    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

RunSelectedCommand2:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 2, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

IncreaseRank:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    if (g_CurrentCommandList[index] != "")
    {
        IncreaseRank(g_CurrentCommandList[index], true)
        LoadFiles()
    }
return

DecreaseRank:
    if (g_CurrentCommand != "")
    {
        IncreaseRank(g_currentCommand, true, -1)
        LoadFiles()
    }
return

LoadFiles()
{
    g_Commands := Object()
    g_FallbackCommands := Object()

    rankString := ""
    for command, rank in g_Conf.Rank
    {
        rankString .= rank "`t" command "`n"
    }

    if (rankString != "")
    {
        Sort, rankString, R N

        Loop, Parse, rankString, `n
        {
            if (A_LoopField == "")
            {
                continue
            }

            g_Commands.Push(StrSplit(A_loopField, "`t")[2])
        }
    }

    for key, value in g_Conf.Command
    {
        if (value != "")
        {
            g_Commands.Push(key . "（" . value "）")
        }
        else
        {
            g_Commands.Push(key)
        }
    }

    if (FileExist(A_ScriptDir "\UserFunctions.ahk"))
    {
        userFunctionLabel := "UserFunctions"
        if (IsLabel(userFunctionLabel))
        {
            GoSub, %userFunctionLabel%
        }
        else
        {
            MsgBox, 未在 %A_ScriptDir%\UserFunctions.ahk 中发现 %userFunctionLabel% 标签，请修改！
        }
    }

    GoSub, Functions

    Loop, Read, %g_SearchFileList%
    {
        g_Commands.Push(A_LoopReadLine)
    }

    if (g_Conf.Config.LoadControlPanelFunctions)
    {
        Loop, Read, %A_ScriptDir%\ControlPanelFunctions.txt
        {
            g_Commands.Push(A_LoopReadLine)
        }
    }
}

DisplayText(text)
{
    textToDisplay := StrReplace(text, "`n", "`r`n")
    ControlSetText, Edit2, %textToDisplay%
}

DisplayResult(result)
{
    DisplayText(result)
    g_UseDisplay := true
}

LoadHistoryCommands()
{
    for key, value in g_Conf.History
    {
        g_HistoryCommands.Push(value)
    }
}

DisplayHistoryCommands:
    result := ""
    g_CurrentCommandList := Object()

    for index, element in g_HistoryCommands
    {
        result .= Chr(g_FirstChar + index - 1) . " | " . element "`n"

        if (index == 1)
        {
            g_CurrentCommand := element
        }

        g_CurrentCommandList.Push(element)
    }

    DisplayResult(result)
return

; AddFunction(label, info, fallback)
@(label, info, fallback = false)
{
    if (!IsLabel(label))
    {
        MsgBox, 未找到 %label% 标签，请检查 %A_ScriptDir%\UserFunctions.ahk 文件格式！
        return
    }

    g_Commands.Push("function | " . label . "（" . info . "）")
    if (fallback)
    {
        g_FallbackCommands.Push("function | " . label . "（" . info . "）")
    }
}

RunAndGetOutput(command)
{
    tempFileName := "RunZ.stdout.log"
    fullCommand = bash -c "%command% &> %tempFileName%"

    if (!FileExist("c:\msys64\usr\bin\bash.exe"))
    {
        fullCommand = %ComSpec% /C "%command% > %tempFileName%"
    }

    RunWait, %fullCommand%, %A_Temp%, Hide
    FileRead, result, %A_Temp%\%tempFileName%
    FileDelete, %A_Temp%\%tempFileName%
    return result
}

RunWithCmd(command)
{
    if (FileExist("c:\msys64\usr\bin\mintty.exe"))
    {
        Run, % "mintty -e sh -c '" command "; read'"
    }
    else
    {
        Run, % ComSpec " /C " command " & pause"
    }
}

OpenPath(filePath)
{
    if (!FileExist(filePath))
    {
        return
    }

    if (FileExist(g_Conf.Config.TCPath))
    {
        TCPath := g_Conf.Config.TCPath
        Run, %TCPath% /O /A /L="%filePath%"
    }
    else
    {
        SplitPath, filePath, , fileDir, ,
        Run, explorer "%fileDir%"
    }
}

GetAllFunctions()
{
    result := ""

    for index, element in g_Commands
    {
        if (InStr(element, "function | ") == 1)
        {
            result .= element "`n"
        }
    }

    return result
}

OpenCurrentFileDir:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]
    OpenPath(filePath)
return

DeleteCurrentFile:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]

    if (!FileExist(filePath))
    {
        return
    }

    FileRecycle, % filePath
    GoSub, ReloadFiles
return

ShowCurrentFile:
    clipboard := StrSplit(g_CurrentCommand, " | ")[2]
    ToolTip, % clipboard
    SetTimer, RemoveToolTip, 800
return

RemoveToolTip:
    ToolTip
    SetTimer, RemoveToolTip, Off
return

WM_ACTIVATE(wParam, lParam)
{
    if (g_DisableAutoExit)
    {
        return
    }

    if (wParam >= 1) ; 窗口激活
    {
        return
    }
    else if (wParam <= 0) ; 窗口非激活
    {
        SetTimer, ToExit, 50
    }
}

ToExit:
    if (!WinExist("RunZ.ahk"))
    {
        GoSub, ExitRunZ
    }

    SetTimer, ToExit, Off
return

UrlDownloadToString(url)
{
    static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
    whr.Open("GET", url, true)
    whr.Send()
    whr.WaitForResponse()
    return whr.ResponseText
}

; 修改自万年书妖的 Candy 里的 SksSub_UrlEncode 函数，用于转换编码。感谢！
UrlEncode(url, enc = "UTF-8")
{
    enc := trim(enc)
    If enc=
        return url
    formatInteger := A_FormatInteger
    SetFormat, IntegerFast, H
    VarSetCapacity(buff, StrPut(url, enc))
    Loop % StrPut(url, &buff, enc) - 1
    {
        byte := NumGet(buff, A_Index-1, "UChar")
        encoded .= byte > 127 or byte <33 ? "%" Substr(byte, 3) : Chr(byte)
    }
    SetFormat, IntegerFast, %formatInteger%
    return encoded
}

; 0：英文 1：中文
GetInputState(WinTitle = "A")
{
    ControlGet, hwnd, HWND, , , %WinTitle%
    if (A_Cursor = "IBeam")
        return 1
    if (WinActive(WinTitle))
    {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize := 4 + 4 + (PtrSize * 6) + 16, 0)
        NumPut(cbSize, stGTI, 0, "UInt")   ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint, 0, Uint, &stGTI)
                         ? NumGet(stGTI, 8 + PtrSize, "UInt") : hwnd
    }
    return DllCall("SendMessage"
        , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint, hwnd)
        , UInt, 0x0283  ;Message : WM_IME_CONTROL
        , Int, 0x0005  ;wParam  : IMC_GETOPENSTATUS
        , Int, 0)      ;lParam  : 0
}

#include %A_ScriptDir%\Lib\EasyIni.ahk
#include %A_ScriptDir%\Lib\TCMatch.ahk
#include %A_ScriptDir%\Lib\Eval.ahk
#include %A_ScriptDir%\Lib\JSON.ahk
#include %A_ScriptDir%\Lib\Kanji\Kanji.ahk
#include %A_ScriptDir%\Functions.ahk
; 用户自定义命令
#include *i %A_ScriptDir%\UserFunctions.ahk

#NoEnv
#SingleInstance, Force
#NoTrayIcon

FileEncoding, utf-8
SendMode Input

; 自动生成的命令文件
global g_SearchFileList := A_ScriptDir . "\SearchFileList.txt"
; 配置文件
global g_ConfFile := A_ScriptDir . "\RunZ.ini"

if !FileExist(g_ConfFile)
{
    if (FileExist(g_ConfFile ".EasyIni.bak"))
    {
        MsgBox, % "发现上次写入配置的备份文件：`n"
            . g_ConfFile . ".EasyIni.bak"
            . "`n确定则将其恢复，否则请手动检查文件内容再继续"
        FileMove, % g_ConfFile ".EasyIni.bak", % g_ConfFile
    }
    else
    {
        FileCopy, %g_ConfFile%.help.txt, %g_ConfFile%
    }
}

global g_Conf := class_EasyINI(g_ConfFile)

; 不能是 RunZ.ahk 的子串，否则按键绑定会有问题
global g_WindowName := "RunZ "
; 所有命令
global g_Commands
; 当搜索无结果时使用的命令
global g_FallbackCommands
; 编辑框当前内容
global g_CurrentInput
; 当前匹配到的第一条命令
global g_CurrentCommand
; 当前匹配到的所有命令
global g_CurrentCommandList
; 是否启用 TCMatch
global g_EnableTCMatch = TCMatchOn(g_Conf.Config.TCMatchPath)
; 列表第一列的首字母或数字
global g_FirstChar := Asc(g_Conf.Gui.FirstChar)
; 在列表中显示的行数
global g_DisplayRows := g_Conf.Gui.DisplayRows
; 在列表中显示的文字列数（多出的会被截断）
global g_DisplayCols := g_Conf.Gui.DisplayCols
; 命令使用了显示框
global g_UseDisplay
; 历史命令
global g_HistoryCommands
; 运行命令时临时设置，避免因为自身退出无法运行需要提权的软件
global g_DisableAutoExit
; 当前输入命令的参数，数组，为了方便没有添加 g_ 前缀
global Arg

if (FileExist(g_SearchFileList))
{
    LoadFiles()
}
else
{
    GoSub, ReloadFiles
}

Gui, Font, % "s" g_Conf.Gui.FontSize, % g_Conf.Gui.FontName
Gui, Add, Edit, % "gProcessInputCommand vSearchArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
Gui, Add, Edit, % "ReadOnly vDisplayArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.DisplayAreaHeight
        , % SearchCommand("", true)
if (g_Conf.Gui.ShowCurrentCommand)
{
    Gui, Add, Edit, % "ReadOnly"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
}
Gui, Show, , % g_WindowName
if (g_Conf.Gui.HideTitle)
{
    WinSet, Style, -0xC00000, A
    WinGetPos, , , , windowHeight, A
    WinMove, A, , , , , % windowHeight - 29
}

if (g_Conf.Config.WindowAlwaysOnTop)
{
    WinSet, AlwaysOnTop, On, A
}

if (g_Conf.Config.ExitIfInactivate)
{
    OnMessage(0x06, "WM_ACTIVATE")
}

Hotkey, IfWinActive, % g_WindowName
; 如果是 ~enter，有时候会响
Hotkey, enter, RunCurrentCommand
Hotkey, ^j, ClearInput
Hotkey, f1, Help
Hotkey, f2, EditConfig
Hotkey, esc, ExitRunZ
Hotkey, ^d, OpenCurrentFileDir
Hotkey, ^x, DeleteCurrentFile
Hotkey, ^s, ShowCurrentFile
Hotkey, ^r, ReloadFiles
Hotkey, ^h, DisplayHistoryCommands
Hotkey, ^b, DecreaseRank
Hotkey, ^b, DecreaseRank

if (g_Conf.Config.RunInBackground)
{
    Hotkey, esc, WindowMin
}

Loop, % g_DisplayRows
{
    key := Chr(g_FirstChar + A_Index - 1)
    ; lalt +
    Hotkey, <!%key%, RunSelectedCommand1
    ; tab +
    Hotkey, ~%key%, RunSelectedCommand2
    ; shift +
    Hotkey, ~+%key%, IncreaseRank
}

if (g_Conf.Config.SaveInputText && g_Conf.Auto.InputText != "")
{
    Send, % g_Conf.Auto.InputText
}

if (g_Conf.Config.SaveHistory)
{
    g_HistoryCommands := Object()
    LoadHistoryCommands()
}

return

GuiClose:
    GoSub, ExitRunZ
return

ExitRunZ:
    saveConf := false

    if (g_Conf.Config.SaveInputText)
    {
        g_Conf.DeleteKey("Auto", "InputText")
        g_Conf.AddKey("Auto", "InputText", g_CurrentInput)
        saveConf := true
    }

    if (g_Conf.Config.SaveHistory)
    {
        g_Conf.DeleteSection("History")
        g_Conf.AddSection("History")

        for index, element in g_HistoryCommands
        {
            g_Conf.AddKey("History", index, element)
        }

        saveConf := true
    }

    if (g_Conf.AutoRank)
    {
        saveConf := true
    }

    if (saveConf)
    {
        g_Conf.Save()

        Loop
        {
            if (!FileExist(g_ConfFile))
            {
                MsgBox, 配置文件 %g_ConfFile% 写入后丢失，请检查磁盘并点确定来重试
            }
            else
            {
                break
            }
        }

        /*
        应该没有这个问题，备用
        FileGetSize, oldFileSize, %g_ConfFile%
        FileCopy, %g_ConfFile%, %g_ConfFile%.auto.bak
        g_Conf.Save()
        ;...
        FileGetSize, newFileSize, %g_ConfFile%
        if (oldFileSize - newFileSize >= 50)
        {
            MsgBox, % "配置文件 " g_ConfFile
                . "`n减小了 " oldFileSize - newFileSize " 字节"
                . "`n如有疑问请不要退出或重新启动 RunZ，以免配置丢失"
                . "`n配置文件已备份到"
                . "`n" . g_ConfFile . ".auto.bak"
        }
        */
    }

    ExitApp
return

WindowMin:
    WinMinimize, A
return

GenerateSearchFileList()
{
    FileDelete, %g_SearchFileList%

    searchFileType := g_Conf.Config.SearchFileType

    for dirIndex, dir in StrSplit(g_Conf.Config.SearchFileDir, " | ")
    {
        if (InStr(dir, "A_") == 1)
        {
            searchPath := %dir%
        }
        else
        {
            searchPath := dir
        }

        for extIndex, ext in StrSplit(searchFileType, " | ")
        {
            Loop, Files, %searchPath%\%ext%, R
            {
                if (g_Conf.Config.SearchFileExclude != ""
                        && RegexMatch(A_LoopFileLongPath, g_Conf.Config.SearchFileExclude))
                {
                    continue
                }
                FileAppend, file | %A_LoopFileLongPath%`n, %g_SearchFileList%,
            }
        }
    }
}

ReloadFiles:
    GenerateSearchFileList()

    LoadFiles()
return

ProcessInputCommand:
    GuiControlGet, g_CurrentInput, , SearchArea
    SearchCommand(g_CurrentInput)
return

SearchCommand(command = "", firstRun = false)
{
    static useFallbackCommands
    result := ""
    ; 供去重使用
    fullResult := ""
    commandPrefix := SubStr(command, 1, 1)

    if (commandPrefix == ";" || commandPrefix == ":")
    {
        if (commandPrefix == ";")
        {
            g_CurrentCommand := g_FallbackCommands[1]
        }
        else if (commandPrefix == ":")
        {
            g_CurrentCommand := g_FallbackCommands[2]
        }

        g_CurrentCommandList.Push(g_CurrentCommand)
        result .= "a | " . g_CurrentCommand
        Arg := SubStr(g_CurrentInput, 2)
        DisplaySearchResult(result)
        return result
    }
    ; 用空格来判断参数
    else if (InStr(command, " ") && g_CurrentCommand != "")
    {
        if (useFallbackCommands)
        {
            Arg := command
        }
        else
        {
            Arg := SubStr(command, InStr(command, " ") + 1)
        }
        return
    }

    g_CurrentCommandList := Object()

    order := g_FirstChar

    for index, element in g_Commands
    {
        if (InStr(fullResult, element "`n"))
        {
            continue
        }

        splitedElement := StrSplit(element, " | ")

        if (splitedElement[1] == "file")
        {
            SplitPath, % splitedElement[2], , fileDir, , fileNameNoExt

            ; 只搜索和展示不带扩展名的文件名
            elementToSearch := fileNameNoExt
            elementToShow := "file | " . fileNameNoExt

            if (splitedElement.Length() >= 3)
            {
                elementToSearch .= " " . splitedElement[3]
                elementToShow .= "（" . splitedElement[3] . "）"
            }

            elementToShow := SubStr(elementToShow, 1, g_DisplayCols)

            if (g_Conf.Config.SearchFullPath)
            {
                ; TCMatch 在搜索路径时只搜索文件名，强行将 \ 转成空格
                elementToSearch := StrReplace(fileDir, "\", " ") . " " . elementToSearch
            }
        }
        else
        {
            elementToShow := SubStr(element, 1, g_DisplayCols)
            elementToSearch := splitedElement[2]
        }

        if (MatchCommand(elementToSearch, command))
        {
            fullResult .= element "`n"
            g_CurrentCommandList.Push(element)

            if (order == g_FirstChar)
            {
                g_CurrentCommand := element
            }
            else
            {
                result .= "`n"
            }

            result .= Chr(order++) . " | " . elementToShow

            if (order - g_FirstChar >= g_DisplayRows)
            {
                break
            }
            ; 第一次运行只加载 function 类型
            if (firstRun && (order - g_FirstChar >= g_DisplayRows - 4))
            {
                result .= "`n`n现有 " g_Commands.Length() " 条命令。"
                result .= "`n`n键入内容 搜索，回车 执行第一条，Alt + 字母 执行，F1 帮助，Esc 退出。"

                break
            }
        }
    }

    if (result == "")
    {
        useFallbackCommands := true
        g_CurrentCommand := g_FallbackCommands[1]
        g_CurrentCommandList := g_FallbackCommands
        Arg := g_CurrentInput

        for index, element in g_FallbackCommands
        {
            if (index != 1)
            {
                result .= "`n"
            }

            result .= Chr(g_FirstChar - 1 + index++) . " | " . element
        }
    }
    else
    {
        useFallbackCommands := false
    }

    DisplaySearchResult(result)
    return result
}

DisplaySearchResult(result)
{
    DisplayText(result)

    if (g_CurrentCommandList.Length() == 1 && g_Conf.Config.RunIfOnlyOne)
    {
        GoSub, RunCurrentCommand
    }

    if (g_Conf.Gui.ShowCurrentCommand)
    {
        ControlSetText, Edit3, %g_CurrentCommand%
    }
}

ClearInput:
    ControlSetText, Edit1,
return

RunCurrentCommand:
    if (GetInputState() == 1)
    {
        Send, {enter}
    }

    if (g_CurrentInput != "")
    {
        g_UseDisplay := false

        RunCommand(g_CurrentCommand)
        if (g_Conf.Config.RunOnce && !g_UseDisplay)
        {
            GoSub, ExitRunZ
        }
    }
return

MatchCommand(Haystack, Needle)
{
    if (g_EnableTCMatch)
    {
        return TCMatch(Haystack, Needle)
    }

    return InStr(Haystack, Needle)
}

RunCommand(originCmd)
{
    g_DisableAutoExit := true

    splitedOriginCmd := StrSplit(originCmd, " | ")
    ; 去掉括号内的注释
    cmd := StrSplit(splitedOriginCmd[2], "（")[1]

    if (splitedOriginCmd[1] == "file" || splitedOriginCmd[1] == "url")
    {
        if (InStr(cmd, ".lnk"))
        {
            ; 处理 32 位 ahk 运行不了某些 64 位系统 .lnk 的问题
            FileGetShortcut, %cmd%, filePath
            if (!FileExist(filePath))
            {
                filePath := StrReplace(filePath, "C:\Program Files (x86)", "C:\Program Files")
                if (FileExist(filePath))
                {
                    cmd := filePath
                }
            }
        }

        Run, %cmd%
    }
    else if (splitedOriginCmd[1] == "function")
    {
        if (splitedOriginCmd.Length() >= 3)
        {
            Arg := splitedOriginCmd[3]
        }

        if (IsLabel(cmd))
        {
            GoSub, %cmd%
        }
    }
    else if (splitedOriginCmd[1] == "cmd")
    {
        RunWithCmd(cmd)
    }

    if (g_Conf.Config.SaveHistory && cmd != "DisplayHistoryCommands")
    {
        if (splitedOriginCmd.Length() == 2 && Arg != "")
        {
            g_HistoryCommands.InsertAt(1, originCmd " | " Arg)
        }
        else
        {
            g_HistoryCommands.InsertAt(1, originCmd)
        }

        if (g_HistoryCommands.Length() > g_Conf.Config.HistorySize)
        {
            g_HistoryCommands.Pop()
        }
    }

    if (g_Conf.Config.AutoRank)
    {
        IncreaseRank(originCmd)
    }

    g_DisableAutoExit := false
}

IncreaseRank(cmd, show = false, inc := 1)
{
    splitedCmd := StrSplit(cmd, " | ")

    if (splitedCmd.Length() >= 3 && splitedCmd[1] == "function")
    {
        ; 去掉参数
        cmd := splitedCmd[1]  " | " splitedCmd[2]
    }

    cmdRank := g_Conf.GetValue("Rank", cmd)
    if cmdRank is integer
    {
        g_Conf.DeleteKey("Rank", cmd)
        cmdRank += inc
    }
    else
    {
        cmdRank := inc
    }

    if (cmdRank > 0)
    {
        g_Conf.AddKey("Rank", cmd, cmdRank)
    }
    else
    {
        cmdRank := 0
    }

    if (show)
    {
        ToolTip, 调整 %cmd% 的权重到 %cmdRank%
        SetTimer, RemoveToolTip, 800
    }
}

RunSelectedCommand1:
    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

RunSelectedCommand2:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 2, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

IncreaseRank:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    if (g_CurrentCommandList[index] != "")
    {
        IncreaseRank(g_CurrentCommandList[index], true)
        LoadFiles()
    }
return

DecreaseRank:
    if (g_CurrentCommand != "")
    {
        IncreaseRank(g_currentCommand, true, -1)
        LoadFiles()
    }
return

LoadFiles()
{
    g_Commands := Object()
    g_FallbackCommands := Object()

    rankString := ""
    for command, rank in g_Conf.Rank
    {
        rankString .= rank "`t" command "`n"
    }

    if (rankString != "")
    {
        Sort, rankString, R N

        Loop, Parse, rankString, `n
        {
            if (A_LoopField == "")
            {
                continue
            }

            g_Commands.Push(StrSplit(A_loopField, "`t")[2])
        }
    }

    for key, value in g_Conf.Command
    {
        if (value != "")
        {
            g_Commands.Push(key . "（" . value "）")
        }
        else
        {
            g_Commands.Push(key)
        }
    }

    if (FileExist(A_ScriptDir "\UserFunctions.ahk"))
    {
        userFunctionLabel := "UserFunctions"
        if (IsLabel(userFunctionLabel))
        {
            GoSub, %userFunctionLabel%
        }
        else
        {
            MsgBox, 未在 %A_ScriptDir%\UserFunctions.ahk 中发现 %userFunctionLabel% 标签，请修改！
        }
    }

    GoSub, Functions

    Loop, Read, %g_SearchFileList%
    {
        g_Commands.Push(A_LoopReadLine)
    }

    if (g_Conf.Config.LoadControlPanelFunctions)
    {
        Loop, Read, %A_ScriptDir%\ControlPanelFunctions.txt
        {
            g_Commands.Push(A_LoopReadLine)
        }
    }
}

DisplayText(text)
{
    textToDisplay := StrReplace(text, "`n", "`r`n")
    ControlSetText, Edit2, %textToDisplay%
}

DisplayResult(result)
{
    DisplayText(result)
    g_UseDisplay := true
}

LoadHistoryCommands()
{
    for key, value in g_Conf.History
    {
        g_HistoryCommands.Push(value)
    }
}

DisplayHistoryCommands:
    result := ""
    g_CurrentCommandList := Object()

    for index, element in g_HistoryCommands
    {
        result .= Chr(g_FirstChar + index - 1) . " | " . element "`n"

        if (index == 1)
        {
            g_CurrentCommand := element
        }

        g_CurrentCommandList.Push(element)
    }

    DisplayResult(result)
return

; AddFunction(label, info, fallback)
@(label, info, fallback = false)
{
    if (!IsLabel(label))
    {
        MsgBox, 未找到 %label% 标签，请检查 %A_ScriptDir%\UserFunctions.ahk 文件格式！
        return
    }

    g_Commands.Push("function | " . label . "（" . info . "）")
    if (fallback)
    {
        g_FallbackCommands.Push("function | " . label . "（" . info . "）")
    }
}

RunAndGetOutput(command)
{
    tempFileName := "RunZ.stdout.log"
    fullCommand = bash -c "%command% &> %tempFileName%"

    if (!FileExist("c:\msys64\usr\bin\bash.exe"))
    {
        fullCommand = %ComSpec% /C "%command% > %tempFileName%"
    }

    RunWait, %fullCommand%, %A_Temp%, Hide
    FileRead, result, %A_Temp%\%tempFileName%
    FileDelete, %A_Temp%\%tempFileName%
    return result
}

RunWithCmd(command)
{
    if (FileExist("c:\msys64\usr\bin\mintty.exe"))
    {
        Run, % "mintty -e sh -c '" command "; read'"
    }
    else
    {
        Run, % ComSpec " /C " command " & pause"
    }
}

OpenPath(filePath)
{
    if (!FileExist(filePath))
    {
        return
    }

    if (FileExist(g_Conf.Config.TCPath))
    {
        TCPath := g_Conf.Config.TCPath
        Run, %TCPath% /O /A /L="%filePath%"
    }
    else
    {
        SplitPath, filePath, , fileDir, ,
        Run, explorer "%fileDir%"
    }
}

GetAllFunctions()
{
    result := ""

    for index, element in g_Commands
    {
        if (InStr(element, "function | ") == 1)
        {
            result .= element "`n"
        }
    }

    return result
}

OpenCurrentFileDir:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]
    OpenPath(filePath)
return

DeleteCurrentFile:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]

    if (!FileExist(filePath))
    {
        return
    }

    FileRecycle, % filePath
    GoSub, ReloadFiles
return

ShowCurrentFile:
    clipboard := StrSplit(g_CurrentCommand, " | ")[2]
    ToolTip, % clipboard
    SetTimer, RemoveToolTip, 800
return

RemoveToolTip:
    ToolTip
    SetTimer, RemoveToolTip, Off
return

WM_ACTIVATE(wParam, lParam)
{
    if (g_DisableAutoExit)
    {
        return
    }

    if (wParam >= 1) ; 窗口激活
    {
        return
    }
    else if (wParam <= 0) ; 窗口非激活
    {
        SetTimer, ToExit, 50
    }
}

ToExit:
    if (!WinExist("RunZ.ahk"))
    {
        GoSub, ExitRunZ
    }

    SetTimer, ToExit, Off
return

UrlDownloadToString(url)
{
    static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
    whr.Open("GET", url, true)
    whr.Send()
    whr.WaitForResponse()
    return whr.ResponseText
}

; 修改自万年书妖的 Candy 里的 SksSub_UrlEncode 函数，用于转换编码。感谢！
UrlEncode(url, enc = "UTF-8")
{
    enc := trim(enc)
    If enc=
        return url
    formatInteger := A_FormatInteger
    SetFormat, IntegerFast, H
    VarSetCapacity(buff, StrPut(url, enc))
    Loop % StrPut(url, &buff, enc) - 1
    {
        byte := NumGet(buff, A_Index-1, "UChar")
        encoded .= byte > 127 or byte <33 ? "%" Substr(byte, 3) : Chr(byte)
    }
    SetFormat, IntegerFast, %formatInteger%
    return encoded
}

; 0：英文 1：中文
GetInputState(WinTitle = "A")
{
    ControlGet, hwnd, HWND, , , %WinTitle%
    if (A_Cursor = "IBeam")
        return 1
    if (WinActive(WinTitle))
    {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize := 4 + 4 + (PtrSize * 6) + 16, 0)
        NumPut(cbSize, stGTI, 0, "UInt")   ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint, 0, Uint, &stGTI)
                         ? NumGet(stGTI, 8 + PtrSize, "UInt") : hwnd
    }
    return DllCall("SendMessage"
        , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint, hwnd)
        , UInt, 0x0283  ;Message : WM_IME_CONTROL
        , Int, 0x0005  ;wParam  : IMC_GETOPENSTATUS
        , Int, 0)      ;lParam  : 0
}

#include %A_ScriptDir%\Lib\EasyIni.ahk
#include %A_ScriptDir%\Lib\TCMatch.ahk
#include %A_ScriptDir%\Lib\Eval.ahk
#include %A_ScriptDir%\Lib\JSON.ahk
#include %A_ScriptDir%\Lib\Kanji\Kanji.ahk
#include %A_ScriptDir%\Functions.ahk
; 用户自定义命令
#include *i %A_ScriptDir%\UserFunctions.ahk