2022年12月24日星期六

Win11卸载小组件的方法

Win11卸载小组件的方法

隐藏了小组件图标,没法解决所有问题,例如资源占用。小组件在后台还会持续占用资源,如果你的确完全用不上它,那可以把它卸载掉。

卸载 Win11 小组件,我们需要用到 CMD。使用管理员权限打开 Windows Terminal 终端的“命令提示符”,或者使用管理员权限运行 CMD,输入以下命令。

winget uninstall MicrosoftWindows.Client.WebExperience_cw5n1h2txyewy

按下回车键,稍等片刻

是否同意所有源协议条款?
[Y] 是  [N] 否: y

输入 Y  ,Win11 小组件就会被卸载掉了。

如果你想要重新安装 Win11 小组件,则可以执行以下命令。

winget install 9MSSGKG348SP

2022年12月18日星期日

在Windows下使用sshfs-win挂载sftp协议远程目录为本地磁盘

 

sshfs-win原理介绍

Windows下的sshfs-win与Linux下的sshfs原理基本一致,即它们都是建立在用户空间文件系统的基础上的应用。

sshfs将SFTP协议转换为FUSE的接口,FUSE再将这一接口以文件系统的方式暴露给内核;而sshfs-win则将SFTP协议转换为WinFSP(Windows文件系统代理)提供的接口,WinFSP所做的事情大致可以列举为以下三件:

注册一个设备驱动,让Windows能够挂载它 实现NT内核下CreateFile、ReadFile、WriteFile等API,管理读写队列 调用挂载到WinFSP上应用程序对应的FUSE接口 Windows的内核扩展与驱动程序非常复杂,因此为Windows开发内核态文件系统需要比在Linux下开发内核态文件系统更多的精力,而WinFSP作为FUSE接口到Windows文件系统的桥梁(这就是名字里代理的由来),能以更加全面与完整的API,以及对FUSE良好的兼容性,降低文件系统开发的难度。

接下来我们开始讲解如何安装与使用依赖WinFSP的sshfs-win。

sshfs-win安装与使用

上文提到,sshfs-win依赖WinFSP, 因此我们要首先安装WinFSP:https://github.com/billziss-gh/winfsp WinFSP安装结束后,我们再安装sshfs-win:https://github.com/billziss-gh/sshfs-win

两者都安装完毕后,我们在Windows的文件资源管理器中点击『映射网络驱动器』: 在弹出的对话框中,我们选定需要赋予的盘符,然后在文件夹中输入如下内容:

\\sshfs\用户名@IP地址!端口号

需要注意的是这里端口号不是我们通常使用的:,而是!,点击完成后,输入用户名对应的密码即可连接成功。

一些需要注意的细节

尽管sshfs-win的操作较为简单,但如果你想做更多操作两个需要注意的细节。

1. 如何挂载子目录

默认情况下,我们在输入第二节提到的连接串后,会将用户的家目录映射到Windows中,如果我们只是为了管理网站目录、做做备份或者是作为NAS使用,可能需要挂载其他子目录,但这时我们可能会发现,使用如下的连接串会导致连接时出现『位置不可用』的报错:

\\sshfs\用户名@IP地址!端口号\home

这是因为连接串中的路径是以用户家目录为参考的相对路径,即如果我们需要映射/home目录,则需要使用如下连接串

\\sshfs\用户名@IP地址!端口号\..\..\home

其中…\的数量需要根据实际情况决定,这样就能成功映射到我们所需的目录

这样的方式很容易造成误解,也让连接串变得复杂,因此sshfs-win支持另一种更为简明的连接串语法:

\\sshfs.r\用户名@IP地址!端口号\home

这里的r指的是root,即默认从根目录挂载而非家目录,这样就无需使用丑陋的…\回到根目录,我们可以直接从根目录开始,输入绝对路径来挂载我们所需的文件夹。

其实除了sshfs.r以外,还有其他的一些连接串规则能帮助sshfs-win变得更加方便,具体可以参考:https://github.com/winfsp/sshfs-win

2. 如何取消挂载

在已挂载的盘符上右键选择断开连接即可取消挂载。

在使用sshfs-win的时候,可能会出现无法卸载盘符的情况,无论通过文件资源管理器右键断开连接,还是通过cmd执行net use 盘符: /delete操作,均会在提示卸载成功后发现盘符依旧存在。 这可能是由于和其他应用程序的冲突引起。冲突可能不便解决,但我们可以利用上文描述过的原理,即WinFSP为sshfs提供支持,从WinFSP的角度下手解决这个问题。

我们打开命令提示符(或者PowerShell,取决于你的喜好),定位目录到WinFSP的安装目录,默认应该是C:\Program Files (x86)\WinFsp\bin\,然后执行如下命令:

.\launchctl-x64.exe list

这时它会列出正在运行的挂载任务,

这里可以看到,某条挂载任务的语法存在错误,这可能是导致它无法正常取消挂载的原因,这时候我们可以执行如下命令来取消挂载:

.\launchctl-x64.exe stop sshfs root@xxx...

命令执行成功后,我们打开文件资源管理器就会发现之前无法取消挂载的盘符已经成功消失。

其他的替代品

尽管sshfs-win简单直接,但如果读者需要更多功能(如图形界面、缓存等),就需要其他的替代品来实现同样的功能。这里推荐几款替代品:

