发送文件脚本源码版本
V1
适配win10和 win11
#SingleInstance Force
SendMode Input
SetWorkingDir %A_ScriptDir%; Global variables
global TaskList := []
global CurrentFileConfig := "current_file.ini"
global RemainingFilesConfig := "remaining_files.ini"
global FileListConfig := "file_list.ini"
global ConfigFile := A_ScriptDir "\sender_config.ini"
global LogFile := A_ScriptDir "\sender_log.txt"
global SignalFile := A_ScriptDir "\signal.ini"
global MainSeedFile := A_ScriptDir "\main_seed.txt"
global SupplementSeedFile := A_ScriptDir "\supplement_seed.txt"
global SendPosX, SendPosY
global IncludeFileName, WithExt, WithoutExt, IncludeFullPath
global CustomKey, TriggerDelay, MoveUpKey, MoveDownKey, DeleteFileKey, StartSendKey, SendSupplementKey, SkipFileKey, PauseSendKey
global TriggerCustomKeyAfterSend
global StartTriggerMode
global NextTriggerMode
global IsPaused := false
global StartTriggerKey := "^!s"
global NextTriggerKey := "^!m"
global AutoTriggerKey := "^!n"
global SignalMonitorName := "TriggerSender"
global SignalNextName := "TriggerMonitor"
global SignalHasSupplement := "HasSupplement"
global SignalTriggerNextSend := "TriggerNextSend"
global IsSending := false
global MainGuiHwnd
global FloatGuiHwnd
global GuiVisible := 1
global FloatVisible := 1
global SignalValue := 0
global Countdown := 5
global DetectionStatus := "未启动"
global CurrentTaskIndex := 0
global SendingSupplement := falseCoordMode, Mouse, Screen
CoordMode, ToolTip, Screen
CoordMode, Gui, ScreenIniWrite, 0, %SignalFile%, Signals, %SignalMonitorName%
IniWrite, 0, %SignalFile%, Signals, %SignalNextName%
IniWrite, 0, %SignalFile%, Signals, %SignalHasSupplement%
IniWrite, 0, %SignalFile%, Signals, %SignalTriggerNextSend%
IniWrite, 0, %SignalFile%, Signals, ReadyForNote ; 初始化 ReadyForNoteIfNotExist, %ConfigFile%
{IniWrite, 300, %ConfigFile%, Settings, SendPosXIniWrite, 500, %ConfigFile%, Settings, SendPosYIniWrite, 0, %ConfigFile%, Settings, IncludeFileNameIniWrite, 0, %ConfigFile%, Settings, WithExtIniWrite, 0, %ConfigFile%, Settings, WithoutExtIniWrite, 0, %ConfigFile%, Settings, IncludeFullPathIniWrite, 500, %ConfigFile%, Settings, TriggerDelayIniWrite, 1, %ConfigFile%, Settings, TriggerCustomKeyAfterSendIniWrite, 0, %ConfigFile%, Settings, StartTriggerModeIniWrite, 0, %ConfigFile%, Settings, NextTriggerModeIniWrite, ^Up, %ConfigFile%, Hotkeys, MoveUpKeyIniWrite, ^Down, %ConfigFile%, Hotkeys, MoveDownKeyIniWrite, ^Delete, %ConfigFile%, Hotkeys, DeleteFileKeyIniWrite, ^!s, %ConfigFile%, Hotkeys, StartSendKeyIniWrite, ^!u, %ConfigFile%, Hotkeys, SendSupplementKeyIniWrite, ^!k, %ConfigFile%, Hotkeys, SkipFileKeyIniWrite, ^!p, %ConfigFile%, Hotkeys, PauseSendKeyIniWrite, ^!t, %ConfigFile%, Hotkeys, CustomKeyIniWrite, ^!s, %ConfigFile%, Hotkeys, StartTriggerKeyIniWrite, ^!m, %ConfigFile%, Hotkeys, NextTriggerKeyIniWrite, ^!n, %ConfigFile%, Hotkeys, AutoTriggerKeyIniWrite, 1, %ConfigFile%, Settings, GuiVisible
}
IfNotExist, %RemainingFilesConfig%IniWrite, 0, %RemainingFilesConfig%, Settings, RemainingFiles
IfNotExist, %FileListConfig%IniWrite, "", %FileListConfig%, Tasks
IfNotExist, %SignalFile%
{IniWrite, 0, %SignalFile%, Signals, %SignalMonitorName%IniWrite, 0, %SignalFile%, Signals, %SignalNextName%IniWrite, 0, %SignalFile%, Signals, %SignalHasSupplement%IniWrite, 0, %SignalFile%, Signals, %SignalTriggerNextSend%IniWrite, 0, %SignalFile%, Signals, ReadyForNote
}
IfNotExist, %MainSeedFile%FileAppend, ww, %MainSeedFile%
IfNotExist, %SupplementSeedFile%FileAppend, aa, %SupplementSeedFile%IniRead, SendPosX, %ConfigFile%, Settings, SendPosX, 300
IniRead, SendPosY, %ConfigFile%, Settings, SendPosY, 500
IniRead, IncludeFileName, %ConfigFile%, Settings, IncludeFileName, 0
IniRead, WithExt, %ConfigFile%, Settings, WithExt, 0
IniRead, WithoutExt, %ConfigFile%, Settings, WithoutExt, 0
IniRead, IncludeFullPath, %ConfigFile%, Settings, IncludeFullPath, 0
IniRead, TriggerDelay, %ConfigFile%, Settings, TriggerDelay, 500
IniRead, TriggerCustomKeyAfterSend, %ConfigFile%, Settings, TriggerCustomKeyAfterSend, 1
IniRead, StartTriggerMode, %ConfigFile%, Settings, StartTriggerMode, 0
IniRead, NextTriggerMode, %ConfigFile%, Settings, NextTriggerMode, 0
IniRead, MoveUpKey, %ConfigFile%, Hotkeys, MoveUpKey, ^Up
IniRead, MoveDownKey, %ConfigFile%, Hotkeys, MoveDownKey, ^Down
IniRead, DeleteFileKey, %ConfigFile%, Hotkeys, DeleteFileKey, ^Delete
IniRead, StartSendKey, %ConfigFile%, Hotkeys, StartSendKey, ^!s
IniRead, SendSupplementKey, %ConfigFile%, Hotkeys, SendSupplementKey, ^!u
IniRead, SkipFileKey, %ConfigFile%, Hotkeys, SkipFileKey, ^!k
IniRead, PauseSendKey, %ConfigFile%, Hotkeys, PauseSendKey, ^!p
IniRead, CustomKey, %ConfigFile%, Hotkeys, CustomKey, ^!t
IniRead, StartTriggerKey, %ConfigFile%, Hotkeys, StartTriggerKey, ^!s
IniRead, NextTriggerKey, %ConfigFile%, Hotkeys, NextTriggerKey, ^!m
IniRead, AutoTriggerKey, %ConfigFile%, Hotkeys, AutoTriggerKey, ^!n
IniRead, GuiVisible, %ConfigFile%, Settings, GuiVisible, 1Gui, Main:New, +LastFound +Resize
MainGuiHwnd := WinExist()StartTriggerModeKey := !StartTriggerMode
StartTriggerModeSignal := StartTriggerMode
NextTriggerModeKey := !NextTriggerMode
NextTriggerModeSignal := NextTriggerModeGui, Main:Add, Text, x20 y10 w280 h20, 待处理任务
Gui, Main:Add, ListView, x20 y30 w360 h150 vToProcessList gListViewClick AltSubmit, 序号|任务名|补充文件
Gui, Main:Add, Button, x20 y190 w70 h30 gImportFiles, 导入任务
Gui, Main:Add, Button, x100 y190 w70 h30 gImportSupplementFiles, 导入补充文件
Gui, Main:Add, Button, x180 y190 w70 h30 gSmartRecognizeSort, 智能识别排列
Gui, Main:Add, Button, x260 y190 w70 h30 gSetSendPos, 定位发送
Gui, Main:Add, Button, x20 y230 w70 h30 gMoveUp, 上移
Gui, Main:Add, Button, x100 y230 w70 h30 gMoveDown, 下移
Gui, Main:Add, Button, x180 y230 w70 h30 gDeleteFile, 删除
Gui, Main:Add, Button, x260 y230 w70 h30 gStartSend, 发送主任务
Gui, Main:Add, Button, x340 y230 w70 h30 gSendSupplement, 发送补充文件
Gui, Main:Add, Button, x20 y270 w70 h30 gSkipFile, 跳过
Gui, Main:Add, Button, x100 y270 w70 h30 gPauseSend, 暂停
Gui, Main:Add, Button, x180 y270 w70 h30 gBatchDelete, 批量删除
Gui, Main:Add, Button, x260 y270 w70 h30 gShowHotkeyMenu, 快捷键设置
Gui, Main:Add, Button, x20 y310 w70 h30 gSimulateSend, 模拟发送
Gui, Main:Add, Button, x100 y310 w100 h30 gSetMainSeed, 设置主任务种子
Gui, Main:Add, Button, x210 y310 w100 h30 gSetSupplementSeed, 设置补充任务种子
Gui, Main:Add, CheckBox, x320 y310 w150 h20 vIncludeFileName gToggleFileNameOptions Checked%IncludeFileName%, 发送时带文件名
Gui, Main:Add, Radio, x480 y310 w80 h20 vWithExt gSaveSettings Checked%WithExt% Disabled, 有后缀
Gui, Main:Add, Radio, x560 y310 w80 h20 vWithoutExt gSaveSettings Checked%WithoutExt% Disabled, 无后缀
Gui, Main:Add, CheckBox, x20 y340 w150 h20 vIncludeFullPath gSaveSettings Checked%IncludeFullPath%, 发送时带绝对路径
Gui, Main:Add, CheckBox, x180 y340 w200 h20 vTriggerCustomKeyAfterSend gSaveSettings Checked%TriggerCustomKeyAfterSend%, 发送后触发自定义快捷键
Gui, Main:Add, Text, x20 y370 w150 h20, 触发延迟(毫秒):
Gui, Main:Add, Edit, x180 y370 w100 h20 vTriggerDelay, %TriggerDelay%
Gui, Main:Add, Button, x290 y370 w70 h30 gSaveTriggerDelay, 保存
Gui, Main:Add, Text, x20 y400 w150 h20, 被触发方式:
Gui, Main:Add, Radio, x20 y420 w150 h20 vStartTriggerModeKey gSaveStartTriggerMode Checked%StartTriggerModeKey%, 快捷键触发
Gui, Main:Add, Radio, x180 y420 w150 h20 vStartTriggerModeSignal gSaveStartTriggerMode Checked%StartTriggerModeSignal%, 信号量触发
Gui, Main:Add, Text, x20 y450 w150 h20, 触发下一脚本方式:
Gui, Main:Add, Radio, x20 y470 w150 h20 vNextTriggerModeKey gSaveNextTriggerMode Checked%NextTriggerModeKey%, 快捷键触发
Gui, Main:Add, Radio, x180 y470 w150 h20 vNextTriggerModeSignal gSaveNextTriggerMode Checked%NextTriggerModeSignal%, 信号量触发
Gui, Main:Add, GroupBox, x20 y500 w400 h150, 状态监控
Gui, Main:Add, Text, xp+10 yp+20 w380 vDetectionStatusDisplay, 检测状态: %DetectionStatus%
Gui, Main:Add, Text, xp yp+30 w380 vCountdownDisplay, 信号检测倒计时: %Countdown% 秒
Gui, Main:Add, Text, xp yp+30 w380 vSignalStatusDisplay, 信号量 TriggerSender: %SignalValue%
Gui, Main:Add, Button, xp yp+30 w180 gToggleFloatWindow, 显示/隐藏悬浮窗
Gui, Main:Add, Text, x430 y500 w150 h20 vMoveUpKeyDisplay, 上移快捷键: %MoveUpKey%
Gui, Main:Add, Text, x430 y530 w150 h20 vMoveDownKeyDisplay, 下移快捷键: %MoveDownKey%
Gui, Main:Add, Text, x430 y560 w150 h20 vDeleteFileKeyDisplay, 删除快捷键: %DeleteFileKey%
Gui, Main:Add, Text, x590 y500 w150 h20 vStartSendKeyDisplay, 发送主任务: %StartSendKey%
Gui, Main:Add, Text, x590 y530 w150 h20 vSendSupplementKeyDisplay, 发送补充文件: %SendSupplementKey%
Gui, Main:Add, Text, x590 y560 w150 h20 vSkipFileKeyDisplay, 跳过快捷键: %SkipFileKey%
Gui, Main:Add, Text, x750 y500 w150 h20 vPauseSendKeyDisplay, 暂停快捷键: %PauseSendKey%
Gui, Main:Add, Text, x750 y530 w150 h20 vCustomKeyDisplay, 自定义快捷键: %CustomKey%
Gui, Main:Add, Text, x750 y560 w150 h20 vStartTriggerKeyDisplay, 被触发快捷键: %StartTriggerKey%
Gui, Main:Add, Text, x910 y500 w150 h20 vNextTriggerKeyDisplay, 下一触发快捷键: %NextTriggerKey%
Gui, Main:Add, Text, x410 y10 w280 h20, 已处理任务
Gui, Main:Add, ListView, x410 y30 w360 h150 vProcessedList gListViewClick AltSubmit, 序号|任务名|补充文件
Gui, Main:Add, Button, x410 y190 w70 h30 gViewFile, 查看文件
Gui, Main:Add, Button, x490 y190 w70 h30 gClearProcessed, 清空已处理
Gui, Main:Add, Button, x570 y190 w70 h30 gDeleteProcessed, 删除选中
Gui, Main:Add, Button, x650 y190 w70 h30 gReAddMainToOrigin, 重加主任务
Gui, Main:Add, Button, x730 y190 w70 h30 gReAddSupplementToOrigin, 重加补充文件
Gui, Main:Add, StatusBar, vStatusBar, 状态: 就绪if (GuiVisible = 1) {Gui, Main:Show, w1000 h660, 文件发送器LogMessage("GUI 创建并显示")
} else {Gui, Main:HideLogMessage("GUI 创建并隐藏")
}if (IncludeFileName) {GuiControl, Main:Enable, WithExtGuiControl, Main:Enable, WithoutExt
} else {GuiControl, Main:Disable, WithExtGuiControl, Main:Disable, WithoutExtGuiControl, Main:, WithExt, 0GuiControl, Main:, WithoutExt, 0
}Gosub, CreateFloatWindow
BindHotkeys()
Gosub, LoadTaskListif (StartTriggerMode = 1) {SetTimer, MonitorSignal, 100DetectionStatus := "监控中(信号量模式)"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
}returnLogMessage(message) {FormatTime, CurrentTime,, yyyy-MM-dd HH:mm:ssFileAppend, [%CurrentTime%] %message%`n, %LogFile%
}LogDebug(message) {FormatTime, CurrentTime,, yyyy-MM-dd HH:mm:ssFileAppend, [DEBUG %CurrentTime%] %message%`n, %LogFile%
}CreateFloatWindow:
Gui, Float:+LastFound +AlwaysOnTop +Border
FloatGuiHwnd := WinExist()
if (!FloatGuiHwnd) {LogMessage("悬浮窗创建失败:无法获取窗口句柄")MsgBox, 悬浮窗创建失败,请检查脚本!return
}
Gui, Float:Add, Text, w300 vFloatSignalDisplay, 信号量 TriggerSender: %SignalValue% (倒计时: %Countdown% 秒)
Gui, Float:Show, x10 y50 w320 h30
FloatVisible := 1
LogMessage("悬浮窗创建成功,句柄: " FloatGuiHwnd ",坐标: (10, 50),大小: (320, 30)")
returnUpdateFloatWindow:
IniRead, SignalValue, %SignalFile%, Signals, %SignalMonitorName%, 0
GuiControl, Float:, FloatSignalDisplay, 信号量 TriggerSender: %SignalValue% (倒计时: %Countdown% 秒)
GuiControl, Main:, SignalStatusDisplay, 信号量 TriggerSender: %SignalValue%
GuiControl, Main:, CountdownDisplay, 信号检测倒计时: %Countdown% 秒
if (WinExist("ahk_id " FloatGuiHwnd)) {LogMessage("悬浮窗更新: SignalValue=" SignalValue ", Countdown=" Countdown)
} else {LogMessage("悬浮窗更新失败: 窗口不存在")
}
returnUpdateCountdown:
if (StartTriggerMode != 1) {return
}
Countdown -= 1
if (Countdown <= 0) {Countdown := 5Gosub, MonitorSignal
}
Gosub, UpdateFloatWindow
returnToggleFloatWindow:
FloatVisible := !FloatVisible
if (FloatVisible = 1) {Gui, Float:ShowLogMessage("悬浮窗显示,句柄: " FloatGuiHwnd)
} else {Gui, Float:HideLogMessage("悬浮窗隐藏,句柄: " FloatGuiHwnd)
}
returnBindHotkeys() {try {Hotkey, %MoveUpKey%, MoveUpLogMessage("绑定 MoveUpKey: " MoveUpKey " 成功")} catch e {LogMessage("绑定 MoveUpKey: " MoveUpKey " 失败: " e)}try {Hotkey, %MoveDownKey%, MoveDownLogMessage("绑定 MoveDownKey: " MoveDownKey " 成功")} catch e {LogMessage("绑定 MoveDownKey: " MoveDownKey " 失败: " e)}try {Hotkey, %DeleteFileKey%, DeleteFileLogMessage("绑定 DeleteFileKey: " DeleteFileKey " 成功")} catch e {LogMessage("绑定 DeleteFileKey: " DeleteFileKey " 失败: " e)}try {Hotkey, %StartSendKey%, SimulateStartSendClickLogMessage("绑定 StartSendKey: " StartSendKey " 成功")} catch e {LogMessage("绑定 StartSendKey: " StartSendKey " 失败: " e)}try {Hotkey, %SendSupplementKey%, SimulateSendSupplementClickLogMessage("绑定 SendSupplementKey: " SendSupplementKey " 成功")} catch e {LogMessage("绑定 SendSupplementKey: " SendSupplementKey " 失败: " e)}try {Hotkey, %SkipFileKey%, SkipFileLogMessage("绑定 SkipFileKey: " SkipFileKey " 成功")} catch e {LogMessage("绑定 SkipFileKey: " SkipFileKey " 失败: " e)}try {Hotkey, %PauseSendKey%, PauseSendLogMessage("绑定 PauseSendKey: " PauseSendKey " 成功")} catch e {LogMessage("绑定 PauseSendKey: " PauseSendKey " 失败: " e)}try {Hotkey, %CustomKey%, TriggerCustomKeyLogMessage("绑定 CustomKey: " CustomKey " 成功")} catch e {LogMessage("绑定 CustomKey: " CustomKey " 失败: " e)}try {Hotkey, %AutoTriggerKey%, SimulateStartSendClickLogMessage("绑定 AutoTriggerKey: " AutoTriggerKey " 成功")} catch e {LogMessage("绑定 AutoTriggerKey: " AutoTriggerKey " 失败: " e)}if (StartTriggerMode = 0) {try {Hotkey, %StartTriggerKey%, SimulateStartSendClickLogMessage("绑定 StartTriggerKey: " StartTriggerKey " 成功")} catch e {LogMessage("绑定 StartTriggerKey: " StartTriggerKey " 失败: " e)}}
}MonitorSignal:
if (StartTriggerMode = 1) {IniRead, SignalValue, %SignalFile%, Signals, %SignalMonitorName%, 0IniRead, ReadyForNote, %SignalFile%, Signals, ReadyForNote, 0if (ReadyForNote = 1) {LogDebug("检测到 ReadyForNote=1,开始暂停并倒计时")Gui, WaitGui:New, +AlwaysOnTopGui, WaitGui:Add, Text, vWaitText, 等待新建笔记完成: 20 秒Gui, WaitGui:Show,, 等待中Loop, 20 {Sleep, 1000remaining := 20 - A_IndexGuiControl, WaitGui:, WaitText, 等待新建笔记完成: %remaining% 秒}Gui, WaitGui:DestroyIniRead, ReadyForNote, %SignalFile%, Signals, ReadyForNote, 0if (ReadyForNote = 1) {LogDebug("20秒后 ReadyForNote 仍为1,跳过发送")ToolTip, 新建笔记未完成,暂停发送, , , , 16SetTimer, RemoveTooltip, -2000return}}if (SignalValue = 1) {LogDebug("检测到信号量 " SignalMonitorName "=1,模拟点击发送主任务按钮")SendingSupplement := falseGosub, SimulateStartSendClickIniWrite, 0, %SignalFile%, Signals, %SignalMonitorName%LogDebug("重置信号量 " SignalMonitorName "=0")Gosub, RefreshTaskListsGui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%}IniRead, NextSendValue, %SignalFile%, Signals, %SignalTriggerNextSend%, 0if (NextSendValue = 1) {LogDebug("检测到信号量 " SignalTriggerNextSend "=1,检查是否发送补充文件")IniRead, HasSupplement, %SignalFile%, Signals, %SignalHasSupplement%, 0if (HasSupplement = 1 && CurrentTaskIndex > 0) {LogDebug("有补充文件,模拟点击发送补充文件按钮,任务编号: " CurrentTaskIndex)SendingSupplement := trueGosub, SimulateSendSupplementClickIniWrite, 0, %SignalFile%, Signals, %SignalTriggerNextSend%LogDebug("重置信号量 " SignalTriggerNextSend "=0")Gosub, RefreshTaskListsGui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%} else {LogDebug("无补充文件或任务已完成,任务编号: " CurrentTaskIndex)if (CurrentTaskIndex > 0) {Gosub, SaveTaskListGosub, UpdateRemainingTasksGosub, RefreshTaskLists}CurrentTaskIndex := 0if (NextTriggerMode = 0) {SendInput, %NextTriggerKey%LogDebug("使用快捷键 " NextTriggerKey " 触发 " SignalNextName)} else {IniWrite, 1, %SignalFile%, Signals, %SignalNextName%LogDebug("写入信号量 " SignalNextName "=1")}IniWrite, 0, %SignalFile%, Signals, %SignalTriggerNextSend%LogDebug("重置信号量 " SignalTriggerNextSend "=0")Gosub, RefreshTaskListsGui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%}}
}
returnSimulateStartSendClick:Gui, Main:DefaultWinActivate, ahk_id %MainGuiHwnd% ; 激活窗口Sleep, 200 ; 增加延迟,确保窗口准备好ControlClick, Button8, ahk_id %MainGuiHwnd%, , Left, 1, NA ; 发送点击Sleep, 200 ; 点击后等待,确保动作完成if (ErrorLevel = 0) {LogMessage("模拟点击发送主任务按钮成功")} else {LogMessage("模拟点击发送主任务按钮失败,ErrorLevel: " ErrorLevel)}
returnSimulateSendSupplementClick:Gui, Main:DefaultWinActivate, ahk_id %MainGuiHwnd% ; 激活窗口Sleep, 200 ; 增加延迟,确保窗口准备好ControlClick, Button9, ahk_id %MainGuiHwnd%, , Left, 1, NA ; 发送点击Sleep, 200 ; 点击后等待,确保动作完成if (ErrorLevel = 0) {LogMessage("模拟点击发送补充文件按钮成功")} else {LogMessage("模拟点击发送补充文件按钮失败,ErrorLevel: " ErrorLevel)}
returnSetMainSeed:
Gui, Main:Default
Gui, +Disabled ; 禁用主 GUI
Gui, SeedMain:New, +Owner%MainGuiHwnd% +ToolWindow, 设置主任务种子
Gui, SeedMain:Add, Edit, w400 h200 vMainSeedText,
Gui, SeedMain:Add, Button, gSaveMainSeed, 保存
Gui, SeedMain:Add, Button, gCancelSeedMain, 取消
; 加载当前种子文本
if FileExist(MainSeedFile)
{FileRead, currentText, %MainSeedFile%GuiControl, SeedMain:, MainSeedText, %currentText%
}
Gui, SeedMain:Show
returnSaveMainSeed:
Gui, SeedMain:Submit
if (StrLen(MainSeedText) > 3000)
{MsgBox, 种子文本超过3000字符,已截断!MainSeedText := SubStr(MainSeedText, 1, 3000)
}
FileDelete, %MainSeedFile%
FileAppend, %MainSeedText%, %MainSeedFile%
Gui, SeedMain:Destroy
Gui, Main:Default
Gui, -Disabled
WinActivate, ahk_id %MainGuiHwnd%
LogMessage("设置主任务种子: " MainSeedText)
returnCancelSeedMain:
Gui, SeedMain:Destroy
Gui, Main:Default
Gui, -Disabled
WinActivate, ahk_id %MainGuiHwnd%
returnSetSupplementSeed:
Gui, Main:Default
Gui, +Disabled ; 禁用主 GUI
Gui, SeedSupplement:New, +Owner%MainGuiHwnd% +ToolWindow, 设置补充任务种子
Gui, SeedSupplement:Add, Edit, w400 h200 vSupplementSeedText,
Gui, SeedSupplement:Add, Button, gSaveSupplementSeed, 保存
Gui, SeedSupplement:Add, Button, gCancelSeedSupplement, 取消
; 加载当前种子文本
if FileExist(SupplementSeedFile)
{FileRead, currentText, %SupplementSeedFile%GuiControl, SeedSupplement:, SupplementSeedText, %currentText%
}
Gui, SeedSupplement:Show
returnSaveSupplementSeed:
Gui, SeedSupplement:Submit
if (StrLen(SupplementSeedText) > 3000)
{MsgBox, 种子文本超过3000字符,已截断!SupplementSeedText := SubStr(SupplementSeedText, 1, 3000)
}
FileDelete, %SupplementSeedFile%
FileAppend, %SupplementSeedText%, %SupplementSeedFile%
Gui, SeedSupplement:Destroy
Gui, Main:Default
Gui, -Disabled
WinActivate, ahk_id %MainGuiHwnd%
LogMessage("设置补充任务种子: " SupplementSeedText)
returnCancelSeedSupplement:
Gui, SeedSupplement:Destroy
Gui, Main:Default
Gui, -Disabled
WinActivate, ahk_id %MainGuiHwnd%
returnLoadTaskList:
TaskList := []
IniRead, TaskData, %FileListConfig%, Tasks
if (TaskData != "ERROR") {Loop, Parse, TaskData, `n{if (A_LoopField = "")continueSplitPath, A_LoopField, , , , KeyIniRead, Value, %FileListConfig%, Tasks, %Key%if (Value != "ERROR") {StringSplit, Parts, Value, |TaskList[A_Index] := {Name: Parts1, MainPath: Parts2, MainName: Parts3, SupplementPath: Parts4, SupplementName: Parts5, MainSent: Parts6 = "1" ? true : false, SupplementSent: Parts7 = "1" ? false : false}LogMessage("加载任务: 编号=" A_Index " 名称=" Parts1 " 主文件=" Parts2 " 主文件名=" Parts3 " 补充文件=" Parts4 " 补充文件名=" Parts5 " MainSent=" Parts6 " SupplementSent=" Parts7)}}
}
Gosub, RefreshTaskLists
returnSaveTaskList:
IniDelete, %FileListConfig%, Tasks
Loop, % TaskList.Length() {if (TaskList[A_Index].MainPath != "" || TaskList[A_Index].SupplementPath != "") {Value := TaskList[A_Index].Name "|" TaskList[A_Index].MainPath "|" TaskList[A_Index].MainName "|" TaskList[A_Index].SupplementPath "|" TaskList[A_Index].SupplementName "|" (TaskList[A_Index].MainSent ? "1" : "0") "|" (TaskList[A_Index].SupplementSent ? "1" : "0")IniWrite, %Value%, %FileListConfig%, Tasks, %A_Index%LogMessage("保存任务: 编号=" A_Index " 名称=" TaskList[A_Index].Name " 主文件=" TaskList[A_Index].MainPath " 主文件名=" TaskList[A_Index].MainName " 补充文件=" TaskList[A_Index].SupplementPath " 补充文件名=" TaskList[A_Index].SupplementName " MainSent=" TaskList[A_Index].MainSent " SupplementSent=" TaskList[A_Index].SupplementSent)}
}
returnUpdateRemainingTasks:
tempCount := 0
Loop, % TaskList.Length() {if (!TaskList[A_Index].MainSent || (TaskList[A_Index].SupplementPath != "" && !TaskList[A_Index].SupplementSent))tempCount++
}
IniWrite, %tempCount%, %RemainingFilesConfig%, Settings, RemainingFiles
LogMessage("更新 RemainingTasks: " tempCount)
returnImportFiles:
FileSelectFile, SelectedFiles, M3, , 选择主文件和补充文件 (*.txt; *.srt), Text Files (*.txt; *.srt)
if (SelectedFiles = "") {ToolTip, 文件选择被取消!SetTimer, RemoveTooltip, -2000LogMessage("文件选择被取消")return
}
TempList := []
LogMessage("开始解析 SelectedFiles: " SelectedFiles)
Loop, Parse, SelectedFiles, `n
{if (A_Index = 1) {BaseDir := Trim(A_LoopField, "`r`n")LogMessage("基目录: " BaseDir)continue}FileName := Trim(A_LoopField, "`r`n")if (FileName = "") {LogMessage("文件名为空,跳过: " A_LoopField)continue}CleanPath := BaseDir "\" FileNameLogMessage("尝试导入路径: " CleanPath)if (!FileExist(CleanPath)) {LogMessage("路径无效,跳过: " CleanPath)continue}SplitPath, FileName, , , Ext, OutNameNoExtif (Ext != "txt" && Ext != "srt") {LogMessage("不支持的文件格式,跳过: " FileName)continue}if (InStr(OutNameNoExt, "_supplement") || Ext = "srt") {MainName := StrReplace(OutNameNoExt, "_supplement", "")Found := falsefor Index, Task in TempList {if (Task.Name = MainName) {Task.SupplementPath := CleanPathTask.SupplementName := FileNameFound := trueLogMessage("关联补充文件: 任务=" MainName " 名称=" FileName " 路径=" CleanPath)break}}if (!Found) {TempList.Push({Name: MainName, MainPath: "", MainName: "", SupplementPath: CleanPath, SupplementName: FileName, MainSent: false, SupplementSent: false})LogMessage("添加孤立补充文件: 名称=" MainName " 文件名=" FileName " 路径=" CleanPath)}} else {TempList.Push({Name: OutNameNoExt, MainPath: CleanPath, MainName: FileName, SupplementPath: "", SupplementName: "", MainSent: false, SupplementSent: false})LogMessage("添加主文件: 名称=" OutNameNoExt " 文件名=" FileName " 路径=" CleanPath)}
}
if (TempList.Length() = 0) {ToolTip, 未导入任何有效任务!SetTimer, RemoveTooltip, -2000LogMessage("未导入任何有效任务")return
}
SortTempList(TempList)
for Index, TaskObj in TempListTaskList.Push(TaskObj)
Gosub, SaveTaskList
Gosub, UpdateRemainingTasks
Gosub, RefreshTaskLists
temp_number := TempList.Length()
ToolTip, 成功导入 %temp_number% 个任务
SetTimer, RemoveTooltip, -2000
LogMessage("成功导入 " TempList.Length() " 个任务")
returnImportSupplementFiles:
FileSelectFile, SelectedFiles, M3, , 选择补充文件 (*.txt; *.srt), Text Files (*.txt; *.srt)
if (SelectedFiles = "") {ToolTip, 文件选择被取消!SetTimer, RemoveTooltip, -2000LogMessage("补充文件选择被取消")return
}
ImportedCount := 0
Loop, Parse, SelectedFiles, `n
{if (A_Index = 1) {BaseDir := Trim(A_LoopField, "`r`n")LogMessage("基目录: " BaseDir)continue}FileName := Trim(A_LoopField, "`r`n")if (FileName = "") {LogMessage("文件名为空,跳过: " A_LoopField)continue}CleanPath := BaseDir "\" FileNameLogMessage("尝试导入补充文件路径: " CleanPath)if (!FileExist(CleanPath)) {LogMessage("路径无效,跳过: " CleanPath)continue}SplitPath, FileName, , , Ext, OutNameNoExtif (Ext != "txt" && Ext != "srt") {LogMessage("不支持的文件格式,跳过: " FileName)continue}MainName := StrReplace(OutNameNoExt, "_supplement", "")for Index, Task in TaskList {if (Task.Name = MainName && Task.MainPath != "" && Task.SupplementPath = "") {Task.SupplementPath := CleanPathTask.SupplementName := FileNameImportedCount++LogMessage("匹配补充文件: 任务=" MainName " 名称=" FileName " 路径=" CleanPath)break}}
}
if (ImportedCount = 0) {ToolTip, 未匹配任何补充文件!SetTimer, RemoveTooltip, -2000LogMessage("未匹配任何补充文件")return
}
Gosub, SaveTaskList
Gosub, UpdateRemainingTasks
Gosub, RefreshTaskLists
ToolTip, 成功导入 %ImportedCount% 个补充文件
SetTimer, RemoveTooltip, -2000
LogMessage("成功导入 " ImportedCount " 个补充文件")
returnSmartRecognizeSort:
Folder := FileSelectFolder, , , 选择包含任务文件的文件夹
if (Folder = "") {ToolTip, 文件夹选择被取消!SetTimer, RemoveTooltip, -2000LogMessage("文件夹选择被取消")return
}
TempList := []
Loop, Files, %Folder%\*.txt
{SplitPath, A_LoopFileName, , , , OutNameNoExtTempList.Push({Name: OutNameNoExt, MainPath: A_LoopFileFullPath, MainName: A_LoopFileName, SupplementPath: "", SupplementName: "", MainSent: false, SupplementSent: false})LogMessage("扫描主文件: 名称=" OutNameNoExt " 文件名=" A_LoopFileName " 路径=" A_LoopFileFullPath)
}
Loop, Files, %Folder%\*.srt
{SplitPath, A_LoopFileName, , , , OutNameNoExtMainName := OutNameNoExtFound := falsefor Index, Task in TempList {if (Task.Name = MainName) {Task.SupplementPath := A_LoopFileFullPathTask.SupplementName := A_LoopFileNameFound := trueLogMessage("匹配补充文件 (.srt): 任务=" MainName " 名称=" A_LoopFileName " 路径=" A_LoopFileFullPath)break}}if (!Found) {TempList.Push({Name: MainName, MainPath: "", MainName: "", SupplementPath: A_LoopFileFullPath, SupplementName: A_LoopFileName, MainSent: false, SupplementSent: false})LogMessage("添加孤立补充文件 (.srt): 名称=" MainName " 文件名=" A_LoopFileName " 路径=" A_LoopFileFullPath)}
}
Loop, Files, %Folder%\*_supplement.txt
{SplitPath, A_LoopFileName, , , , OutNameNoExtMainName := StrReplace(OutNameNoExt, "_supplement", "")Found := falsefor Index, Task in TempList {if (Task.Name = MainName && Task.SupplementPath = "") {Task.SupplementPath := A_LoopFileFullPathTask.SupplementName := A_LoopFileNameFound := trueLogMessage("匹配补充文件 (_supplement.txt): 任务=" MainName " 名称=" A_LoopFileName " 路径=" A_LoopFileFullPath)break}}if (!Found) {TempList.Push({Name: MainName, MainPath: "", MainName: "", SupplementPath: A_LoopFileFullPath, SupplementName: A_LoopFileName, MainSent: false, SupplementSent: false})LogMessage("添加孤立补充文件 (_supplement.txt): 名称=" MainName " 文件名=" A_LoopFileName " 路径=" A_LoopFileFullPath)}
}
if (TempList.Length() = 0) {ToolTip, 未找到任何有效任务文件!SetTimer, RemoveTooltip, -2000LogMessage("未找到任何有效任务文件")return
}
SortTempList(TempList)
TaskList := TempList
Gosub, SaveTaskList
Gosub, UpdateRemainingTasks
Gosub, RefreshTaskLists
temp_task := TempList.Length()
ToolTip, 智能识别并排列 %temp_task% 个任务
SetTimer, RemoveTooltip, -2000
LogMessage("智能识别并排列 " TempList.Length() " 个任务")
returnSetSendPos:
ToolTip, 请将鼠标移动到目标发送区域(支持双屏幕),然后点击左键!
KeyWait, LButton, D
MouseGetPos, SendPosX, SendPosY
IniWrite, %SendPosX%, %ConfigFile%, Settings, SendPosX
IniWrite, %SendPosY%, %ConfigFile%, Settings, SendPosY
ToolTip, 位置已记录:X=%SendPosX%, Y=%SendPosY%
SetTimer, RemoveTooltip, -2000
LogMessage("发送位置设置: X=" SendPosX " Y=" SendPosY)
returnMoveUp:
GuiControl, Main:-Redraw, ToProcessList
Gui, Main:ListView, ToProcessList
SelectedRow := LV_GetNext()
if (SelectedRow > 1 && (!TaskList[SelectedRow].MainSent || (TaskList[SelectedRow].SupplementPath != "" && !TaskList[SelectedRow].SupplementSent)) && TaskList[SelectedRow - 1].MainPath != "") {Temp := TaskList[SelectedRow - 1]TaskList[SelectedRow - 1] := TaskList[SelectedRow]TaskList[SelectedRow] := TempGosub, SaveTaskListGosub, RefreshTaskListsLV_Modify(SelectedRow - 1, "Select Focus")LogMessage("上移任务: 从 " SelectedRow " 到 " (SelectedRow - 1))
} else {ToolTip, 无法上移!SetTimer, RemoveTooltip, -2000
}
GuiControl, Main:+Redraw, ToProcessList
returnMoveDown:
GuiControl, Main:-Redraw, ToProcessList
Gui, Main:ListView, ToProcessList
SelectedRow := LV_GetNext()
if (SelectedRow < TaskList.Length() && (!TaskList[SelectedRow].MainSent || (TaskList[SelectedRow].SupplementPath != "" && !TaskList[SelectedRow].SupplementSent)) && TaskList[SelectedRow + 1].MainPath != "") {Temp := TaskList[SelectedRow + 1]TaskList[SelectedRow + 1] := TaskList[SelectedRow]TaskList[SelectedRow] := TempGosub, SaveTaskListGosub, RefreshTaskListsLV_Modify(SelectedRow + 1, "Select Focus")LogMessage("下移任务: 从 " SelectedRow " 到 " (SelectedRow + 1))
} else {ToolTip, 无法下移!SetTimer, RemoveTooltip, -2000
}
GuiControl, Main:+Redraw, ToProcessList
returnDeleteFile:
GuiControl, Main:-Redraw, ToProcessList
Gui, Main:ListView, ToProcessList
SelectedRow := LV_GetNext()
if (SelectedRow > 0 && (!TaskList[SelectedRow].MainSent || (TaskList[SelectedRow].SupplementPath != "" && !TaskList[SelectedRow].SupplementSent))) {TaskList[SelectedRow] := {Name: "", MainPath: "", MainName: "", SupplementPath: "", SupplementName: "", MainSent: true, SupplementSent: true}Gosub, SaveTaskListGosub, UpdateRemainingTasksGosub, RefreshTaskListsToolTip, 已删除SetTimer, RemoveTooltip, -2000LogMessage("删除任务: 编号=" SelectedRow)
} else {ToolTip, 无法删除!SetTimer, RemoveTooltip, -2000
}
GuiControl, Main:+Redraw, ToProcessList
returnBatchDelete:
Gui, Main:ListView, ToProcessList
SelectedRows := []
Row := 0
Loop {Row := LV_GetNext(Row)if (Row = 0)breakSelectedRows.Push(Row)
}
if (SelectedRows.Length() = 0) {ToolTip, 请先选中至少一个待处理任务!SetTimer, RemoveTooltip, -2000return
}
Loop, % SelectedRows.Length() {Row := SelectedRows[A_Index]if (Row > 0 && (!TaskList[Row].MainSent || (TaskList[Row].SupplementPath != "" && !TaskList[Row].SupplementSent)))TaskList[Row] := {Name: "", MainPath: "", MainName: "", SupplementPath: "", SupplementName: "", MainSent: true, SupplementSent: true}
}
Gosub, SaveTaskList
Gosub, UpdateRemainingTasks
Gosub, RefreshTaskLists
ToolTip, 已批量删除
SetTimer, RemoveTooltip, -2000
LogMessage("批量删除任务: 共 " SelectedRows.Length() " 个")
returnStartSend:
if (IsSending) {return
}
IsSending := true
Critical
if (IsPaused) {ToolTip, 发送已暂停,请先恢复!, , , , 16SetTimer, RemoveTooltip, -2000IsSending := falsereturn
}
DetectionStatus := "发送中"
GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
Gui, Main:HideGui, Main:ListView, ToProcessList
SelectedRow := LV_GetNext(0, "Focused")
if (SelectedRow > 0 && SelectedRow <= TaskList.Length() && IsObject(TaskList[SelectedRow]) && !TaskList[SelectedRow].MainSent && TaskList[SelectedRow].MainPath != "") {CurrentTaskIndex := SelectedRow
} else {CurrentTaskIndex := 0Loop, % TaskList.Length() {if (!TaskList[A_Index].MainSent && TaskList[A_Index].MainPath != "") {CurrentTaskIndex := A_Indexbreak}}if (CurrentTaskIndex = 0) {Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, 所有主任务已发送完成, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "已完成"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%GuiControl, Main:, StatusBar, 状态: 所有主任务已发送完成LogMessage("所有主任务已发送完成")IsSending := falsereturn}
}SendingSupplement := false
Gosub, SendTask
IsSending := false
returnSendSupplement:
if (IsSending) {return
}
IsSending := true
Critical
if (IsPaused) {ToolTip, 发送已暂停,请先恢复!, , , , 16SetTimer, RemoveTooltip, -2000IsSending := falsereturn
}
DetectionStatus := "发送中"
GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
Gui, Main:HideGui, Main:ListView, ToProcessList
SelectedRow := LV_GetNext(0, "Focused")
if (SelectedRow > 0 && SelectedRow <= TaskList.Length() && IsObject(TaskList[SelectedRow]) && TaskList[SelectedRow].MainSent && !TaskList[SelectedRow].SupplementSent && TaskList[SelectedRow].SupplementPath != "") {CurrentTaskIndex := SelectedRow
} else {CurrentTaskIndex := 0Loop, % TaskList.Length() {if (TaskList[A_Index].MainSent && !TaskList[A_Index].SupplementSent && TaskList[A_Index].SupplementPath != "") {CurrentTaskIndex := A_Indexbreak}}if (CurrentTaskIndex = 0) {Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, 无可发送的补充文件或主任务未发送, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "就绪"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%LogMessage("无可发送的补充文件或主任务未发送")IsSending := falsereturn}
}if (!TaskList[CurrentTaskIndex].MainSent) {Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, 请先发送主任务!, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "就绪"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%LogMessage("尝试发送补充文件失败: 主任务尚未发送,任务编号=" CurrentTaskIndex)IsSending := falsereturn
}SendingSupplement := true
Gosub, SendTask
IsSending := false
returnSendTask:
IniRead, ReadyForNote, %SignalFile%, Signals, ReadyForNote, 0
if (ReadyForNote = 1) {LogDebug("检测到 ReadyForNote=1,开始暂停并倒计时")Gui, WaitGui:New, +AlwaysOnTopGui, WaitGui:Add, Text, vWaitText, 等待新建笔记完成: 20 秒Gui, WaitGui:Show,, 等待中Loop, 10 {Sleep, 1000remaining := 10 - A_IndexGuiControl, WaitGui:, WaitText, 等待新建笔记完成: %remaining% 秒}Gui, WaitGui:DestroyIniRead, ReadyForNote, %SignalFile%, Signals, ReadyForNote, 0if (ReadyForNote = 1) {LogDebug("10秒后 ReadyForNote 仍为1,跳过发送")Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, 新建笔记未完成,跳过发送, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "等待"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%return}
}TaskObj := TaskList[CurrentTaskIndex]
MainPath := TaskObj.MainPath
SupplementPath := TaskObj.SupplementPath
TaskName := TaskObj.MainName
SplitPath, TaskName,,,, OutNameNoExt
LogMessage("尝试发送任务: 编号=" CurrentTaskIndex " 名称=" TaskName " 主文件=" MainPath " 补充文件=" SupplementPath " 是否发送补充文件=" (SendingSupplement ? "是" : "否"))FilePath := SendingSupplement ? SupplementPath : MainPath
FileType := SendingSupplement ? "补充文件" : "主文件"
if (!FileExist(FilePath)) {Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, %FileType% 路径不存在:%FilePath%, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "错误"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%LogMessage("发送失败: " FileType " 路径不存在 - " FilePath)return
}
Content := ReadFileContent(FilePath)
if (Content = "") {Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, 无法读取 %FileType% 内容!, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "错误"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%LogMessage("发送失败: 无法读取 " FileType " 内容 - " FilePath)return
}if (!SendingSupplement && SupplementPath != "" && !TaskObj.SupplementSent) {IniWrite, 1, %SignalFile%, Signals, %SignalHasSupplement%LogDebug("设置信号量 " SignalHasSupplement "=1")
} else if (SendingSupplement) {IniWrite, 0, %SignalFile%, Signals, %SignalHasSupplement%LogDebug("设置信号量 " SignalHasSupplement "=0")
}IniRead, IncludeFileName, %ConfigFile%, Settings, IncludeFileName, 0
IniRead, WithExt, %ConfigFile%, Settings, WithExt, 0
IniRead, WithoutExt, %ConfigFile%, Settings, WithoutExt, 0
IniRead, IncludeFullPath, %ConfigFile%, Settings, IncludeFullPath, 0
SendText := ""
if (IncludeFileName && !SendingSupplement) {if (WithExt)SendText .= "任务名: " . TaskName . "`n"else if (WithoutExt)SendText .= "文件名: " . OutNameNoExt . "`n"
}
if (IncludeFullPath)SendText .= FileType "路径: " . FilePath . "`n"if (SendingSupplement) {SeedFile := SupplementSeedFileDefaultSeed := "aa"
} else {SeedFile := MainSeedFileDefaultSeed := "ww"
}
if FileExist(SeedFile) {FileRead, SeedText, %SeedFile%if ErrorLevel {SeedText := DefaultSeedLogMessage("读取种子文件失败,使用默认值 '" DefaultSeed "'")}
} else {SeedText := DefaultSeedLogMessage("种子文件不存在,使用默认值 '" DefaultSeed "'")
}; Combine seed statement and file content into staging area
StagingArea := SeedText . "`n" . SendText . ContentIniRead, SendPosX, %ConfigFile%, Settings, SendPosX, 300
IniRead, SendPosY, %ConfigFile%, Settings, SendPosY, 500
MouseMove, %SendPosX%, %SendPosY%, 0
Sleep, 200
Click
Sleep, 1000
Clipboard := StagingArea
ClipWait, 2
if (ErrorLevel) {Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%ToolTip, 剪贴板更新失败!, , , , 16SetTimer, RemoveTooltip, -2000DetectionStatus := "错误"GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%LogMessage("发送失败: 剪贴板更新失败")return
}
Send, ^v
Sleep, 200
Send, {Enter}
Sleep, 200; 保存当前文件名到 current_file.ini
SplitPath, FilePath, , , , OutNameNoExt
IniWrite, %OutNameNoExt%, %CurrentFileConfig%, CurrentFile, Name
LogMessage("保存当前文件名: " OutNameNoExt " 到 " CurrentFileConfig)if (!SendingSupplement) {TaskObj.MainSent := trueLogMessage("标记主文件为已发送: 编号=" CurrentTaskIndex " 名称=" TaskName)
} else {TaskObj.SupplementSent := trueLogMessage("标记补充文件为已发送: 编号=" CurrentTaskIndex " 名称=" TaskObj.SupplementName)
}
Gosub, SaveTaskList
Gosub, UpdateRemainingTasks
Gosub, RefreshTaskLists; 触发 TriggerMonitor
if (NextTriggerMode = 0) {SendInput, %NextTriggerKey%LogDebug("使用快捷键 " NextTriggerKey " 触发 " SignalNextName)
} else {IniWrite, 1, %SignalFile%, Signals, %SignalNextName%LogDebug("写入信号量 " SignalNextName "=1")
}Sleep, %TriggerDelay%
if (TriggerCustomKeyAfterSend) {LogMessage("触发 CustomKey: " CustomKey)Gosub, TriggerCustomKey
}
ToolTip, 已发送 %FileType%:%CurrentTaskIndex% - %TaskName%, , , , 16
SetTimer, RemoveTooltip, -2000
DetectionStatus := "就绪"
GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
LogMessage("成功发送 " FileType ": 编号=" CurrentTaskIndex " 名称=" TaskName)
Gui, Main:Show
WinActivate, ahk_id %MainGuiHwnd%
returnReadFileContent(FilePath) {FileRead, Content, *P65001 %FilePath%if (ErrorLevel) {LogMessage("读取失败: 无法读取文件 - " FilePath)return ""}return Content
}SimulateSend:
Gui, Main:Hide
LogMessage("开始模拟发送")
Sleep, 200
if (NextTriggerMode = 0) {SendInput, %NextTriggerKey%LogDebug("模拟发送 - 使用快捷键 " NextTriggerKey " 触发 " SignalNextName)
} else {IniWrite, 1, %SignalFile%, Signals, %SignalNextName%LogDebug("模拟发送 - 写入信号量 " SignalNextName "=1")
}
if (TriggerCustomKeyAfterSend) {LogMessage("模拟发送 - 触发 CustomKey: " CustomKey)Gosub, TriggerCustomKey
}
Gui, Main:Show
WinActivate, ahk_id %MainGuiHwnd%
Gosub, RefreshTaskLists
ToolTip, 模拟发送完成, , , , 16
SetTimer, RemoveTooltip, -2000
DetectionStatus := "就绪"
GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
LogMessage("模拟发送完成")
returnTriggerCustomKey:
SendInput, %CustomKey%
LogMessage("已发送 CustomKey: " CustomKey)
returnSkipFile:
Gui, Main:ListView, ToProcessList
SelectedRow := LV_GetNext(0, "Focused")
if (SelectedRow > 0 && SelectedRow <= TaskList.Length() && IsObject(TaskList[SelectedRow]) && (!TaskList[SelectedRow].MainSent || (TaskList[SelectedRow].SupplementPath != "" && !TaskList[SelectedRow].SupplementSent))) {TaskList[SelectedRow].MainSent := trueTaskList[SelectedRow].SupplementSent := trueGosub, SaveTaskListGosub, UpdateRemainingTasksGosub, RefreshTaskListsToolTip, 已跳过任务:%SelectedRow%SetTimer, RemoveTooltip, -2000LogMessage("跳过任务: 编号=" SelectedRow)
} else {ToolTip, 无法跳过!SetTimer, RemoveTooltip, -2000
}
returnViewFile:
Gui, Main:ListView, ProcessedList
SelectedRow := LV_GetNext()
if (SelectedRow > 0 && (TaskList[SelectedRow].MainSent || TaskList[SelectedRow].SupplementSent)) {Gui, FileChoice:New, +AlwaysOnTopGui, FileChoice:Add, Button, w100 gViewMainFile, 查看主文件Gui, FileChoice:Add, Button, w100 gViewSupplementFile, 查看补充文件Gui, FileChoice:Showglobal ViewFileIndex := SelectedRow
} else {ToolTip, 无法查看!SetTimer, RemoveTooltip, -2000
}
returnViewMainFile:
Gui, FileChoice:Destroy
if (FileExist(TaskList[ViewFileIndex].MainPath)) {Run, % TaskList[ViewFileIndex].MainPathToolTip, 已打开主文件:%ViewFileIndex%SetTimer, RemoveTooltip, -2000LogMessage("查看主文件: 编号=" ViewFileIndex " 路径=" TaskList[ViewFileIndex].MainPath)
} else {tempPath := TaskList[ViewFileIndex].MainPathToolTip, 主文件路径不存在:%tempPath%SetTimer, RemoveTooltip, -2000LogMessage("查看失败: 主文件路径不存在 - " tempPath)
}
returnViewSupplementFile:
Gui, FileChoice:Destroy
if (TaskList[ViewFileIndex].SupplementPath != "" && FileExist(TaskList[ViewFileIndex].SupplementPath)) {Run, % TaskList[ViewFileIndex].SupplementPathToolTip, 已打开补充文件:%ViewFileIndex%SetTimer, RemoveTooltip, -2000LogMessage("查看补充文件: 编号=" ViewFileIndex " 路径=" TaskList[ViewFileIndex].SupplementPath)
} else {tempPath := TaskList[ViewFileIndex].SupplementPathToolTip, 补充文件不存在:%tempPath%SetTimer, RemoveTooltip, -2000LogMessage("查看失败: 补充文件路径不存在 - " tempPath)
}
returnClearProcessed:
MsgBox, 清除已处理任务功能已禁用,以保留任务记录!
returnDeleteProcessed:
Gui, Main:ListView, ProcessedList
SelectedRow := LV_GetNext()
if (SelectedRow > 0 && (TaskList[SelectedRow].MainSent || TaskList[SelectedRow].SupplementSent)) {TaskList[SelectedRow] := {Name: "", MainPath: "", MainName: "", SupplementPath: "", SupplementName: "", MainSent: true, SupplementSent: true}Gosub, SaveTaskListGosub, UpdateRemainingTasksGosub, RefreshTaskListsToolTip, 已删除已处理任务:%SelectedRow%SetTimer, RemoveTooltip, -2000LogMessage("删除已处理任务: 编号=" SelectedRow)
} else {ToolTip, 无法删除!SetTimer, RemoveTooltip, -2000
}
returnPauseSend:
IsPaused := !IsPaused
if (IsPaused) {try {Hotkey, %MoveUpKey%, OffHotkey, %MoveDownKey%, OffHotkey, %DeleteFileKey%, OffHotkey, %StartSendKey%, OffHotkey, %SendSupplementKey%, OffHotkey, %SkipFileKey%, OffLogMessage("暂停时禁用快捷键成功")} catch e {LogMessage("暂停时禁用快捷键失败: " e)}Gui, Main:HideClickDetectionStatus := "已暂停"
} else {try {Hotkey, %MoveUpKey%, OnHotkey, %MoveDownKey%, OnHotkey, %DeleteFileKey%, OnHotkey, %StartSendKey%, OnHotkey, %SendSupplementKey%, OnHotkey, %SkipFileKey%, OnLogMessage("恢复时启用快捷键成功")} catch e {LogMessage("恢复时启用快捷键失败: " e)}Gui, Main:ShowWinActivate, ahk_id %MainGuiHwnd%DetectionStatus := "就绪"
}
GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
GuiControl, Main:, StatusBar, % (IsPaused ? "状态: 已暂停" : "状态: 就绪")
ToolTip, % (IsPaused ? "已暂停" : "已恢复")
SetTimer, RemoveTooltip, -2000
LogMessage("发送状态: " (IsPaused ? "暂停" : "恢复"))
returnSortTempList(TempList) {TempArray := []for Index, TaskObj in TempList {TaskName := TaskObj.NameRegExMatch(TaskName, "^\D*(\d+)", Match)Num := Match1 ? Match1 : 999999TempArray.Push({Num: Num, Obj: TaskObj})}SortArray(TempArray, 1, TempArray.Length())TempList := []for Index, Item in TempArrayTempList.Push(Item.Obj)
}SortArray(arr, left, right) {if (left < right) {pivot := Partition(arr, left, right)SortArray(arr, left, pivot - 1)SortArray(arr, pivot + 1, right)}
}Partition(arr, left, right) {pivotValue := arr[right].Numi := left - 1Loop, % right - left + 1 {j := left + A_Index - 1if (arr[j].Num <= pivotValue) {i++Temp := arr[i]arr[i] := arr[j]arr[j] := Temp}}Temp := arr[i + 1]arr[i + 1] := arr[right]arr[right] := Tempreturn i + 1
}RefreshTaskLists:
GuiControl, Main:-Redraw, ToProcessList
GuiControl, Main:-Redraw, ProcessedList
Gui, Main:ListView, ToProcessList
LV_Delete()
Loop, % TaskList.Length() {TaskObj := TaskList[A_Index]MainDisplay := !TaskObj.MainSent ? TaskObj.MainName : ""SupplementDisplay := (TaskObj.SupplementPath != "" && !TaskObj.SupplementSent) ? TaskObj.SupplementName : ""LV_Add("", A_Index, MainDisplay, SupplementDisplay)
}
LV_ModifyCol()
LV_ModifyCol(1, 60)
LV_ModifyCol(2, 150)
LV_ModifyCol(3, 150)Gui, Main:ListView, ProcessedList
LV_Delete()
Loop, % TaskList.Length() {TaskObj := TaskList[A_Index]MainDisplay := TaskObj.MainSent ? TaskObj.MainName . " (已发送)" : ""SupplementDisplay := TaskObj.SupplementSent ? TaskObj.SupplementName . " (已发送)" : ""LV_Add("", A_Index, MainDisplay, SupplementDisplay)
}
LV_ModifyCol()
LV_ModifyCol(1, 60)
LV_ModifyCol(2, 150)
LV_ModifyCol(3, 150)
GuiControl, Main:+Redraw, ToProcessList
GuiControl, Main:+Redraw, ProcessedListGosub, UpdateStatusBar
LogMessage("任务列表刷新完成: 总任务数=" TaskList.Length())
returnUpdateStatusBar:
if (IsPaused)GuiControl, Main:, StatusBar, 状态: 已暂停
else {NextIndex := 0Loop, % TaskList.Length() {if (!TaskList[A_Index].MainSent || (TaskList[A_Index].SupplementPath != "" && !TaskList[A_Index].SupplementSent)) {NextIndex := A_Indexbreak}}if (NextIndex > 0) {TaskObj := TaskList[NextIndex]NextFile := !TaskObj.MainSent ? TaskObj.MainName : TaskObj.SupplementNameGuiControl, Main:, StatusBar, % "状态: 下次发送 " NextIndex " - " NextFile ",请按 " StartSendKey " 发送"} elseGuiControl, Main:, StatusBar, 状态: 所有任务已发送完成
}
returnListViewClick:
if (A_GuiEvent = "DoubleClick") {Gui, Main:ListView, %A_GuiControl%SelectedRow := LV_GetNext()if (SelectedRow > 0) {Gui, FileChoice:New, +AlwaysOnTopGui, FileChoice:Add, Button, w100 gViewMainFile, 查看主文件Gui, FileChoice:Add, Button, w100 gViewSupplementFile, 查看补充文件Gui, FileChoice:Showglobal ViewFileIndex := SelectedRow}
}
returnToggleFileNameOptions:
Gui, Main:Submit, NoHide
if (IncludeFileName) {GuiControl, Main:Enable, WithExtGuiControl, Main:Enable, WithoutExtif (!WithExt && !WithoutExt)GuiControl, Main:, WithExt, 1
} else {GuiControl, Main:Disable, WithExtGuiControl, Main:Disable, WithoutExtGuiControl, Main:, WithExt, 0GuiControl, Main:, WithoutExt, 0
}
Gosub, SaveSettings
returnSaveSettings:
Gui, Main:Submit, NoHide
IniWrite, %IncludeFileName%, %ConfigFile%, Settings, IncludeFileName
IniWrite, %WithExt%, %ConfigFile%, Settings, WithExt
IniWrite, %WithoutExt%, %ConfigFile%, Settings, WithoutExt
IniWrite, %IncludeFullPath%, %ConfigFile%, Settings, IncludeFullPath
IniWrite, %TriggerCustomKeyAfterSend%, %ConfigFile%, Settings, TriggerCustomKeyAfterSend
LogMessage("保存设置: IncludeFileName=" IncludeFileName " WithExt=" WithExt " WithoutExt=" WithoutExt " IncludeFullPath=" IncludeFullPath " TriggerCustomKeyAfterSend=" TriggerCustomKeyAfterSend)
returnSaveStartTriggerMode:
Gui, Main:Submit, NoHide
StartTriggerMode := (StartTriggerModeKey = 1) ? 0 : 1
IniWrite, %StartTriggerMode%, %ConfigFile%, Settings, StartTriggerMode
if (StartTriggerMode = 0) {try {Hotkey, %StartTriggerKey%, SimulateStartSendClickLogMessage("绑定 StartTriggerKey: " StartTriggerKey " 成功")} catch e {LogMessage("绑定 StartTriggerKey: " StartTriggerKey " 失败: " e)}SetTimer, MonitorSignal, OffDetectionStatus := "就绪(快捷键模式)"
} else {try {Hotkey, %StartTriggerKey%, OffLogMessage("解除 StartTriggerKey 绑定: " StartTriggerKey)} catch e {}SetTimer, MonitorSignal, 100DetectionStatus := "监控中(信号量模式)"
}
GuiControl,, DetectionStatusDisplay, 检测状态: %DetectionStatus%
LogDebug("保存被触发模式: " (StartTriggerMode = 0 ? "快捷键" : "信号量"))
returnSaveNextTriggerMode:
Gui, Main:Submit, NoHide
NextTriggerMode := (NextTriggerModeKey = 1) ? 0 : 1
IniWrite, %NextTriggerMode%, %ConfigFile%, Settings, NextTriggerMode
LogDebug("保存触发下一脚本模式: " (NextTriggerMode = 0 ? "快捷键" : "信号量"))
returnRemoveTooltip:
ToolTip
returnGuiClose:
Gui, Main:Hide
GuiVisible := 0
IniWrite, %GuiVisible%, %ConfigFile%, Settings, GuiVisible
SetTimer, MonitorSignal, Off
Gui, Float:Destroy
LogMessage("GUI 关闭")
returnSaveTriggerDelay:
Gui, Main:Submit, NoHide
TriggerDelay := TriggerDelay
IniWrite, %TriggerDelay%, %ConfigFile%, Settings, TriggerDelay
ToolTip, 触发延迟已设置为:%TriggerDelay%ms
SetTimer, RemoveTooltip, -2000
LogMessage("设置触发延迟: " TriggerDelay "ms")
returnShowHotkeyMenu:
Menu, HotkeyMenu, Add
Menu, HotkeyMenu, DeleteAll
Menu, HotkeyMenu, Add, 上移 (%MoveUpKey%), SetMoveUpKey
Menu, HotkeyMenu, Add, 下移 (%MoveDownKey%), SetMoveDownKey
Menu, HotkeyMenu, Add, 删除 (%DeleteFileKey%), SetDeleteFileKey
Menu, HotkeyMenu, Add, 发送 (%StartSendKey%), SetStartSendKey
Menu, HotkeyMenu, Add, 发送补充 (%SendSupplementKey%), SetSendSupplementKey
Menu, HotkeyMenu, Add, 跳过 (%SkipFileKey%), SetSkipFileKey
Menu, HotkeyMenu, Add, 暂停 (%PauseSendKey%), SetPauseSendKey
Menu, HotkeyMenu, Add, 自定义快捷键 (%CustomKey%), SetCustomKey
Menu, HotkeyMenu, Add, 被触发快捷键 (%StartTriggerKey%), SetStartTriggerKey
Menu, HotkeyMenu, Add, 下一触发快捷键 (%NextTriggerKey%), SetNextTriggerKey
Menu, HotkeyMenu, Show
returnSetMoveUpKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "MoveUpKey"
global CurrentLabel := "MoveUp"
returnSetMoveDownKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "MoveDownKey"
global CurrentLabel := "MoveDown"
returnSetDeleteFileKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "DeleteFileKey"
global CurrentLabel := "DeleteFile"
returnSetStartSendKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "StartSendKey"
global CurrentLabel := "SimulateStartSendClick"
returnSetSendSupplementKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "SendSupplementKey"
global CurrentLabel := "SimulateSendSupplementClick"
returnSetSkipFileKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "SkipFileKey"
global CurrentLabel := "SkipFile"
returnSetPauseSendKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "PauseSendKey"
global CurrentLabel := "PauseSend"
returnSetCustomKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "CustomKey"
global CurrentLabel := "TriggerCustomKey"
returnSetStartTriggerKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "StartTriggerKey"
global CurrentLabel := "SimulateStartSendClick"
returnSetNextTriggerKey:
Gosub, ShowHotkeyInput
global CurrentHotkeyField := "NextTriggerKey"
global CurrentLabel := ""
returnShowHotkeyInput:
Gui, KeyInput:New, +AlwaysOnTop
Gui, KeyInput:Add, CheckBox, vUseCtrl gUpdateHotkeyPreview, 使用 Ctrl
Gui, KeyInput:Add, CheckBox, vUseAlt gUpdateHotkeyPreview xm, 使用 Alt
Gui, KeyInput:Add, CheckBox, vUseWin gUpdateHotkeyPreview xm, 使用 Win
Gui, KeyInput:Add, Text, xm, 选择按键:
Gui, KeyInput:Add, DropDownList, vHotkeyChoice gUpdateHotkeyPreview, A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9|F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|Del
Gui, KeyInput:Add, Text, xm vHotkeyPreview, 快捷键预览:
Gui, KeyInput:Add, Button, default w80 gSaveHotkey, 确定
Gui, KeyInput:Show
returnUpdateHotkeyPreview:
Gui, KeyInput:Submit, NoHide
newKey := ""
if (UseCtrl)newKey .= "^"
if (UseAlt)newKey .= "!"
if (UseWin)newKey .= "#"
if (HotkeyChoice != "")newKey .= HotkeyChoice
GuiControl, KeyInput:, HotkeyPreview, 快捷键预览: %newKey%
returnSaveHotkey:
Gui, KeyInput:Submit
newKey := ""
if (UseCtrl)newKey .= "^"
if (UseAlt)newKey .= "!"
if (UseWin)newKey .= "#"
if (HotkeyChoice != "")newKey .= HotkeyChoice
else {MsgBox, 请选择一个按键!Gui, KeyInput:Showreturn
}
if (newKey = "") {MsgBox, 请至少选择一个修饰键或按键!Gui, KeyInput:Showreturn
}
if (newKey = MoveUpKey || newKey = MoveDownKey || newKey = DeleteFileKey || newKey = StartSendKey || newKey = SendSupplementKey || newKey = SkipFileKey || newKey = PauseSendKey || newKey = CustomKey || newKey = StartTriggerKey || newKey = NextTriggerKey) && (newKey != %CurrentHotkeyField%) {MsgBox, 快捷键 %newKey% 已与其他功能冲突,请选择其他组合!Gui, KeyInput:Showreturn
}
if (%CurrentHotkeyField% != "") {try {Hotkey, % %CurrentHotkeyField%, OffLogMessage("释放旧快捷键 " CurrentHotkeyField ": " %CurrentHotkeyField% " 成功")} catch e {LogMessage("释放旧快捷键 " CurrentHotkeyField ": " %CurrentHotkeyField% " 失败: " e)}
}
%CurrentHotkeyField% := newKey
IniWrite, %newKey%, %ConfigFile%, Hotkeys, %CurrentHotkeyField%
if (CurrentLabel != "") {try {Hotkey, %newKey%, %CurrentLabel%LogMessage("绑定新快捷键 " CurrentHotkeyField ": " newKey " 成功")} catch e {LogMessage("绑定新快捷键 " CurrentHotkeyField ": " newKey " 失败: " e)defaultKey := (CurrentHotkeyField = "MoveUpKey" ? "^Up" : CurrentHotkeyField = "MoveDownKey" ? "^Down" : CurrentHotkeyField = "DeleteFileKey" ? "^Delete" : CurrentHotkeyField = "StartSendKey" ? "^!s" : CurrentHotkeyField = "SendSupplementKey" ? "^!u" : CurrentHotkeyField = "SkipFileKey" ? "^!k" : CurrentHotkeyField = "PauseSendKey" ? "^!p" : CurrentHotkeyField = "CustomKey" ? "^!t" : CurrentHotkeyField = "StartTriggerKey" ? "^!s" : CurrentHotkeyField = "NextTriggerKey" ? "^!m" : "^!n")%CurrentHotkeyField% := defaultKeyIniWrite, %defaultKey%, %ConfigFile%, Hotkeys, %CurrentHotkeyField%try {Hotkey, %defaultKey%, %CurrentLabel%LogMessage("恢复默认快捷键 " CurrentHotkeyField ": " defaultKey " 成功")} catch e {LogMessage("恢复默认快捷键 " CurrentHotkeyField ": " defaultKey " 失败: " e)}}
}
GuiControl, Main:, %CurrentHotkeyField%Display, % (CurrentHotkeyField = "MoveUpKey" ? "上移" : CurrentHotkeyField = "MoveDownKey" ? "下移" : CurrentHotkeyField = "DeleteFileKey" ? "删除" : CurrentHotkeyField = "StartSendKey" ? "发送" : CurrentHotkeyField = "SendSupplementKey" ? "发送补充" : CurrentHotkeyField = "SkipFileKey" ? "跳过" : CurrentHotkeyField = "PauseSendKey" ? "暂停" : CurrentHotkeyField = "CustomKey" ? "自定义" : CurrentHotkeyField = "StartTriggerKey" ? "被触发" : "下一触发") "快捷键: " newKey
Gui, KeyInput:Destroy
ToolTip, %CurrentHotkeyField% 已设置为:%newKey%, , , , 16
SetTimer, RemoveTooltip, -2000
LogMessage(CurrentHotkeyField " 设置为: " newKey)
returnReAddMainToOrigin:
Gui, Main:ListView, ProcessedList
SelectedRow := LV_GetNext()
if (SelectedRow > 0 && TaskList[SelectedRow].MainSent && TaskList[SelectedRow].MainPath != "") {TaskList[SelectedRow].MainSent := falseGosub, SaveTaskListGosub, UpdateRemainingTasksGosub, RefreshTaskListstemp_task := TaskList[SelectedRow].MainNameToolTip, 已将主任务 %SelectedRow% - %temp_task% 重新加入原位SetTimer, RemoveTooltip, -2000LogMessage("重新加入主任务原位: 编号=" SelectedRow " 名称=" TaskList[SelectedRow].MainName)
} else {ToolTip, 无法重新加入主任务!请确认已选择已发送的主任务SetTimer, RemoveTooltip, -2000LogMessage("重加主任务失败: 编号=" SelectedRow " 未选择有效任务或主任务未发送")
}
returnReAddSupplementToOrigin:
Gui, Main:ListView, ProcessedList
SelectedRow := LV_GetNext()
if (SelectedRow > 0 && TaskList[SelectedRow].SupplementSent && TaskList[SelectedRow].SupplementPath != "") {TaskList[SelectedRow].SupplementSent := falseGosub, SaveTaskListGosub, UpdateRemainingTasksGosub, RefreshTaskListstemp_task := TaskList[SelectedRow].SupplementNameToolTip, 已将补充文件 %SelectedRow% - %temp_task% 重新加入原位SetTimer, RemoveTooltip, -2000LogMessage("重新加入补充文件原位: 编号=" SelectedRow " 名称=" TaskList[SelectedRow].SupplementName)
} else {ToolTip, 无法重新加入补充文件!请确认已选择已发送的补充文件SetTimer, RemoveTooltip, -2000LogMessage("重加补充文件失败: 编号=" SelectedRow " 未选择有效任务或补充文件未发送")
}
return
相关文章:
发送文件脚本源码版本
V1 适配win10和 win11 #SingleInstance Force SendMode Input SetWorkingDir %A_ScriptDir%; Global variables global TaskList : [] global CurrentFileConfig : "current_file.ini" global RemainingFilesConfig : "remaining_files.ini" global File…...

