如何使“Firewall Rule Delete”命令分配给右键按钮,以侦测文件的路径?

huangapple go评论76阅读模式
英文:

How do I make the "Firewall Rule Delete" command assigned to the right mouse button detect the path of the file?

问题

我已经为右键菜单创建了一个自定义属性,允许我在Windows 10中的任何文件上设置“防火墙规则”并阻止其访问互联网。

同样,我还有另一个属性,可以禁用或删除我创建的规则。
然而,我遇到了一个小问题。

该属性按预期工作,但它“删除所有具有相同名称的规则”。
它不考虑文件的路径,只考虑其名称。

我应该如何修改下面的代码,以便只删除特定路径的规则?

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall]
@=""
"MUIVerb"="Windows Firewall"
"icon"="%SystemRoot%\\system32\\FirewallControlPanel.dll,0"
"subcommands"=""

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall]

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Add Blocking Rule (Outgoing)]
@=""
MUIVerb"="Add Blocking Rule (Outgoing)"
"Icon"="%SystemRoot%\\system32\\FirewallControlPanel.dll,1"

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Add Blocking Rule (Outgoing)\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Executionpolicy ByPass -WindowStyle Hidden -NoLogo -Command \"start powershell -Verb runas -ArgumentList '\\\"-NoLogo -WindowStyle Hidden -command `\\\"New-NetFirewallRule -DisplayName ([System.IO.Path]::GetFilenameWithoutExtension('%1')) -Name '%1' -Enabled True -Direction Outbound -Action Block -Program '%1'`\\\"'\""

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Delete Rule (Outgoing)]
@=""
MUIVerb"="Unblock Rule (Outgoing)"
"Icon"="%SystemRoot%\\system32\\FirewallControlPanel.dll,2"

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Delete Rule (Outgoing)\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Executionpolicy Bypass -WindowStyle Hidden -NoLogo -Command \"Start-Process powershell -Verb RunAs -ArgumentList '\\\"-NoLogo -WindowStyle Hidden -Command `\\\"& {netsh advfirewall firewall delete rule name='\\\"'([System.IO.Path]::GetFileNameWithoutExtension('%1'))'\\\"' dir=out}'%1'`\\\"'\""

我将不胜感激您在这个问题上提供的任何帮助或指导。在此提前感谢您的关注和兴趣。

英文:

I have created a custom property for the right button menu that allows me to "Firewall Rule" any file in Windows 10 and block its internet access.

Similarly, I have another property that can disable or delete the rule I created.
However, I encountered a small problem.

The property works as intended, but it "deletes all rules with the same name".
It does not take into account the path of the file, only its name.

How can I modify the code below so that it only deletes the rule for the specific path?

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall]
@=""
"MUIVerb"="Windows Firewall"
"icon"="%SystemRoot%\\system32\\FirewallControlPanel.dll,0"
"subcommands"=""

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall]

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Add Blocking Rule (Outgoing)]
@=""
MUIVerb"="Add Blocking Rule (Outgoing)"
"Icon"="%SystemRoot%\\system32\\FirewallControlPanel.dll,1"

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Add Blocking Rule (Outgoing)\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Executionpolicy ByPass -WindowStyle Hidden -NoLogo -Command \"start powershell -Verb runas -ArgumentList \\\"-NoLogo -WindowStyle Hidden -command `\\\"New-NetFirewallRule -DisplayName ([System.IO.Path]::GetFilenameWithoutExtension('%1')) -Name '%1' -Enabled True -Direction Outbound -Action Block -Program '%1'`\\\"\\\"\""

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Delete Rule (Outgoing)]
@=""
MUIVerb"="Unblock Rule (Outgoing)"
"Icon"="%SystemRoot%\\system32\\FirewallControlPanel.dll,2"

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Delete Rule (Outgoing)\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Executionpolicy Bypass -WindowStyle Hidden -NoLogo -Command \"Start-Process powershell -Verb RunAs -ArgumentList \\\"-NoLogo -WindowStyle Hidden -Command `\"& {netsh advfirewall firewall delete rule name='\"'([System.IO.Path]::GetFileNameWithoutExtension('%1'))'\"' dir=out}'%1'`\\\"\\\"\""