rclone:一款号称『挂载任何存储服务』的跨平台开源软件,支持范围之广从Amazon S3到Google Drive,或者是更为传统的FTP、SFTP,甚至内存!rclone提供了超过30种存储目标,并提供充分的自定义选项支持,可以实现缓存、权限等复杂配置。美中不足的是rclone并未提供图形界面,而在Windows下编写服务配置文件较为复杂,因此该软件适合有较多自定义需求的用户使用。 raidrive: raidrive相对比rclone最大的特色就是提供了图形界面支持,可以更方便地管理挂载目录,但这是一款商业软件,免费套餐只支持较少的挂载目标,也无法支持缓存等高级功能。 类似的软件还有很多,如SFTP Drive等,读者可以根据自己的需求挑选适合自己的软件。

需要注意的是,这些软件的原理大多类似,其中还有不少是基于WinFSP的二次开发,因此在性能和稳定性方面,它们是相差不多的。

win11 恢复经典上下文菜单

如果要从 Windows 11 上下文菜单中删除“显示更多选项”条目并还原 Windows 11 中的经典右键单击菜单,可以使用以下方式实现。

使用 cmd  命令提示符  恢复 Windows 11 上的经典上下文菜单

1. 以管理员权限
打开 Cmd 2.复制并粘贴以下代码,然后按回车键

reg.exe add “HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32” /f  && taskkill /f /im explorer.exe && explorer.exe

使用 Cmd 恢复 Windows 11 上的默认上下文菜单

1. 以管理员权限
打开 Cmd 2.复制并粘贴以下代码,然后按回车键

reg.exe delete “HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}” /f  && taskkill /f /im explorer.exe && explorer.exe

2022年12月17日星期六

在Windows下使用 RClone 挂载Webdav、SFTP、SMB协议远程目录为本地磁盘

软件准备:
Windows系统需要先安装WinFsp用以支持类FUSE文件系统
下载WinFsp官网:https://github.com/winfsp/winfsp/releasess
新建一个文件夹,路径建议全英文,比如D:\rclone
解压文件,将rclone.exe放到文件夹中

配置RClone

在含有rclone.exe文件的目录中空白处右键,选择在终端中打开/在此处打开命令提示符

输入.\rclone config   按以下提示操作,添加自己的webdav服务器,或添加其他网盘,并给他们起个名字,比如webdav。

首次设置时配置文件生成在:C:\用户\你的用户名\.config\rclone\rclone.conf

推荐自建空白rclone.conf文件与rclone.exe放置在同一目录

Rclone webdav方式挂载Linux目录

e)Edit existing remote #编辑已有的远程挂载点
n) New remote #新挂载
d) Delete remote #删除挂载
r) Rename remote #重命名挂载
c) Copy remote #为已有挂载建立一个副本
s) Set configuration password #设置配置密码
q) Quit config #退出配置
e/n/d/r/c/s/q> #首先输入 n 新建一个配置

name > webdav                                   #给你你的挂载点取个名字

然后又是噼里啪啦一堆选项

Choose a number from below, or type in your own value
1 / A stackable unification remote, which can appear to merge the contents of several remotes \ "union"
2 / Alias for a existing remote \ "alias"
3 / Amazon Drive \ "amazon cloud drive"
............略............
Storage>webdav #此处挂载的是webdav

然后

url > http://host:8080                       #输入服务商给的webdav地址

然后输入网站所使用的程序,这里选 other

然后user > 输入用户名

y) Yes type in my own password
g) Generate random password
n) No leave this optional password blank
y/g/n> y        #选择输入密码

设置完密码以后,接着按提示输入一个口令用来代替输入繁琐的密码,默认为空

Bearer token instead of user/pass (eg a Macaroon)
Enter a string value. Press Enter for the default ("").
bearer_token>

接着程序会列出刚刚进行的的配置信息,没有问题的话y确认就好啦

重新回到主界面,在菜单顶上会实现列出已有的挂载点

输入q 退出配置

首次设置配置文件在:C:\用户\你的用户名\.config\rclone\rclone.conf 

命令挂载 webdav 到本地

rclone mount  本地磁盘: o: --cache-dir D:\Temp --allow-other --vfs-cache-mode writes --allow-non-empty

备注: --cache-dir D:\Temp  设置用于在上传之前暂存的地方

有些服务商不支持读取空间大小,会导致挂载显示为0可用或者7.99EB,为正常现象

5.1 创建命令启动脚本

将配置文件C:\用户\你的用户名\.config\rclone\rclone.conf 剪切到在D:\rckone目录

.BAT脚本方式:

在D:\rckone中,新建一个文本文档,将命令

.\rclone.exe mount webdav: o: --cache-dir B:\Temp --allow-other --vfs-cache-mode writes --allow-non-empty

复制到文档中,并将文档另存为rclone.bat,双击rclone.bat即可挂载

VBS脚本方式:

创建挂载脚本

新建文本文档,输入内容:

dim objShell 
set objShell=wscript.createObject("WScript.Shell") 
iReturnCode=objShell.Run(".\rclone.exe mount webdav: o:  --cache-dir %SystemRoot%\TEMP  --allow-other --vfs-cache-mode writes  --vfs-cache-max-age 60s  --allow-non-empty",0,TRUE)

另存为 mount-Webdav.vbs ,与rclone.exe,及rclone.conf 放在同一目录

创建卸载脚本
新建文本文档,输入内容:

set ws=createobject("wscript.shell")
   ws.run "taskkill /f /im rclone.exe",hide 

另存为 End-uount.vbs ,与rclone.exe,及rclone.conf 放在同一目录

挂载远程目录
双击mount-Webdav.vbs执行挂载操作,并刷新资源管理器
卸载远程目录
双击End-uount.vbs执行卸载操作,并刷新资源管理器

Rclone SSH/SFTP方式挂载Linux目录

生成ssh公钥密钥

ssh-keygen -q -t rsa -b 4096 -C "rclone key" -N "" -f ~/.ssh/rclone
cd ~/.ssh/
cat rclone* > rclone-merged                 # <- 须做项,否则会连接失败
在服务器server中添加pub key到~/.ssh/authorized_keys