Vue部署到Nginx上及问题解决
一、Vue打包 dist文件即打包文件 二、下载Nginx,将dist内容全部复制到Nginx的html下 三、修改Nginx的nginx.conf配置文件,添加try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html; 是 Nginx 配置中的一个重要指令,用于处理…...
MCP(Model Context Protocol)与提示词撰写
随着大模型(LLM)在复杂任务中的普及,如何让模型高效调用外部工具和数据成为关键挑战。传统函数调用(Function Calling)依赖开发者手动封装 API,而 MCP(Model Context Protocol) 通过…...
每日一令:Linux 极简通关指南 - 汇总
专栏列表 💻 每日一令:Linux 极简通关指南 (25篇) 【基础】每天掌握一个Linux命令 - nsenter:深入容器与命名空间的利器 发布于 2025-06-08 22:27:04【基础】 每天掌握一个Linux命令 - journalctl:系统日志管理的得力助手 发布于…...

项目-- Json-Rpc框架
目录 项目简介环境搭建Ubuntu-22.04 第三方库使用JsonCppMuduo基础类EventLoop类TcpConnection类Buffer类TcpClient类TcpServer类 服务端基本搭建客户端基本搭建 future 项目设计通用模块设计Rpc功能模块设计发现者设计提供者设计服务注册中心设计 Topic功夫模块设计主题管理中…...

