Autohotkey个人即用脚本分享(持续更新ing)

对文件移动专家的更新,但是未必所有人喜欢,所以仍保留第一版在上面,另开一楼贴2.0版。

文件移动专家2.0

image

代码
#Requires AutoHotkey v2.0
#SingleInstance Force
global allcopyed
global activedir
global clipold
kk:=1

;获取当前文件的两重父文件夹
{
activedir:=Explorer_GetPath()
SplitPath activedir , , &activedirpapa
SplitPath activedirpapa , , &activediryaya
}

;获取选中的文件、文件夹列表
{
clipold:=A_Clipboard
A_Clipboard:=""
sendinput "^c"
allcopyed:=""
ClipWait(0.2)
ClipSaved := ClipboardAll()
A_Clipboard := ClipSaved 
ClipSaved := ""
allcopyed:=A_Clipboard
A_Clipboard:=""
;msgbox(allcopyed activedir activedirpapa activediryaya)
}

{
	global WinID := WinExist("A")
	ContextMenu := Menu()

	{	ContextMenu.insert(,"包裹到新文件夹", foldtonew)	
		;如要添加自定义路径,可复制本行和下一行,只修改其中路径即可
		ContextMenu.SetIcon(kk "&", "shell32.dll", 301)
		kk++
		
		ContextMenu.insert(,activediryaya, MenuHandler)	;如要添加自定义路径,可复制本行和下一行,只修改其中路径即可
		ContextMenu.SetIcon(kk "&", "shell32.dll", 147)
		kk++
		ContextMenu.insert(,activedirpapa, MenuHandler)	;如要添加自定义路径,可复制本行和下一行,只修改其中路径即可
		ContextMenu.SetIcon(kk "&", "shell32.dll", 147)
		kk++
		ContextMenu.Add
		kk++
	}

	;---------------资源管理器-------------------------
	For openedwindows in ComObject("shell.Application").windows
	{
		This := openedwindows.Document.Folder.Self.Path
		ContextMenu.insert(,This, MenuHandler)
		ContextMenu.SetIcon(kk "&", "shell32.dll", 5)
		kk++
	}
	openedwindows := ""	;清空变量

;去除当前文件夹
ContextMenu.Delete(activedir)
kk--

	;---------------Total Commander-------------------
	if WinExist("ahk_class TTOTAL_CMD")
	{
		TCPath := WinGetProcessPath("ahk_class TTOTAL_CMD")
		cm_CopySrcPathToClip := 2029	;Total Commander 内部代码
		cm_CopyTrgPathToClip := 2030
		ClipSaved := ClipboardAll()
		A_Clipboard := ""

		SendMessage(1075, cm_CopySrcPathToClip, 0, , "ahk_class TTOTAL_CMD")
		ContextMenu.Add
		kk++
		ContextMenu.insert(,A_Clipboard, MenuHandler)
		ContextMenu.SetIcon(A_Clipboard, TCPath, 1)
		kk++

		SendMessage(1075, cm_CopyTrgPathToClip, 0, , "ahk_class TTOTAL_CMD")
		ContextMenu.insert(,A_Clipboard, MenuHandler)
		ContextMenu.SetIcon(A_Clipboard, TCPath, 1)
		kk++

		A_Clipboard := ClipSaved
		ClipSaved := ""
	}
	;--------------常用文件夹-------
	ContextMenu.Add
	ContextMenu.Add("常用路径", nothing)
	KK:=kk+2
	ContextMenu.insert(,"C:\miniapp", MenuHandler)	;如要添加自定义路径,可复制本行和下一行,只修改其中路径即可
	ContextMenu.SetIcon(kk "&", "shell32.dll", 44)
	kk++
	
	ContextMenu.insert(,"G:\代码库\自写软件\clauch增强\ahks", MenuHandler)	
	ContextMenu.SetIcon(kk "&", "shell32.dll", 44)
	kk++
	
	;ContextMenu.Add("%UserProfile%\", MenuHandler)	;用户文件夹
	;ContextMenu.SetIcon("%UserProfile%\", "shell32.dll", 44)
	;------------------------------
	
	;获取最近文件夹5个
	ContextMenu.Add
	kk++
{
k:=0
filesget:=""
Loop Files, "C:\Users\" A_UserName "\AppData\Roaming\Microsoft\Windows\Recent\*.lnk", "F"
{
	vPath := A_LoopFilePath
	FileGetShortcut(vPath, &vTarget)
	vAttrib := FileExist(vTarget)
	if InStr(vAttrib, "D")
	{
	if ! InStr(filesget, vTarget "`r`n")
	{
	ContextMenu.insert(,vTarget, MenuHandler)
	ContextMenu.SetIcon(kk "&", "shell32.dll", 21)
	kk++
	k++
	filesget.=vTarget "`r`n"
	}
	;msgbox(filesget)
	}
if k-4>0
	break
}
}
	
	ContextMenu.Show
	ContextMenu.Delete
} 

#HotIf	;关闭上下文相关性

nothing(ItemName, ItemPos, MyMenu)
{
	return
}

foldtonew(ItemName, ItemPos, MyMenu)
{
	global activedir
	global allcopyed
	global clipold
	
if ! clipold
	ItemName:=activedir "\新建文件夹"
else
{
	clipold:= SubStr(clipold, 1 , 100)
	clipold := RegExReplace(clipold, "[`t`"!@#$%^&*()\-+=<>?:{}|,\/;'\\[\]·~]+" , , , -1, 1)
	clipold := StrReplace(clipold, "`r", , , , -1) ; 去除回车
	clipold := StrReplace(clipold, "`n", , , , -1) ; 去除回车
	ItemName:=activedir "\" clipold
}

	dircreate ItemName
	
Loop parse, allcopyed, "`n", "`r"
{
	if ! DirExist(A_LoopField)
	FileMove A_LoopField, ItemName "\" , 0
	else
	{
		SplitPath A_LoopField , &OutFileName
		DirMove A_LoopField, ItemName "\" OutFileName, 0
	}
}
}

MenuHandler(ItemName, ItemPos, MyMenu)
{
	global allcopyed
	WinActivate "ahk_id" WinID

errorfind:=0

	if allcopyed
{
	Loop parse, allcopyed, "`n", "`r"
{
	try
  {
	;msgbox A_LoopField
	if ! DirExist(A_LoopField)
	FileMove A_LoopField, ItemName "\" , 0
	else
	{
		SplitPath A_LoopField , &OutFileName
		DirMove A_LoopField, ItemName "\" OutFileName, 0
	}
	}
	catch
		errorfind++
}
if errorfind
	msgbox errorfind "个文件未成功移动,大概是因为有重复文件"
}
	else
{
	try
	{
		if ControlGetEnabled("ToolbarWindow323", WinID) = 1 or ControlGetEnabled("ToolWindow324", WinID) = 1
		{
			Send "!d"
			Sleep 100	;等待获取焦点,如果设为 50 ,在 chrome 中另存为会出现焦点错误
			addressbar := ControlGetFocus("A")	; 按下 alt+D 之后的焦点为地址栏
			ControlSetText(ItemName, addressbar, "A")
			ControlSend("{Enter}", addressbar, "A")
			ControlFocus("Edit1", "A")	;焦点移回到 Edit1
		}
	}
	catch TargetError
	{
		FolderPath := ItemName
		OldText := ControlGetText("Edit1", "A")	;读取当前 Edit1 控件中的文件名
		ControlFocus "Edit1", "A"

		Loop 5
		{
			ControlSetText FolderPath, "Edit1", "ahk_id" WinID
			Sleep(50)
			CurControlText := ControlGetText("Edit1", "ahk_id" WinID)
			if (CurControlText = FolderPath)
				break
		}

		Sleep 50
		ControlSend "{Enter}", "Edit1", "A"
		Sleep 50

		If !OldText	;插入原始文件名
			return

		Loop 5
		{
			ControlSetText OldText, "Edit1", "A"
			Sleep 50
			CurControlText := ControlGetText("Edit1", "A")
			if (CurControlText = OldText)
				break
		}
	}
}
}

Explorer_GetPath() {
   winClass := WinGetClass(hWnd := WinExist("A"))
   if !(winClass ~= "(Cabinet|Explore)WClass")
      return
   for window in ComObject("Shell.Application").Windows
      if (hWnd = window.hWnd)
         return window.Document.Folder.Self.Path
}
1 个赞

有没有针对 hk1.0版本的代码?

神乎其神!太强了

优雅!太优雅啦!

有不是v2版的ahk吗

我想把这个动作改成独立运行的 我都快哭了哈哈

image
文件移动专家2.0 移动桌面上的文件会出错

1 个赞

应该是没有获取到当前激活的路径名,可以加一个判断,
如果没有获取到当前激活的路径名,就干脆默认是在桌面。
你可以试试写一下 :face_with_peeking_eye:

啥动作啊

这个

activedir:=Explorer_GetPath()
if (activedir:="") {
    activedir:= A_Desktop
}

我以为加一句就好了,实际上各种报错,不会改 :sweat_smile:
image
image

1、CLaunch 的焦点转移是一个问题,用 WIN + F 的小窗。
2、获取上一级文件夹的功能,在桌面有问题,应该是桌面的特殊性。

第8-15行,改为:

;获取当前文件的两重父文件夹
{
activedir:=Explorer_GetPath()
if activedir=""
	activedir:=A_Desktop
SplitPath activedir , , &activedirpapa
SplitPath activedirpapa , , &activediryaya
}

第61行附近,改为:

;去除当前文件夹
try
{
ContextMenu.Delete(activedir)
kk--
}
catch
{
}

其实你改的没问题,就是有点粗心。。。

这里用等号,而不是赋值号

原来这是赋值的意思 :sweat_smile:
我说怎么输出都变空白了。

另外:papa和yaya 有些搞笑

大佬…小弟也出现了这个问题…该修改那边呢??谢谢
PixPin_2024-03-21_14-37-13

而这个也是出现了问题 都该如何修改…谢谢您了

PixPin_2024-03-21_14-39-25

你照着楼上的楼上那层 我说的改改试试

大佬2.0版本…已改成您的但还是出现错误

PixPin_2024-03-22_14-17-53

1.0 跟2.0 都出现这错误
再麻烦您了…谢谢

你是什么使用环境呀,win几,多少位,用的是默认文件管理器吧,应该是 Explorer_GetPath()这个函数不适配。