ssh-copy-id -i ~/.ssh/rclone.pub root@example.com                # <- example.com为访问地址,可以为IP或域名

添加连接配置

F:\rclone\rclone>rclone config
Current remotes:

Name                 Type
====                 ====
smb                  smb
webdav               webdav

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n         # <- 输入 n 创建新连接

Enter name for new remote.
name> sftp                 # <- 输入配置名即  sftp 

Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
 1 / 1Fichier
   \ (fichier)
 2 / Akamai NetStorage
   \ (netstorage)
 3 / Alias for an existing remote
   \ (alias)
 4 / Amazon Drive
   \ (amazon cloud drive)
 5 / Amazon S3 Compliant Storage Providers including AWS, Alibaba, Ceph, China Mobile, Cloudflare, ArvanCloud, Digital Ocean, Dreamhost, Huawei OBS, IBM COS, IDrive e2, IONOS Cloud, Lyve Cloud, Minio, Netease, RackCorp, Scaleway, SeaweedFS, StackPath, Storj, Tencent COS, Qiniu and Wasabi
   \ (s3)
 6 / Backblaze B2
   \ (b2)
 7 / Better checksums for other remotes
   \ (hasher)
 8 / Box
   \ (box)
 9 / Cache a remote
   \ (cache)
10 / Citrix Sharefile
   \ (sharefile)
11 / Combine several remotes into one
   \ (combine)
12 / Compress a remote
   \ (compress)
13 / Dropbox
   \ (dropbox)
14 / Encrypt/Decrypt a remote
   \ (crypt)
15 / Enterprise File Fabric
   \ (filefabric)
16 / FTP
   \ (ftp)
17 / Google Cloud Storage (this is not Google Drive)
   \ (google cloud storage)
18 / Google Drive
   \ (drive)
19 / Google Photos
   \ (google photos)
20 / HTTP
   \ (http)
21 / Hadoop distributed file system
   \ (hdfs)
22 / HiDrive
   \ (hidrive)
23 / In memory object storage system.
   \ (memory)
24 / Internet Archive
   \ (internetarchive)
25 / Jottacloud
   \ (jottacloud)
26 / Koofr, Digi Storage and other Koofr-compatible storage providers
   \ (koofr)
27 / Local Disk
   \ (local)
28 / Mail.ru Cloud
   \ (mailru)
29 / Mega
   \ (mega)
30 / Microsoft Azure Blob Storage
   \ (azureblob)
31 / Microsoft OneDrive
   \ (onedrive)
32 / OpenDrive
   \ (opendrive)
33 / OpenStack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
   \ (swift)
34 / Oracle Cloud Infrastructure Object Storage
   \ (oracleobjectstorage)
35 / Pcloud
   \ (pcloud)
36 / Put.io
   \ (putio)
37 / QingCloud Object Storage
   \ (qingstor)
38 / SMB / CIFS
   \ (smb)
39 / SSH/SFTP
   \ (sftp)
40 / Sia Decentralized Cloud
   \ (sia)
41 / Storj Decentralized Cloud Storage
   \ (storj)
42 / Sugarsync
   \ (sugarsync)
43 / Transparently chunk/split large files
   \ (chunker)
44 / Union merges the contents of several upstream fs
   \ (union)
45 / Uptobox
   \ (uptobox)
46 / WebDAV
   \ (webdav)
47 / Yandex Disk
   \ (yandex)
48 / Zoho
   \ (zoho)
49 / premiumize.me
   \ (premiumizeme)
50 / seafile
   \ (seafile)
Storage> sftp                 # <- 输入配置类型即  sftp 

Option host.
SSH host to connect to.
E.g. "example.com".
Enter a value.
host> example.com​ # <- 输入主机名即  example.com

Option user.
SSH username.
Enter a string value. Press Enter for the default (User).
user> root       ​ # <- 输入登录用户名即  root

Option port.
SSH port number.
Enter a signed integer. Press Enter for the default (22).
port> 11113       # <- 输入登录端口号即  root

Option pass.
SSH password, leave blank to use ssh-agent.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n> y            # <- 输入y选择密码登录
Enter the password:
password:          # <- 输入登录密码
Confirm the password:
password:         # <- 再次输入登录密码

Option key_pem.
Raw PEM-encoded private key.
If specified, will override key_file parameter.
Enter a value. Press Enter to leave empty.
key_pem>         # <- 按回车健选择默认

Option key_file.
Path to PEM-encoded private key file.
Leave blank or set key-use-agent to use ssh-agent.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a value. Press Enter to leave empty.
key_file>         # <- 按回车健选择默认

Option key_file_pass.
The passphrase to decrypt the PEM-encoded private key file.
Only PEM encrypted key files (old OpenSSH format) are supported. Encrypted keys
in the new OpenSSH format can't be used.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n>         # <- 按回车健选择默认

Option pubkey_file.
Optional path to public key file.
Set this if you have a signed certificate you want to use for authentication.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a value. Press Enter to leave empty.
pubkey_file>         # <- 按回车健选择默认

Option key_use_agent.
When set forces the usage of the ssh-agent.
When key-file is also set, the ".pub" file of the specified key-file is read and only the associated key is
requested from the ssh-agent. This allows to avoid `Too many authentication failures for *username*` errors
when the ssh-agent contains many keys.
Enter a boolean value (true or false). Press Enter for the default (false).
key_use_agent>         # <- 按回车健选择默认