因泰立科技H1X激光雷达:因泰立科技为智慧工业注入新动力
在当今工业领域,精准测量与高效作业是推动产业升级的关键因素。因泰立科技推出的H1X三维轮廓扫描激光雷达,凭借其卓越的性能和广泛的应用场景,正成为智慧工业中不可或缺的高科技装备。 产品简介 H1X三维轮廓扫描激光雷达是因泰立科技基于二维…...
day50 随机函数与广播机制
目录 一、随机张量的生成 1.1 torch.randn() 函数 1.2 其他随机函数 1.3 输出维度测试 二、广播机制 2.1 广播机制的规则 2.2 加法的广播机制 二维张量与一维向量相加 三维张量与二维张量相加 二维张量与标量相加 高维张量与低维张量相加 2.3 乘法的广播机制 批量…...
Codeforces Educational 179(ABCDE)
前言 byd这组题纯靠感觉是吧…^_^ b题赛时举了无数个例子都没想明白,然后一直卡到结束,后面题都没看到,结果补题的时候c题d题直接秒了…-_-|| A. Energy Crystals #include <bits/stdc.h> using namespace std;typedef long long …...
基于 actix-web 框架的简单 demo
以下是一个基于 actix-web 框架的简单 demo, 如果你还没有 Rust,我们建议你使用 rustup 来管理你的 Rust 安装。官方 Rust 指南有一个很棒的入门部分。 Actix Web 目前支持的最低 Rust 版本 (MSRV) 为 1.72。运行 rustup update…...

