IE没了 Powershell curl/iwr需要IE引擎?解救过程

thumbnail

封面图: Inori Aizawa by Winnetou-AD

给字多不看的:给$PROFILE文件加上一行:

1
$PSDefaultParameterValues["Invoke-WebRequest:UseBasicParsing"]=[System.Management.Automation.SwitchParameter]::Present

都怪IE!

Invoke-WebRequest 和 Internet Explorer

忘了是哪个大概是最近的某个版本微软把IE彻底从Win10移除了,结果这么个古董级的东西没了还带来一堆副作用(我Steam url图标没了, Microsoft wcnm)。

Windows Powershell 的 Invoke-WebRequest

Invoke-WebRequest 是 Powershell的一个cmdlet,默认它有三个别名:iwrcurlwget。把它当wget用的话,IE没了也无所谓,毕竟输出是写到文件的,但是把它当curl的时候就麻烦了。

1
2
3
iwr github.com
iwr : 无法分析响应内容,因为 Internet Explorer 引擎不可用,或者 Internet Explorer 的
首次启动配置不完整。请指定 UseBasicParsing 参数,然后再试一次。

iwr的DOM渲染引擎用的是IE的,确实很有年代感。指定 -UseBasicParsing可以禁用DOM分析.

1
2
3
4
iwr github.com -UseBasicParsing
StatusCode : 200
StatusDescription : OK
...

失败尝试: 为 Invoke-WebRequest -UseBasicParsing 指定别名

每次都加上这个参数未免太繁琐,有这时间还不如开个WSL用curl。所以,要指定一个默认使用此参数的别名。

直接Set会失败

如果直接Set-Alias:

1
2
3
4
5
set-alias iwr 'Invoke-WebRequest -UseBasicParsing'
set-alias : 别名不可写入,因为别名 iwr 为只读别名或常量,无法写入。
#加个 -Force
set-alias iwr 'Invoke-WebRequest -UseBasicParsing' -Force
set-alias : 无法从别名“iwr”中删除 AllScope 选项。

所以其实得先删掉这些别名

1
2
3
Del alias:iwr  -Force
Del alias:curl -Force
Del alias:wget -Force

Set成功了也不行

以为这样再set就好了?pwsh就是和人不一样:

1
2
3
4
set-alias iwr 'Invoke-WebRequest -UseBasicParsing'
iwr github.com
iwr : 无法将“Invoke-WebRequest -UseBasicParsing”项识别为 cmdlet、函数、脚本文件
或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。

在许多Linux的shell上这是可行的,例如你可以把rm 设为 rm -f 的别名, 因为这些shell是基于文本的,所以只要最终能拼出一个合法的字符串即可,但是powershell是基于对象的。这表示,例如Invoke-WebRequest是一个对象,而-UseBasicParsing是它的一个属性,因此不能通过拼凑文本来实现。

解决方案:更改cmdlet的默认值

创建SwitchParameter实例

我们需要默认启用UseBasicParsing这个参数,Powershell 提供了 $PSDefaultParameterValues 变量来让我们指定cmdlet的默认值,这是一个哈希表,格式为:

1
2
3
4
5
6
#创建新表
$PSDefaultParameterValues=@{"CmdletName:ParameterName"="DefaultValue"}
#创建新表,其中值可以是脚本块(返回对象)
$PSDefaultParameterValues=@{ "CmdletName:ParameterName"={{ScriptBlock}} }
#向表中添加值,这样不会覆盖已有的值
$PSDefaultParameterValues["Disabled"]=$True | $False

UseBasicParsing的类型是System.Management.Automation.SwitchParameter,它的属性IsPresent确定它是否打开。

首先new一个SwitchParameter,或者你也可以使用静态属性[System.Management.Automation.SwitchParameter]::Present

1
2
3
4
5
6
7
8
9
New-Object -TypeName System.Management.Automation.SwitchParameter -ArgumentList true
IsPresent
---------
True
#你也可以这样创建一个实例,调用它的静态属性
❯ [System.Management.Automation.SwitchParameter]::Present
IsPresent
---------
True

添加到配置文件

$PSDefaultParameterValues如所有变量一样,只在当前会话启用,要在每次开启powershell时都配置好,需要配置PROFILE文件。一般$PROFILE变量中存储的值就足够了,如果你有特殊需求,可以查看它的几个属性:

说明 名称
当前用户、当前主机 $PROFILE
当前用户、当前主机 $PROFILE.CurrentUserCurrentHost
当前用户,所有主机 $PROFILE.CurrentUserAllHosts
所有用户,当前主机 $PROFILE.AllUsersCurrentHost
所有用户、所有主机 $PROFILE.AllUsersAllHosts

所以,我们为$PROFILE指向的文件添加如下内容:

1
2
#你的$PROFILE所指向的文件
$PSDefaultParameterValues["Invoke-WebRequest:UseBasicParsing"]=[System.Management.Automation.SwitchParameter]::Present

现在,打开新的powershell窗口,大概效果:

1
2
3
4
5
6
7
8
9
10
11
加载个人及系统配置文件用了 563 毫秒。
$PSDefaultParameterValues
Name Value
---- -----
Invoke-WebRequest:UseBasicP... True
iwr github.com
StatusCode : 200
StatusDescription : OK
Content :
<!DOCTYPE html>
...

现在,Invoke-WebRequest将默认调用BasicParsing,我们不需要Internet Explorer !!!


参考文章

Permalink: http://blog.artiga.top/2021/pwsh-iwr-without-ie/

本文采用CC BY-NC-SA 4.0许可

Comments