Option use_insecure_cipher.
Enable the use of insecure ciphers and key exchange methods.
This enables the use of the following insecure ciphers and key exchange methods:
- aes128-cbc
- aes192-cbc
- aes256-cbc
- 3des-cbc
- diffie-hellman-group-exchange-sha256
- diffie-hellman-group-exchange-sha1
Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
Choose a number from below, or type in your own boolean value (true or false).
Press Enter for the default (false).
 1 / Use default Cipher list.
   \ (false)
 2 / Enables the use of the aes128-cbc cipher and diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1 key exchange.
   \ (true)
use_insecure_cipher>         # <- 按回车健选择默认

Option disable_hashcheck.
Disable the execution of SSH commands to determine if remote file hashing is available.
Leave blank or set to false to enable hashing (recommended), set to true to disable hashing.
Enter a boolean value (true or false). Press Enter for the default (false).
disable_hashcheck>         # <- 按回车健选择默认

Edit advanced config?
y) Yes
n) No (default)
y/n>         # <- 按回车健选择默认

Configuration complete.
Options:
- type: sftp
- host: nas.x0x.cn
- user: root
- port: 11113
- pass: *** ENCRYPTED ***
Keep this "sftps" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d>         # <- 按回车健选择默认

到此完已成连接设置添加

Current remotes:

Name                 Type
====                 ====
sftp                 sftp
smb                  smb
webdav               webdav

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q>
创建挂载脚本

新建文本文档,输入内容:

dim objShell 
set objShell=wscript.createObject("WScript.Shell") 
iReturnCode=objShell.Run(".\rclone.exe mount sftp:/mnt o: --cache-dir %SystemRoot%\TEMP --allow-other --vfs-cache-mode writes --vfs-cache-max-age 60s  --allow-non-empty",0,TRUE)

备注:sftp:/mnt 指定挂载根目录

另存为 mount-SFTP.vbs ,与rclone.exe,及rclone.conf 放在同一目录

创建卸载脚本
新建文本文档,输入内容:

set ws=createobject("wscript.shell")
   ws.run "taskkill /f /im rclone.exe",hide 

另存为 End-uount.vbs ,与rclone.exe,及rclone.conf 放在同一目录

挂载远程目录
双击mount-SFTP.vbs执行挂载操作,并刷新资源管理器
卸载远程目录
双击End-uount.vbs执行卸载操作,并刷新资源管理器

Rclone smb方式挂载远程目录


F:\rclone\rclone>.\rclone config
Current remotes:

Name                 Type
====                 ====
sftp                 sftp
webdav               webdav

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n

Enter name for new remote.
name> smb

Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
 1 / 1Fichier
   \ (fichier)
 2 / Akamai NetStorage
   \ (netstorage)
 3 / Alias for an existing remote
   \ (alias)
 4 / Amazon Drive
   \ (amazon cloud drive)
 5 / Amazon S3 Compliant Storage Providers including AWS, Alibaba, Ceph, China Mobile, Cloudflare, ArvanCloud, Digital Ocean, Dreamhost, Huawei OBS, IBM COS, IDrive e2, IONOS Cloud, Lyve Cloud, Minio, Netease, RackCorp, Scaleway, SeaweedFS, StackPath, Storj, Tencent COS, Qiniu and Wasabi
   \ (s3)
 6 / Backblaze B2
   \ (b2)
 7 / Better checksums for other remotes
   \ (hasher)
 8 / Box
   \ (box)
 9 / Cache a remote
   \ (cache)
10 / Citrix Sharefile
   \ (sharefile)
11 / Combine several remotes into one
   \ (combine)
12 / Compress a remote
   \ (compress)
13 / Dropbox
   \ (dropbox)
14 / Encrypt/Decrypt a remote
   \ (crypt)
15 / Enterprise File Fabric
   \ (filefabric)
16 / FTP
   \ (ftp)
17 / Google Cloud Storage (this is not Google Drive)
   \ (google cloud storage)
18 / Google Drive
   \ (drive)
19 / Google Photos
   \ (google photos)
20 / HTTP
   \ (http)
21 / Hadoop distributed file system
   \ (hdfs)
22 / HiDrive
   \ (hidrive)
23 / In memory object storage system.
   \ (memory)
24 / Internet Archive
   \ (internetarchive)
25 / Jottacloud
   \ (jottacloud)
26 / Koofr, Digi Storage and other Koofr-compatible storage providers
   \ (koofr)
27 / Local Disk
   \ (local)
28 / Mail.ru Cloud
   \ (mailru)
29 / Mega
   \ (mega)
30 / Microsoft Azure Blob Storage
   \ (azureblob)
31 / Microsoft OneDrive
   \ (onedrive)
32 / OpenDrive
   \ (opendrive)
33 / OpenStack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
   \ (swift)
34 / Oracle Cloud Infrastructure Object Storage
   \ (oracleobjectstorage)
35 / Pcloud
   \ (pcloud)
36 / Put.io
   \ (putio)
37 / QingCloud Object Storage
   \ (qingstor)
38 / SMB / CIFS
   \ (smb)
39 / SSH/SFTP
   \ (sftp)
40 / Sia Decentralized Cloud
   \ (sia)
41 / Storj Decentralized Cloud Storage
   \ (storj)
42 / Sugarsync
   \ (sugarsync)
43 / Transparently chunk/split large files
   \ (chunker)
44 / Union merges the contents of several upstream fs
   \ (union)
45 / Uptobox
   \ (uptobox)
46 / WebDAV
   \ (webdav)
47 / Yandex Disk
   \ (yandex)
48 / Zoho
   \ (zoho)
49 / premiumize.me
   \ (premiumizeme)
50 / seafile
   \ (seafile)
Storage> smb

Option host.
SMB server hostname to connect to.
E.g. "example.com".
Enter a value.
host> example.com