python:Tkinter 开发邮件客户端,能编写邮件,发送邮件带附件
Python Tkinter 邮件客户端 下面是一个使用 Python Tkinter 开发的简单邮件客户端,支持编写邮件和发送邮件功能: 功能说明 这个邮件客户端包含以下功能: 邮件编写功能: 收件人地址输入抄送地址输入邮件主题输入邮件正文编辑区&…...
CMake基础:gcc/g++编译选项详解
目录 1.编译步骤 2.gcc 与 g 区别 3.gcc 命令的常用选项 3.1.基础编译选项 3.2.优化选项 3.3.调试与分析选项 3.4.链接选项 3.5.语言特性选项(C 特化) 3.6.安全增强选项 3.7.架构与指令集优化 3.8.其他常用选项 4.常见编译组合示例 5.常用环…...

深入解析Java21核心新特性(虚拟线程,分代 ZGC,记录模式模式匹配增强)
文章目录 前言一、虚拟线程 (Virtual Threads - JEP 444) - 并发的革命1.1 解决的核心问题🎯1.2 工作原理与核心机制⚙️1.3 使用详解与最佳实践🛠️1.4 注意事项⚠️1.5 总结 📚 二、分代 ZGC (Generational ZGC - JEP 439) - 低延迟新高度2…...