I would appreciate any help or guidance on this issue. Thank you for your attention and interest in advance.

答案1

得分: 1

  • netsh advfirewall firewall delete rule调用中,只使用name=...将删除所有具有该名称的规则。

  • 要限制删除仅针对具有特定可执行文件的名称的规则,必须添加program=...参数。

根据下面关于PowerShell CLI语法的提示,在你的.reg文件中尝试以下操作:

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Delete Rule (Outgoing)\command]
@="powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -NoProfile -Command Start-Process -Verb RunAs powershell.exe '-NoExit -ExecutionPolicy Bypass -NoProfile -Command netsh advfirewall firewall delete rule name=$([IO.Path]::GetFileNameWithoutExtension(\"%1\")) program=\"%1\" dir=out'"

重要提示

  • 与你的问题一样,上述代码使用[System.IO.Path]::GetFileNameWithoutExtension()来获取输入文件的名称,不包括文件扩展名,例如,对于C:\Users\jdoe\some.exe,它将得到some,如果要保留扩展名,请改用[System.IO.Path]::GetFileName()

  • 为了帮助排除故障,我已从Start-Process调用中删除了-WindowStyle Hidden,并在嵌套的powershell.exe调用中添加了-NoExit

  • 这将以可见方式打开提升的会话,并保持打开状态,以便您可以检查发生的情况。

  • 在会话中运行[Environment]::CommandLine将显示嵌套的提升powershell.exe进程看到的确切进程命令行,例如,在文件C:\User\jdoe\some.exe上调用快捷菜单命令后,您将看到以下内容:

    "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -ExecutionPolicy Bypass -NoProfile -Command netsh advfirewall firewall delete rule name=$([IO.Path]::GetFileNameWithoutExtension(\"C:\Users\jdoe\some.exe\")) program=\"C:\Users\jdoe\some.exe\" dir=out
    
  • 以上代码将转化为以下netsh调用(注意没有"..."引号,因为当PowerShell - 出于必要性 - 在后台重建进程命令行时,它采用按需的双引号括号:仅当参数包含空格时,它才被整体包含在"..."中):

    netsh advfirewall firewall delete rule name=some program=C:\Users\jdoe\some.exe dir=out
    

关于PowerShell CLI 和必要的转义的一般提示:

  • 在通过-Command (-c)参数传递给PowerShell CLI的代码中,没有必要使用"& { ... }"来调用 - 直接使用"..."即可。

    • 较旧版本的CLI文档错误地建议需要使用"& { ... }",但此后已经更正。

    • 在没有shell调用的情况下,例如在你的情况下,甚至不需要"..."括号,这就是为什么在下面的示例中省略了它的原因。

      • 当省略"..."括号时,存在一个基本上是假设性的问题,即关于_空格规范化_,只有当需要_保留_ _多个_相邻空格字符的_嵌入字符串_才需要_按原样_传递。
  • 在使用-Command以抑制启动横幅的CLI调用中,没有必要使用-NoLogo-Command本身就会执行此操作(仅当同时指定-NoExit时才需要在使用-File时才需要)。

    • 然而,通常值得添加-NoProfile开关参数,它抑制加载任何配置文件,这些配置文件通常仅在_交互_会话中有用;不加载它们既提高了性能,也使执行环境更加可预测。
  • 在你的情况中,正确地进行转义和引用是非常困难的,因为需要处理多个解释层:

    • .reg文件格式中必须使用\来转义"字符以及字面上的\本身。

    • 由于需要通过Start-Process -Verb Runas进行_嵌套_调用以启动提升的PowerShell会话,所以Windows PowerShell CLI由powershell.exe执行_两层_解释。

      • 每个PowerShell CLI调用本身都有_两层_解释:
        • 未引用_的"字符在_命令行处理_期间被_移除 - 除非它们被转义为\"
        • 结果然后被解释为PowerShell代码。
英文:

<!-- language-all: sh -->

  • Using just name=... in a netsh advfirewall firewall delete rule call deletes all rules by that name.

  • To limit deletion to those rules by that name that target a specific executable, you must add a program=... argument.

Using the tips regarding PowerShell's CLI syntax below, try the following in your .reg file:

[HKEY_CLASSES_ROOT\*\shell\Windows Firewall\shell\Delete Rule (Outgoing)\command]
@=&quot;powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -NoProfile -Command Start-Process -Verb RunAs powershell.exe &#39;-NoExit -ExecutionPolicy Bypass -NoProfile -Command netsh advfirewall firewall delete rule name=$([IO.Path]::GetFileNameWithoutExtension(\\\\\\\&quot;%1\\\\\\\&quot;)) program=\\\\\\\&quot;%1\\\\\\\&quot; dir=out&#39;&quot;

Important:

  • As in your question, the above uses [System.IO.Path]::GetFileNameWithoutExtension() to get the input file's name without the filename extension, e.g., some for C:\Users\jdoe\some.exe; to keep the extension, use [System.IO.Path]::GetFileName() instead.

  • To assist in troubleshooting, I have removed -WindowStyle Hidden from the Start-Process call and have added -NoExit to the nested powershell.exe call.

  • This will open the elevated session visibly and keep it open, so that you can inspect what happens.

  • Running [Environment]::CommandLine in the session will show you the exact process command line that the nested, elevated powershell.exe process saw; e.g., you'll see the following after invoking the shortcut-menu command on file C:\User\jdoe\some.exe:

    &quot;C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe&quot; -NoExit -ExecutionPolicy Bypass -NoProfile -Command netsh advfirewall firewall delete rule name=$([IO.Path]::GetFileNameWithoutExtension(\&quot;C:\Users\jdoe\some.exe\&quot;)) program=\&quot;C:\Users\jdoe\some.exe\&quot; dir=out
    
  • The above translates to the following netsh call (note the absence of &quot;...&quot; quoting, because, when PowerShell - of necessity - rebuilds the process command line behind the scenes, it employs on-demand double-quoting: only if the argument contains spaces does it get enclosed in &quot;...&quot; - invariably as a whole):

    netsh advfirewall firewall delete rule name=some program=C:\Users\jdoe\some.exe dir=out
    

General tips regarding the PowerShell CLI and the necessary escaping:

  • There's no reason to use &quot;&amp; { ... }&quot; in order to invoke code passed to PowerShell's CLI via the -Command (-c) parameter - just use &quot;...&quot; directly.

    • Older versions of the CLI documentation erroneously suggested that &amp; { ... } is required, but this has since been corrected.

    • In no-shell invocations, such as in your case, even the &quot;...&quot; enclosure isn't necessary, which is why it was omitted below for simplicity.

      • There's a largely hypothetical concern when omitting the &quot;...&quot; enclosure with respect to whitespace normalization, which would only apply if embedded strings with multiple adjacent whitespace characters had to be passed as-is.
  • There is no reason to use -NoLogo in CLI calls that use -Command in order to suppress the startup banner; -Command alone does that (it also isn't necessary when using -File, unless -NoExit is also specified).

    • However, it is generally worth adding the -NoProfile switch parameter, which suppresses loading of any profile files, which are typically only useful in interactive sessions; not loading them both improves performance and makes for a more predictable execution environment.
  • Getting the escaping and quoting right in your case is exceptionally difficult, given that there are multiple layers of interpretation to deal with:

    • The .reg file format in which \ must be used to escape &quot; chars. as well as verbatim \ itself.

    • Two layers of interpretation by powershell.exe, the Windows PowerShell CLI, due to requiring a nested call via Start-Process -Verb Runas in order to launch an elevated PowerShell session.

      • Each PowerShell CLI call itself has two layers of interpretation:
        • Unquoted &quot; chars. are removed during command-line processing - unless they're escaped as \&quot;.
        • The result is then interpreted as PowerShell code.

huangapple
  • 本文由 发表于 2023年7月3日 21:50:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76605390.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定