Option user.
SMB username.
Enter a string value. Press Enter for the default (DESKTOP-A0B2SBH\User).
user> User

Option port.
SMB port number.
Enter a signed integer. Press Enter for the default (445).
port> 5445

Option pass.
SMB password.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n> y
Enter the password:
password:
Confirm the password:
password:

Option domain.
Domain name for NTLM authentication.
Enter a string value. Press Enter for the default (WORKGROUP).
domain>

Edit advanced config?
y) Yes
n) No (default)
y/n>

Configuration complete.
Options:
- type: smb
- host: nas.x0x.cn
- user: User
- port: 5445
- pass: *** ENCRYPTED ***
Keep this "smb1" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y

Current remotes:

Name                 Type
====                 ====
sftp                 sftp
smb                  smb
webdav               webdav

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q>
F:\rclone\rclone>

创建挂载脚本

新建文本文档,输入内容:

dim objShell 
set objShell=wscript.createObject("WScript.Shell") 
iReturnCode=objShell.Run(".\rclone.exe mount smb: o:  --cache-dir %SystemRoot%\TEMP  --allow-other --vfs-cache-mode writes  --vfs-cache-max-age 60s  --allow-non-empty",0,TRUE)

另存为 mount-Smb.vbs ,与rclone.exe,及rclone.conf 放在同一目录

创建卸载脚本
新建文本文档,输入内容:

set ws=createobject("wscript.shell")
   ws.run "taskkill /f /im rclone.exe",hide 

另存为 End-uount.vbs ,与rclone.exe,及rclone.conf 放在同一目录

挂载远程目录
双击mount-Smb.vbs执行挂载操作,并刷新资源管理器
卸载远程目录
双击End-uount.vbs执行卸载操作,并刷新资源管理器
Rclone SSH/SFTP方式挂载Linux目录

生成ssh公钥密钥

ssh-keygen -q -t rsa -b 4096 -C "rclone key" -N "" -f ~/.ssh/rclone
cd ~/.ssh/
cat rclone* > rclone-merged                 # <- 须做项,否则会连接失败
在服务器server中添加pub key到~/.ssh/authorized_keys

ssh-copy-id -i ~/.ssh/rclone.pub root@example.com                # <- example.com为访问地址,可以为IP或域名
添加连接配置

F:\rclone\rclone>rclone config
Current remotes:

Name                 Type
====                 ====
smb                  smb
webdav               webdav

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n         # <- 输入 n 创建新连接

Enter name for new remote.
name> sftp                 # <- 输入配置名即  sftp 

Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
 1 / 1Fichier
   \ (fichier)
 2 / Akamai NetStorage
   \ (netstorage)
 3 / Alias for an existing remote
   \ (alias)
 4 / Amazon Drive
   \ (amazon cloud drive)
 5 / Amazon S3 Compliant Storage Providers including AWS, Alibaba, Ceph, China Mobile, Cloudflare, ArvanCloud, Digital Ocean, Dreamhost, Huawei OBS, IBM COS, IDrive e2, IONOS Cloud, Lyve Cloud, Minio, Netease, RackCorp, Scaleway, SeaweedFS, StackPath, Storj, Tencent COS, Qiniu and Wasabi
   \ (s3)
 6 / Backblaze B2
   \ (b2)
 7 / Better checksums for other remotes
   \ (hasher)
 8 / Box
   \ (box)
 9 / Cache a remote
   \ (cache)
10 / Citrix Sharefile
   \ (sharefile)
11 / Combine several remotes into one
   \ (combine)
12 / Compress a remote
   \ (compress)
13 / Dropbox
   \ (dropbox)
14 / Encrypt/Decrypt a remote
   \ (crypt)
15 / Enterprise File Fabric
   \ (filefabric)
16 / FTP
   \ (ftp)
17 / Google Cloud Storage (this is not Google Drive)
   \ (google cloud storage)
18 / Google Drive
   \ (drive)
19 / Google Photos
   \ (google photos)
20 / HTTP
   \ (http)
21 / Hadoop distributed file system
   \ (hdfs)
22 / HiDrive
   \ (hidrive)
23 / In memory object storage system.
   \ (memory)
24 / Internet Archive
   \ (internetarchive)
25 / Jottacloud
   \ (jottacloud)
26 / Koofr, Digi Storage and other Koofr-compatible storage providers
   \ (koofr)
27 / Local Disk
   \ (local)
28 / Mail.ru Cloud
   \ (mailru)
29 / Mega
   \ (mega)
30 / Microsoft Azure Blob Storage
   \ (azureblob)
31 / Microsoft OneDrive
   \ (onedrive)
32 / OpenDrive
   \ (opendrive)
33 / OpenStack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
   \ (swift)
34 / Oracle Cloud Infrastructure Object Storage
   \ (oracleobjectstorage)
35 / Pcloud
   \ (pcloud)
36 / Put.io
   \ (putio)
37 / QingCloud Object Storage
   \ (qingstor)
38 / SMB / CIFS
   \ (smb)
39 / SSH/SFTP
   \ (sftp)
40 / Sia Decentralized Cloud
   \ (sia)
41 / Storj Decentralized Cloud Storage
   \ (storj)
42 / Sugarsync
   \ (sugarsync)
43 / Transparently chunk/split large files
   \ (chunker)
44 / Union merges the contents of several upstream fs
   \ (union)
45 / Uptobox
   \ (uptobox)
46 / WebDAV
   \ (webdav)
47 / Yandex Disk
   \ (yandex)
48 / Zoho
   \ (zoho)
49 / premiumize.me
   \ (premiumizeme)
50 / seafile
   \ (seafile)
Storage> sftp                 # <- 输入配置类型即  sftp 