免费批量去水印工具 - 针对文心一言生成图片
免费批量去水印工具 - 针对文心一言生成图片 工具介绍 这是一款免费的批量去水印工具,专门针对文心一言生成的图片进行处理。通过简单的操作,您可以快速去除图片中的水印。 下载链接 您可以通过以下网盘链接下载工具: 链接: https://pa…...
android 之 MediaExtractor
MediaExtractor 是Android多媒体处理的基础组件,解封装是其核心价值。 一、功能与定位 MediaExtractor 是Android多媒体框架中的媒体解封装工具,主要作用是从媒体文件(如MP4、MKV、MP3)中分离音视频轨道数据,为后续解…...
行业案例 | ASOS 借助 Azure AI Foundry(国际版)为年轻时尚爱好者打造惊喜体验
英国潮流电商ASOS借力微软Azure OpenAI,打造生成式AI购物新体验。平台整合大语言模型与推荐引擎,通过智能聊天交互帮年轻用户探索穿搭灵感,精准匹配近900个品牌的潮流单品,实现技术升级与个性化需求的双重突破。 使用 Azure Open…...

在WPS中如何启用宏VBA wps.vba.exe下载和安装
首先我们点击导航栏中的【工具】,点击左侧 运行宏,根据提示 点击 立即加载。加载卡在50%时间比较长,耐心等待。 关闭wps重新打开后, word和xls表格都可以使用了。 如果电脑无法联网,需要提前下载 WPS VBA插件 WPS VB…...
12.7Swing控件5 JProgressBar
Swing 进度条(JProgressBar)是用于可视化展示任务完成进度的组件,通常用于显示长时间运行任务的完成百分比。以下是关于 Swing 进度条的详细介绍: 1. 基本概念与用途 作用:直观展示任务完成进度,避免用户…...

