Windows Shell 基于数字而不是命令字符串的 Automation InvokeVerb
Windows Shell Automation InvokeVerb based on number instead of command string
通常 shell 自动化 InvokeVerb 仅接受字符串命令,基于此处的文档:https://msdn.microsoft.com/en-us/library/ms723189(v=vs.85).aspx
但是我注意到 cmd 行 EXE 实用程序接受数字
http://www.technosys.net/products/utils/pintotaskbar
这很有趣,因为在 Windows 10 中,“固定到任务栏”已从 shell 自动化中删除,尽管在 UI 中可见。 ( https://connect.microsoft.com/PowerShell/feedback/details/1609288/pin-to-taskbar-no-longer-working-in-windows-10 )
然而,此 EXE 传递 "number" 5386 作为命令工作。
我很想知道在 PowerShell/VBScript/.NET 语言或 Win32 C/C++ 中可以使用哪些方法来实现此目的。
我知道这几乎肯定不受支持,并且可能随时中断,因为这些数字在 OS 版本之间发生了变化。
在 PowerShell 中使用字符串版本的示例
$filepath = "C:\windows\system32\notepad.exe"
$path = Split-Path $FilePath
$shell= New-Object -com "Shell.Application"
$folder=$shell.Namespace($path)
$item = $folder.Parsename((split-path $FilePath -leaf))
$item.InvokeVerb("&Pin to taskbar")
底层的 shell 上下文菜单扩展系统实际上在本地使用数字 ID;字符串动词是顶部的 可选 层。然而,正如您所观察到的,命令 ID 是上下文菜单扩展的内部,并且不能保证在版本之间(甚至在调用之间)保持相同——动词的全部意义在于它们允许以编程方式调用命令,而不管它们的 ID 是什么。
在 C/C++ 中,您可以通过将数字 ID 转换为字符串指针来按 ID 调用命令(理由是因为所有有效的字符串指针都高于 65535,所以 "safe" 将数字作为字符串指针传递,只要它适合 16 位,因为接收 API 能够正确确定它是否是 "real string"。
请注意,这与将数字打印为字符串不同,后者是不正确的。 MAKEINTRESOURCE
宏的存在就是为了这个目的。
例如,ID 为 1234 的命令将使用 MAKEINTRESOURCE(1234)
作为动词来调用。
这些天我 运行 在一个基于 Windows Script Host 的脚本中遇到了同样的问题。
用本地化字符串调用动词不像以前那样有效。
但是,您仍然可以获得该项目的 "Verbs" 集合,然后枚举它们,直到您获得要调用的动词。然后你可以使用它的 "DoIt" 方法调用它,而不需要传入动词名称。
在 WSH JScript 中它看起来像这样:
/* workaround for 'item.InvokeVerb("&Delete")' which no longer works */
var verbs = item.Verbs(); // item == return of folder.ParseName(..)
for (var x = 0; x < verbs.Count; x++)
{
var verb = verbs.Item(x);
if (verb.Name == "&Delete") //replace with "&Pin to taskbar"
{
try
{
verb.DoIt();
WSH.Echo ("Deleted:", item.Name);
}
catch(e)
{
WSH.Echo ("Error Deleting:", item.Name + "\r\n\t", e.description, e.number);
}
break;
}
}
}
它可能在 PowerShell 中也能以某种方式工作
ffr:
https://docs.microsoft.com/en-us/windows/win32/shell/folderitem-verbs
https://docs.microsoft.com/en-us/windows/win32/shell/folderitemverb
通常 shell 自动化 InvokeVerb 仅接受字符串命令,基于此处的文档:https://msdn.microsoft.com/en-us/library/ms723189(v=vs.85).aspx
但是我注意到 cmd 行 EXE 实用程序接受数字 http://www.technosys.net/products/utils/pintotaskbar
这很有趣,因为在 Windows 10 中,“固定到任务栏”已从 shell 自动化中删除,尽管在 UI 中可见。 ( https://connect.microsoft.com/PowerShell/feedback/details/1609288/pin-to-taskbar-no-longer-working-in-windows-10 )
然而,此 EXE 传递 "number" 5386 作为命令工作。
我很想知道在 PowerShell/VBScript/.NET 语言或 Win32 C/C++ 中可以使用哪些方法来实现此目的。
我知道这几乎肯定不受支持,并且可能随时中断,因为这些数字在 OS 版本之间发生了变化。
在 PowerShell 中使用字符串版本的示例
$filepath = "C:\windows\system32\notepad.exe"
$path = Split-Path $FilePath
$shell= New-Object -com "Shell.Application"
$folder=$shell.Namespace($path)
$item = $folder.Parsename((split-path $FilePath -leaf))
$item.InvokeVerb("&Pin to taskbar")
底层的 shell 上下文菜单扩展系统实际上在本地使用数字 ID;字符串动词是顶部的 可选 层。然而,正如您所观察到的,命令 ID 是上下文菜单扩展的内部,并且不能保证在版本之间(甚至在调用之间)保持相同——动词的全部意义在于它们允许以编程方式调用命令,而不管它们的 ID 是什么。
在 C/C++ 中,您可以通过将数字 ID 转换为字符串指针来按 ID 调用命令(理由是因为所有有效的字符串指针都高于 65535,所以 "safe" 将数字作为字符串指针传递,只要它适合 16 位,因为接收 API 能够正确确定它是否是 "real string"。
请注意,这与将数字打印为字符串不同,后者是不正确的。 MAKEINTRESOURCE
宏的存在就是为了这个目的。
例如,ID 为 1234 的命令将使用 MAKEINTRESOURCE(1234)
作为动词来调用。
这些天我 运行 在一个基于 Windows Script Host 的脚本中遇到了同样的问题。
用本地化字符串调用动词不像以前那样有效。 但是,您仍然可以获得该项目的 "Verbs" 集合,然后枚举它们,直到您获得要调用的动词。然后你可以使用它的 "DoIt" 方法调用它,而不需要传入动词名称。
在 WSH JScript 中它看起来像这样:
/* workaround for 'item.InvokeVerb("&Delete")' which no longer works */
var verbs = item.Verbs(); // item == return of folder.ParseName(..)
for (var x = 0; x < verbs.Count; x++)
{
var verb = verbs.Item(x);
if (verb.Name == "&Delete") //replace with "&Pin to taskbar"
{
try
{
verb.DoIt();
WSH.Echo ("Deleted:", item.Name);
}
catch(e)
{
WSH.Echo ("Error Deleting:", item.Name + "\r\n\t", e.description, e.number);
}
break;
}
}
}
它可能在 PowerShell 中也能以某种方式工作
ffr:
https://docs.microsoft.com/en-us/windows/win32/shell/folderitem-verbs
https://docs.microsoft.com/en-us/windows/win32/shell/folderitemverb