Option host.
SSH host to connect to.
E.g. "example.com".
Enter a value.
host> example.com​ # <- 输入主机名即  example.com

Option user.
SSH username.
Enter a string value. Press Enter for the default (DESKTOP-5B77GK9\User).
user> root       ​ # <- 输入登录用户名即  root

Option port.
SSH port number.
Enter a signed integer. Press Enter for the default (22).
port> 11113       # <- 输入登录端口号即  root

Option pass.
SSH password, leave blank to use ssh-agent.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n> y            # <- 输入y选择密码登录
Enter the password:
password:          # <- 输入登录密码
Confirm the password:
password:         # <- 再次输入登录密码

Option key_pem.
Raw PEM-encoded private key.
If specified, will override key_file parameter.
Enter a value. Press Enter to leave empty.
key_pem>         # <- 按回车健选择默认

Option key_file.
Path to PEM-encoded private key file.
Leave blank or set key-use-agent to use ssh-agent.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a value. Press Enter to leave empty.
key_file>         # <- 按回车健选择默认

Option key_file_pass.
The passphrase to decrypt the PEM-encoded private key file.
Only PEM encrypted key files (old OpenSSH format) are supported. Encrypted keys
in the new OpenSSH format can't be used.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n>         # <- 按回车健选择默认

Option pubkey_file.
Optional path to public key file.
Set this if you have a signed certificate you want to use for authentication.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a value. Press Enter to leave empty.
pubkey_file>         # <- 按回车健选择默认

Option key_use_agent.
When set forces the usage of the ssh-agent.
When key-file is also set, the ".pub" file of the specified key-file is read and only the associated key is
requested from the ssh-agent. This allows to avoid `Too many authentication failures for *username*` errors
when the ssh-agent contains many keys.
Enter a boolean value (true or false). Press Enter for the default (false).
key_use_agent>         # <- 按回车健选择默认

Option use_insecure_cipher.
Enable the use of insecure ciphers and key exchange methods.
This enables the use of the following insecure ciphers and key exchange methods:
- aes128-cbc
- aes192-cbc
- aes256-cbc
- 3des-cbc
- diffie-hellman-group-exchange-sha256
- diffie-hellman-group-exchange-sha1
Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
Choose a number from below, or type in your own boolean value (true or false).
Press Enter for the default (false).
 1 / Use default Cipher list.
   \ (false)
 2 / Enables the use of the aes128-cbc cipher and diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1 key exchange.
   \ (true)
use_insecure_cipher>         # <- 按回车健选择默认

Option disable_hashcheck.
Disable the execution of SSH commands to determine if remote file hashing is available.
Leave blank or set to false to enable hashing (recommended), set to true to disable hashing.
Enter a boolean value (true or false). Press Enter for the default (false).
disable_hashcheck>         # <- 按回车健选择默认

Edit advanced config?
y) Yes
n) No (default)
y/n>         # <- 按回车健选择默认

Configuration complete.
Options:
- type: sftp
- host: nas.x0x.cn
- user: root
- port: 11113
- pass: *** ENCRYPTED ***
Keep this "sftps" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d>         # <- 按回车健选择默认

到此完已成连接设置添加

Current remotes:

Name                 Type
====                 ====
sftp                 sftp
smb                  smb
webdav               webdav

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q>
创建挂载脚本

新建文本文档,输入内容:

dim objShell 
set objShell=wscript.createObject("WScript.Shell") 
iReturnCode=objShell.Run(".\rclone.exe mount sftp:/mnt o: --cache-dir %SystemRoot%\TEMP --allow-other --vfs-cache-mode writes --vfs-cache-max-age 60s  --allow-non-empty",0,TRUE)
备注:sftp:/mnt 指定挂载目录

另存为 mount-SFTP.vbs ,与rclone.exe,及rclone.conf 放在同一目录

创建卸载脚本
新建文本文档,输入内容:

set ws=createobject("wscript.shell")
   ws.run "taskkill /f /im rclone.exe",hide 
另存为 End-uount.vbs ,与rclone.exe,及rclone.conf 放在同一目录

挂载目录
双击mount-SFTP.vbs执行挂载操作,并刷新资源管理器
挂载目录
双击mount-SFTP.vbs执行挂载操作,并刷新资源管理器

2022年12月12日星期一

WIN11运行游戏出现ms-gamingoverlay弹框处理

WIN11运行游戏出现ms-gamingoverlay弹框处理

卸载xbox以后Win10/11运行程序/游戏出现ms-gamingoverlay弹框,一直提升很烦人,找到解决办法
第一步:
1、首先同样是进入系统“设置”。
2、然后进入左侧的“游戏”。
3、再进入右侧的“屏幕截图/摄像”。
4、接着在录制偏好设置中关闭“录制游戏过程”就可以了。
PS:第一步在百度上都是这样设置,但是有些win11电脑设置之后还是会出现弹框,再出现弹框就需要执行第二步操作!
第二步:
1、打开win+R,输入regedit进入注册表编辑器
2、查找AppCaptureEnabled选项
PS:选中计算机,点击编辑,选择查找,输入需要查找的值,进行查找!
3、将AppCaptureEnabled选项的值由原来的1改为0
综上所述两步执行完成,重启电脑后再进行游戏就不会出现提示弹框啦!

2022年12月11日星期日

获得本机的IPv6/v4地址,用于ddns

返回本机IP地址

ipv4

https://ipv4.ddnspod.com
https://api-ipv4.ip.sb/ip
https://myip.ipip.net
https://ddns.oray.com/checkip
https://speed.neu.edu.cn/getIP.php
https://ipv6.ddnspod.com
https://api-ipv6.ip.sb/ip
https://v6.myip.la/json
https://speed.neu6.edu.cn/getIP.php