Hardware-Efficient Attention for Fast Decoding
TL;DR 2025 年普林斯顿大学提出的硬件友好 attention 设计,在 MQA/GQA 与 deepseek 提出的 MLA 基础之上继续优化,提出 Grouped-Tied Attention (GTA) 和 Grouped Latent Attention (GLA),实现更高推理效率的同时也能保持较好的模型效果。 …...

LLMs 系列科普文(13)
十三、AlphaGO 提到强化学习的历史,不得不提到 alphago,如果你不记得这是什么了,那你是否还曾记得,早些年 AI 已经可以在围棋中击败人类选手了。 AlphaGO 系统又 DeepMind 公司开发,你可以在网络上找到当初人机大战的…...
kubernetes jenkins pipeline优化拉取大仓库性能指定分支+深度
有时候我们历史的git仓库,提交了某个比较大的文件如果不限制 depth ,就会拉取所有的历史提交记录,这样在历史仓库比较大的时候 clone 非常之慢,而实际上我们只需要最新的代码来构建就行了,为了优化性能,我们…...

element-plus 单选组件 el-radio,选不上,又没报错,直接复制官网也不行解决方案
在使用 Vue 框架开发项目时,Element UI 是常用的组件库。最近在开发中遇到了 Element 单选框组件el-radio的双向绑定问题,直接复制element官网上的的案例下来也是不得,经过调试和探索,终于找到了解决方案,特此记录分享…...
UDP:简洁高效的报文结构解析与关键注意事项
UDP(User Datagram Protocol)以其无连接、低开销的特性,成为实时应用(如视频、游戏、DNS)的首选传输协议。深入理解其报文结构和注意事项,是高效利用UDP的基础。 一、UDP报文结构:简洁的四段式 …...

idea 启动jar程序并调试
添加一个JAR 应用程序,填写以下内容: JAR路径:填写你要启动的jar程序的绝对路径 虚拟机选项:-Xmx1G -Xms1G -agentlib:jdwptransportdt_socket,servery,suspendn,address*:5005 程序实参(可选,minecraft专用…...

CSS 轮廓(Outline)与边框(Border)的深度解析
在 CSS 中,轮廓(outline)和边框(border)是两个用于装饰元素的重要属性,但它们在功能、渲染机制和应用场景上存在显著差异。下面从多个维度进行详细对比: 一、基础定义与语法差异 边框…...
Spring Boot 2 中 default-autowire 的使用
Spring Boot 2 中 default-autowire 的使用 在 Spring Boot 2 中,default-autowire 这个来自传统 XML 配置的概念仍然存在,但它的使用已经大大减少,因为现代 Spring Boot 应用主要使用注解驱动的配置方式。 default-autowire 在 Spring Boo…...

Docker 部署 Python 的 Flask项目
文章目录 一、构建运行 Docker 容器1. 查找合适镜像2.本地docker 拉取镜像3.项目配置1. python项目下生成 requirements.txt 依赖文件2. 生成Dockerfile文件3.忽略不必要文件4. 构建镜像 4. 运行容器5.测试 二、常见问题与解决方案 一、构建运行 Docker 容器 1. 查找合适镜像 …...
12.vite,webpack构建工具
😺😺 😺1.vite 介绍和对比 🏷️ Vite 是什么? 👉 Vite 是一个 前端构建工具 开发服务器, 可以帮你: • 开发阶段:秒开项目,改代码能瞬间热更新(…...

Vue入门到实战之第一篇【超基础】
Vue入门到实战之第一篇 学习路线1. Vue 概念1.1 Vue 是什么 2. 创建Vue实例,初始化渲染3. 插值表达式 {{ }}4. Vue响应式特性5. 开发者工具 学习路线 1. Vue 概念 1.1 Vue 是什么 概念: Vue是一个用于 构建用户界面1 的 渐进式2 框架3 1:基…...
Selenium自动化操作
1、跳转页面播放视频 我们以b站为例,测试是否可以点击模块进行播放视频 //点击页面看是否视频正常播放public void turn() throws InterruptedException {driver.findElement(By.cssSelector("#i_cecream > div.bili-feed4 > main > div.feed2 >…...

实时数据分析的技术架构:Lambda vs Kappa架构选择
文章目录 引言:实时数据分析架构的重要性Lambda架构深度解析Kappa架构技术特性架构对比分析维度性能与可扩展性评估技术栈选型指南实际应用场景分析成本效益对比模型混合架构与演进策略企业级决策框架最佳实践与案例研究技术趋势与未来展望引言:实时数据分析架构的重要性 在…...