配合wget 或curl 或者python的基础爬虫,就可以看到自己的公网ip地址,如:

wget http://ipv6.ddnspod.com -O ipv6cat ipv6

2022年12月4日星期日

Windows批量Ping脚本

测试IP连通性.bat (以下代码保存为.bat文件,保存编码格式ANSI)

for /%%in (ip.txt) do (ping %%-1 && echo %%i>>通.txt || echo %%>>不通.txt)

for /%in (ip.txt) do (ping %-1 && echo %>>通.txt || echo %>>不通.txt)

测试与bat文件同一目录的 ip.txt 文件中所有ip地址,

能ping通的ip地址另存到 通.txt文件内,不能ping通的ip地址另存到 不通.txt文件内

测试IP延时.bat (以下代码保存为.bat文件,保存编码格式ANSI)

for /%%in (ip.txt) do (ping %%-1 -500 | find "回复" >>结果.txt)

测试与bat文件在同一目录的 ip.txt 文件中所有ip地址,结果另存到 结果.txt 文件内

2022年12月2日星期五

Worker语法示例代码

Workers

https://dash.cloudflare.com/
构建无服务器应用程序并在全球范围内即时部署,从而获得卓越的性能、可靠性和规模性。

1+代访问代码块1

const hostname = "https://bk.abc.com"    //http或https,含端口
  function handleRequest(request) {
    let url = new URL(request.url);
    return fetch(new Request(hostname + url.pathname,request))
  }
addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
  })

2+转发http/https 请求-代码块2

addEventListener(
   "fetch",event => {
        let url=new URL(event.request.url);
        url.protocol="http";     //协议,http或https
        url.hostname="bk.abc.com";     //域名
        url.port="80";     //http或https服务的端口
        let request=new Request(url,event.request);
        event. respondWith(
            fetch(request)
        )
    }
)

3+转发http/https 请求-代码块3

var host = "http://bk.abc.com";
addEventListener("fetch", (event) => {
  event.respondWith(
    handleRequest(event.request).catch(
      (err) => new Response(err.stack, { status: 500 })
    )
  );
});
async function handleRequest(request) {
  const url = new URL(request.url);
  const newURL = new URL(host + url.pathname + url.search);
  const newRequest = new Request(newURL, request);
  return await fetch(newRequest);
}

4+301跳转

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})
async function fetchAndApply(request) {
    url = 'https://bk.abc.com' // 需要跳转到的地址
    return Response.redirect(url, 301)
}

4+全站转发访问

// 示例:访问cdnbk.abc.com,代理访问到 bk.abc.com
// 代理的网址.
const upstream = 'bk.abc.com'

// 上游网站的自定义路径名.
const upstream_path = '/'

// 为使用移动设备的用户检索的路径.
const upstream_mobile = 'bk.abc.com'

// 希望暂停服务的国家和地区.
const blocked_region = []

// 希望阻止使用您的服务的IP地址.
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

// 上游地址是否使用HTTPS协议.
const https = true

// 是否禁用缓存.
const disable_cache = false

const replace_dict = {
    '$upstream': '$custom_domain',
    'bk.abc.com':'cdnbk.abc.com'
//   添加子域.'bk2.abc.com':'cdnbk2.abc.com'
}

let data={}
addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {
    const region = request.headers.get('cf-ipcountry').toUpperCase();
    const ip_address = request.headers.get('cf-connecting-ip');
    const user_agent = request.headers.get('user-agent');

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;

    if (https == true) {
        url.protocol = 'https:';
    } else {
        url.protocol = 'http:';
    }

    if (await device_status(user_agent)) {
        var upstream_domain = upstream;
    } else {
        var upstream_domain = upstream_mobile;
    }

    url.host = upstream_domain;
    if (url.pathname == '/') {
        url.pathname = upstream_path;
    } else {
        url.pathname = upstream_path + url.pathname;
    }

    if (blocked_region.includes(region)) {
        response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
            status: 403
        });
    } else if (blocked_ip_address.includes(ip_address)) {
        response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
            status: 403
        });
    } else {
        let method = request.method;
        let request_headers = request.headers;
        let new_request_headers = new Headers(request_headers);

        new_request_headers.set('Host', upstream_domain);
        new_request_headers.set('Referer', url.protocol + '//' + upstream_domain);

        

        if(method == 'POST'){
            let origin_formData = await request.text()
            data = {
                method: method,
                headers: new_request_headers,
                body : origin_formData
            }
            console.log(data)
        }else if(method == 'GET'){
            data = {
                method: method,
                headers: new_request_headers
            }
        }
        let fuckKeys =  Object.fromEntries(new_request_headers)
        console.log(method)
        console.log(fuckKeys)
        let original_response = await fetch(url.href, data)

        connection_upgrade = new_request_headers.get("Upgrade");
        if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") {
            return original_response;
        }

        let original_response_clone = original_response.clone();
        let original_text = null;
        let response_headers = original_response.headers;
        let new_response_headers = new Headers(response_headers);
        let status = original_response.status;
        
        if (disable_cache) {
            new_response_headers.set('Cache-Control', 'no-store');
        }

        new_response_headers.set('access-control-allow-origin', '*');
        new_response_headers.set('access-control-allow-credentials', true);
        new_response_headers.delete('content-security-policy');
        new_response_headers.delete('content-security-policy-report-only');
        new_response_headers.delete('clear-site-data');
        
        if (new_response_headers.get("x-pjax-url")) {
            new_response_headers.set("x-pjax-url", response_headers.get("x-pjax-url").replace("//" + upstream_domain, "//" + url_hostname));
        }
        
        const content_type = new_response_headers.get('content-type');
        if (content_type != null && content_type.includes('text/html') && content_type.includes('UTF-8')) {
            original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
        } else {
            original_text = original_response_clone.body
        }
        
        response = new Response(original_text, {
            status,
            headers: new_response_headers
        })
    }
    
    return response;
}

async function replace_form_data(formData, upstream_domain, host_name) {
    let text = await response.text()

    var i, j;
    for (in replace_dict) {
        j = replace_dict[i]
        if (== '$upstream') {
            i = upstream_domain
        } else if (== '$custom_domain') {
            i = host_name
        }

        if (== '$upstream') {
            j = upstream_domain
        } else if (== '$custom_domain') {
            j = host_name
        }

        let re = new RegExp(i, 'g')
        text = text.replace(re, j);
    }
    return text;
}

async function replace_response_text(response, upstream_domain, host_name) {
    let text = await response.text()

    var i, j;
    for (in replace_dict) {
        j = replace_dict[i]
        if (== '$upstream') {
            i = upstream_domain
        } else if (== '$custom_domain') {
            i = host_name
        }

        if (== '$upstream') {
            j = upstream_domain
        } else if (== '$custom_domain') {
            j = host_name
        }

        let re = new RegExp(i, 'g')
        text = text.replace(re, j);
    }
    return text;
}


async function device_status(user_agent_info) {
    var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
    var flag = true;
    for (var v = 0; v < agents.length; v++) {
        if (user_agent_info.indexOf(agents[v]) > 0) {
            flag = false;
            break;
        }
    }
    return flag;
}

Workers 单页挂载代码

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

// HTML代码
let html = `
<!DOCTYPE html>
<html>
  <head><title>Test</title></head>
  <body><div>Hello world!</div></body>
</html>
`;

/**
 * Respond to the request
 * @param {Request} request
 */
async function handleRequest(request) {
  return new Response(html, {
    headers: {
      'Content-Type': 'text/html; charset=UTF-8'
    },
    status: 200
  })
}

Workers 反代任意网站

替换掉其中的example.com 为你需要反代的网址即可;

// Website you intended to retrieve for users.
const upstream = 'example.com '

// Custom pathname for the upstream website.
const upstream_path = '/'

// Website you intended to retrieve for users using mobile devices.
const upstream_mobile = 'example.com '

// Countries and regions where you wish to suspend your service.
const blocked_region = ['KP', 'SY', 'PK', 'CU']

// IP addresses which you wish to block from using your service.
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

// Whether to use HTTPS protocol for upstream address.
const https = true

// Whether to disable cache.
const disable_cache = false

// Replace texts.
const replace_dict = {
    '$upstream': '$custom_domain',
    '//sunpma.com': ''
}

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {
    const region = request.headers.get('cf-ipcountry').toUpperCase();
    const ip_address = request.headers.get('cf-connecting-ip');
    const user_agent = request.headers.get('user-agent');

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;

    if (https == true) {
        url.protocol = 'https:';
    } else {
        url.protocol = 'http:';
    }

    if (await device_status(user_agent)) {
        var upstream_domain = upstream;
    } else {
        var upstream_domain = upstream_mobile;
    }

    url.host = upstream_domain;
    if (url.pathname == '/') {
        url.pathname = upstream_path;
    } else {
        url.pathname = upstream_path + url.pathname;
    }

    if (blocked_region.includes(region)) {
        response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
            status: 403
        });
    } else if (blocked_ip_address.includes(ip_address)) {
        response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
            status: 403
        });
    } else {
        let method = request.method;
        let request_headers = request.headers;
        let new_request_headers = new Headers(request_headers);

        new_request_headers.set('Host', upstream_domain);
        new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

        let original_response = await fetch(url.href, {
            method: method,
            headers: new_request_headers
        })

        connection_upgrade = new_request_headers.get("Upgrade");
        if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") {
            return original_response;
        }

        let original_response_clone = original_response.clone();
        let original_text = null;
        let response_headers = original_response.headers;
        let new_response_headers = new Headers(response_headers);
        let status = original_response.status;
        
        if (disable_cache) {
            new_response_headers.set('Cache-Control', 'no-store');
        }

        new_response_headers.set('access-control-allow-origin', '*');
        new_response_headers.set('access-control-allow-credentials', true);
        new_response_headers.delete('content-security-policy');
        new_response_headers.delete('content-security-policy-report-only');
        new_response_headers.delete('clear-site-data');
        
        if (new_response_headers.get("x-pjax-url")) {
            new_response_headers.set("x-pjax-url", response_headers.get("x-pjax-url").replace("//" + upstream_domain, "//" + url_hostname));
        }
        
        const content_type = new_response_headers.get('content-type');
        if (content_type != null && content_type.includes('text/html') && content_type.includes('UTF-8')) {
            original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
        } else {
            original_text = original_response_clone.body
        }
        
        response = new Response(original_text, {
            status,
            headers: new_response_headers
        })
    }
    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {
    let text = await response.text()

    var i, j;
    for (in replace_dict) {
        j = replace_dict[i]
        if (== '$upstream') {
            i = upstream_domain
        } else if (== '$custom_domain') {
            i = host_name
        }

        if (== '$upstream') {
            j = upstream_domain
        } else if (== '$custom_domain') {
            j = host_name
        }

        let re = new RegExp(i, 'g')
        text = text.replace(re, j);
    }
    return text;
}


async function device_status(user_agent_info) {
    var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
    var flag = true;
    for (var v = 0; v < agents.length; v++) {
        if (user_agent_info.indexOf(agents[v]) > 0) {
            flag = false;
            break;
        }
    }
    return flag;
}