软件技巧



APP 图标生成

从大图自动生成 App 各尺寸的图标:https://icon.wuruihong.com/

提取 IOS IPA

需要利用 Mac 上的 App Configurator 应用。
USB 连接手机,在 App Configurator 上点 “添加” 选择 App:

然后登录你的 apple id,会展示你购买的记录:

选择一个点添加,就会启动下载。
当下载完毕后会进行安装,如果你的设备上已经有该 app 了,会提示:

注意,保持这个界面不动,因为下载时会先缓存到一个目录里,等安装完毕就会删除。所以我们需要让这个界面保持,然后去下列路径里:

1
~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets

就能看到导出后的 IPA 了:

注意,这个 ipa 是加壳的版本。

制作 VS 的 offline installer

首先下载 vs_setup.exe,可以在 VS 的官网下载。

然后执行:

1
vs_community.exe --layout OUTPUT_DIR --lang en-US --config vs.vsconfig

就会把 -config 中指定的所有组件都下载到 Output 目录里。可以把它压缩后传递到其他的机器上去。

离线安装:
解压后在根目录下启动 cmd,执行下列命令:

1
vs_setup.exe --noweb

docx 转换为 md

可以使用 pandoc 实现:

1
pandoc test.docx -o test.md

但是它使用的是 pandoc 的格式,与通用的 markdown 存在不兼容。
可以通过 --write gfm 来指定 github 风格的 markdown,但如果 docx 里对图片有缩放,都会转换为 html 的 img 标签。

可以通过与以下 python 脚本组合使用:

1
2
3
4
5
6
7
8
9
10
import panflute as pf

def change_md_link(elem, doc):
if isinstance(elem, pf.Image):
elem.attributes.pop('width', None)
elem.attributes.pop('height', None)
return elem

if __name__ == "__main__":
pf.run_filter(change_md_link)

使用方法:

1
pandoc test.docx -F remove_img_size.py -o test.md

我的每周技术点总结,批量从 docx 转换 md 的命令:

1
find . -name "*docx" | sed -e 's|^\./||' -e 's/\技术点_lipengzha.docx$//' | xargs -I {} pandoc --extract-media=./docx_images/{} {}技术点_lipengzha.docx -F remove_img_size.py -o {}_技术点.md

Chrome 开启新的 WebUI

访问 chrome://flags/,搜索 Chrome Refresh,把以下两个选项都改成 Enable 即可:

Mac 安装 7z

可以通过 homebrew 安装:

1
2
brew update
brew install p7zip

Proxifier 注册码

L6Z8A-XY2J4-BTZ3P-ZZ7DF-A2Q9C(Portable Edition)# 免安装版本
5EZ8G-C3WL5-B56YG-SCXM9-6QZAP(Standard Edition)# 安装版本
P427L-9Y552-5433E-8DSR3-58Z68(MAC)

获取双反斜杠的路径

把当前路径从 \ 替换为 \\,cmd 代码:

1
2
set final_path=%~dp0
set final_path=%final_path:\=\\%

cmd 添加开机自启

1
2
3
4
5
6
7
8
9
10
11
@echo off
echo Windows Registry Editor Version 5.00 > AutoRun.reg
echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run] >> AutoRun.reg
set final_path=%~dp0
set final_path=%final_path:\=\\%
set exe_name=SwarmAgent.exe
echo "SwarmAgent"="%final_path%%exe_name%" >> AutoRun.reg

regedit /s %~dp0AutoRun.reg
del /s %~dp0AutoRun.reg

cmd 遍历拷贝文件

1
2
3
4
5
6
7
8
9
10
11
12
@echo off

set platform=IOS
set target_path=%WORKSPACE%\Client\Saved\HotPatcher\HPL\%platform%
set copy_target_path=%WORKSPACE%\BuildScript\UploadPakScript\fmgame
set format=*.pak

cd %target_path%
for /f "delims=" %%s in ('dir /b/a-d/s "%target_path%"\"%format%"') do (
echo %%s
copy /y "%%s" %copy_target_path%
)

查看 cmd 命令的路径

1
where git

Win 批量修改文件后缀

1
ren *.txt *.log

android 偏移转符号

可以使用 NDK 中的 addr2line 命令:addr2line

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Usage: addr2line [option(s)] [addr(s)]
Convert addresses into line number/file name pairs.
If no addresses are specified on the command line, they will be read from stdin
The options are:
@<file> Read options from <file>
-a --addresses Show addresses
-b --target=<bfdname> Set the binary file format
-e --exe=<executable> Set the input file name (default is a.out)
-i --inlines Unwind inlined functions
-j --section=<name> Read section-relative offsets instead of addresses
-p --pretty-print Make the output easier to read for humans
-s --basenames Strip directory names
-f --functions Show function names
-C --demangle[=style] Demangle function names
-h --help Display this information
-v --version Display the program's version

addr2line: supported targets: pe-x86-64 pei-x86-64 pe-bigobj-x86-64 elf64-x86-64 elf64-l1om elf64-k1om pe-i386 pei-i386 elf32-i386 elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex
Report bugs to <http://www.sourceware.org/bugzilla/>

具体使用案例:

1
2
# addr2line -C -f -e *.so ADDR
addr2line -C -f -e libUE4.so 0x816EF90

参数:

  • -C -f:打印错误行数所在的函数名称
  • -e 打印错误地址对应的路径及行数

转换结果:

keytool 乱码

在 Win10 + 执行 keytool 的时候如果出现乱码,则需要在命令行中执行:

1
chcp 936

然后重新执行 keytool 命令即可。

Google Translate API

可以用以下形式调用:

1
POST https://translation.googleapis.com/language/translate/v2?key=XXXXXXXXXXXXXXXXXXXXXXXX

传递 json 数组:

1
2
3
4
5
6
7
8
9
{
"q": [
"测试",
"函数",
"人生"
],
"source": "zh-Hans",
"target": "en"
}

IOS beta 更新

以下链接注册:Apple Beta Software Program

ffmpeg

mkv 转 mp4

1
ffmpeg.exe -i UOD2022.mkv -vcodec copy -acodec copy UOD2022.mp4

时长裁剪

裁剪原视频的 00:00:03-00:58:29 之间的内容。

1
ffmpeg.exe -i UOD2022.mp4 -vcodec copy -acodec copy -ss 00:00:03 -to 00:58:29 UOD2022_CUT.mp4

mov 转换为 mp4

1
ffmpeg -i input.mov -q:v 0 output.mp4

拼接 mp4

要把 mp4 转换为 ts 之后再进行拼接:

1
2
3
4
ffmpeg -i begin.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts begin.ts
ffmpeg -i end.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts end.ts
// now join
ffmpeg -i "concat:begin.ts|end.ts" -c copy -bsf:a aac_adtstoasc output.mp4

从视频中提取声音

1
ffmpeg -i test.mp4 -f mp3 -vn test.mp3

分割声音

  • segment_time: 秒数
1
ffmpeg -i test.mp3 -f segment -segment_time 30 -write_xing 0 -c copy out%03d.mp3

Mac 上安装 cmake 到 PATH

  1. One may add CMake to the PATH:(重启失效)

PATH="/Applications/CMake.app/Contents/bin":"$PATH"

  1. Or, to install symlinks to ‘/usr/local/bin’, run:

sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install

  1. Or, to install symlinks to another directory, run:

sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install=/path/to/bin

js 不引入库转换时间格式

1
new Date().toISOString().split('.')[0].replace(/[^\d]/gi,'');

得到的是以下格式的时间:20221020021706

Typore+PicGo 时间戳重命名

在 Typora 的验证图片上传选项中,找到 PicGo 的安装路径。
在 exe 目录下执行以下命令,安装 super-prefix 插件:

1
picgo.exe install super-prefix

然后修改 PicGo 的配置文件,可以指定重命名前缀和文件格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"picBed": {
"current": "tcyun",
"tcyun": {
"appId": "",
"area": "",
"bucket": "",
"customUrl": "",
"path": "",
"secretId": "",
"secretKey": "",
"version": "v5"
}
},
"picgoPlugins": {
"picgo-plugin-super-prefix": true
},
"picgo-plugin-super-prefix": {
"prefixFormat": "YYYY/MM/DD/",
"fileFormat": "YYYYMMDDHHmmss"
}
}

curl 触发 Github Actions

首先需要在 action 的 yml 中添加一个 repository_dispatch

1
2
3
on:
repository_dispatch:
branches: [ master ]

curl 的触发 API:

1
2
3
4
5
6
curl \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer TOUR_GITHUB_TOKEN" \
https://api.github.com/repos/OWNER/REPO/dispatches \
--data-raw '{"event_type":"repository_dispatch","client_payload":{"unit":false,"integration":true}}'

官方文档:Create a repository dispatch event

使用 Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests

def RunAction(REPO,TOKEN,PARAMS_PAYLOAD=""):
url = "https://api.github.com/repos/%s/dispatches" % REPO

payload = ""
if PARAMS_PAYLOAD == "":
payload = "{\"event_type\":\"Deploy\"}"
else:
payload = "{\"event_type\":\"Deploy\",%s}" % PARAMS_PAYLOAD
headers = {
'Accept': 'application/vnd.github+json',
'Authorization': 'Bearer %s' % TOKEN,
'Content-Type': 'text/plain'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

RunAction("unrealCommunity/ue5wiki_source","xxxxxxxxxxxxxxxxxxx")

Google Docs 函数

获取页面中的 og:title 属性:

1
IMPORTXML(post_link, "//meta[@property='og:title']/@content")

替换字符串:

1
SUBSTITUTE("xxxx - 博客园","- 博客园",""))

获取页面中的 title 命名:

1
IMPORTXML(post_link, "//title")

检查值是否是 NaN:

1
IFNA(Value,"")

检查值是否是 Error,若是用空字符替代:

1
IFERROR(Value,"")

Google 翻译:

1
=IFERROR(GOOGLETRANSLATE(G2,"zh-hans","en"),"")

提取链接中的文章标题:

1
=IFERROR(SUBSTITUTE(IFNA(IMPORTXML(post_link, "//meta[@property='og:title']/@content"),IMPORTXML(post_link, "//title")),"- 博客园",""),"")

从 Google Docs 下载文件

安装并使用 Pandaspython -m pip install pandas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd

def build_sheet_url(doc_id, sheet_id):
return f'https://docs.google.com/spreadsheets/d/{doc_id}/export?format=csv&gid={sheet_id}'

def write_df_to_local(df, file_path):
df.to_csv(file_path)

doc_id = 'DOC_ID'
sheet_id = 'SHEET_ID'
sheet_url = build_sheet_url(doc_id, sheet_id)
df = pd.read_csv(sheet_url)
file_path = 'FILE_PATH'
write_df_to_local(df, file_path)

启用 ProjFS

1
Enable-WindowsOptionalFeature -Online -FeatureName Client-ProjFS -NoRestart

查看二进制是否支持 SSE 指令

可以使用 dumpbin 检查:

1
dumpbin /disasm required.exe > required_disasm.asm

查看输出的汇编指令中是否包含 SSE/SSE2 指令,如 movss, xmm0 or xmm1

Chrome 禁用缓存

  1. F12 或右键选择 检查 后打开开发者工具:
  2. 选择更多工具(More tools)-> 网络限制 (Network conditions,
  3. 在界面中勾选 “Disable cache” 选项:

Win 上查看 PE 的符号信息

在 Unix 环境中可以使用 nm 查看二进制文件的符号信息,但在 Win 上对于查看 PE 类型的符号不太方便。

不过,MSVC 中提供了一个 mn 等价物 dumpbin.exe,可以用来查看 PE 文件的符号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Microsoft (R) COFF/PE Dumper Version 14.25.28614.0
Copyright (C) Microsoft Corporation. All rights reserved.

usage: DUMPBIN [options] [files]

options:

/ALL
/ARCHIVEMEMBERS
/CLRHEADER
/DEPENDENTS
/DIRECTIVES
/DISASM[:{BYTES|NOBYTES}]
/ERRORREPORT:{NONE|PROMPT|QUEUE|SEND}
/EXPORTS
/FPO
/HEADERS
/IMPORTS[:filename]
/LINENUMBERS
/LINKERMEMBER[:{1|2}]
/LOADCONFIG
/NOLOGO
/NOPDB
/OUT:filename
/PDATA
/PDBPATH[:VERBOSE]
/RANGE:vaMin[,vaMax]
/RAWDATA[:{NONE|1|2|4|8}[,#]]
/RELOCATIONS
/SECTION:name
/SUMMARY
/SYMBOLS
/TLS
/UNWINDINFO

查看导入导出符号:

1
2
dumpbin.exe /imports UE4Editor-ZstdExample.dll
dumpbin.exe /exports UE4Editor-ZstdExample.dll

Win10 UTF8 编码

开启之后会将 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage 下的 ACPOEMCPMACCP 值修改为 65001:

通过检测它们的值可以知道是否开启了 UTF8 编码。

1
2
3
4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"ACP"="65001"
"OEMCP"="65001"
"MACCP"="65001"

BAT 检测文件是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@echo off
SET PYTHON_EXE=%1\..\..\FEngine\Engine\Binaries\ThirdParty\Python3\Win64\python.exe
SET SCANNER_PY_SCRIPT=%1\ResScanner\PreCommitChecker.py
@REM echo %PYTHON_EXE% %SCANNER_PY_SCRIPT% %2 %3 %4 %5 %6 %7

IF EXIST %PYTHON_EXE% (
IF EXIST %SCANNER_PY_SCRIPT% (
%PYTHON_EXE% %SCANNER_PY_SCRIPT% %2 %3 %4 %5 %6 %7
) ELSE (
ECHO %SCANNER_PY_SCRIPT% NOT FOUND!
)
) ELSE (
ECHO %PYTHON_EXE% NOT FOUND!
)

Win 查看虚拟内存的占用情况

通过 systeminfo 命令即可查看:

Win 查看 PE 文件二进制符号空间分布

需要加载 pdb 和 exe 进行分析:




SCP 上传 / 下载文件

  1. 从远程下载文件
1
2
scp username@host:/path/filename /local_path/
# scp lipengzha@192.168.1.111:/root/test.txt /d/folder/
  1. 上传本地文件到远程
1
2
scp /path/filename username@host:/remote_path
# scp /d/folder/test.txt lipengzha@192.168.1.111:/root/home
  1. 从远程下载文件夹
1
2
scp -r username@host:/remote_dir/ /local_dir/
# scp -r lipengzha@192.168.1.111:/root/home/testfolder /d/
  1. 上传文件夹到远程
1
2
scp -r /local_dir/ username@host:/remote_dir/
# scp -r /d/testfolder lipengzhe@192.168.1.111:/root/home/

可以通过 scp -P 2222 来自定义 ssh 端口。

Windows 查看进程的优先级

可以通过任务管理器查看:

LibChecker

查看 Android Apk 的 so、服务、Activity、权限等。

Windows 查看文件被哪个进程占用

通过资源监视器搜文件名,可以查看文件句柄被哪个进程占用:

Adb over Wi-Fi

  1. USB 连接设备
  2. 让设备的 adbd 守护进程监听 5555 端口,等待 PC 连接
1
adb tcpip 5555
  1. 查看设备 IP,获取 wlan0 的 IP 地址
1
adb shell ifconfig

  1. 断开设备的 USB 连接

  2. 通过 Adb 远程连接设备

1
2
adb connect DEVICE_IP:5555
# adb connect 192.168.31.172:5555
  1. 通过 adb devices 即可看到远程连接的设备

wget gist file

And yet there is, look for the raw button (on the top-right of the source code).

The raw URL should look like this:

1
https://gist.githubusercontent.com/{user}/{gist_hash}/raw/{commit_hash}/{file}

Note: it is possible to get the latest version by omitting the {commit_hash} part, as shown below:

1
https://gist.githubusercontent.com/{user}/{gist_hash}/raw/{file}

Python

编码错误

1
SyntaxError: Non-ASCII character '\xe8' in file PreCommitChecker.py on line 10, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

可以在 py 文件顶部添加编码:

1
#coding=utf-8

获取当前目录

1
2
current_path = os.getcwd()
engine_cmd_exe_path = os.path.abspath(os.path.join(current_path,"../../FEngine/Engine/Binaries/Win64/UE4Editor-cmd.exe"))

import 上级目录

1
2
3
4
import sys
sys.path.append("..")
from notice_robot_py import Robot
from Commandlets import DoCommandlets

os.system 执行带空格程序

使用 subprocess 替换:

1
2
3
ps = subprocess.Popen(final_cmdlet)
ps.wait()
exit_code = ps.returncode # os.system(final_cmdlet)

检测 UTF8 With BOM

1
2
3
4
5
6
7
8
import codecs

f = open(filepath, 'rb')
s = f.read()
if s[:3] == codecs.BOM_UTF8:
# with BOM
else:
# not with BOM

SSH 使用 key 登录失败

可以修改 Mac 的 SSH 配置(/etc/ssh/sshd_config):

1
2
3
RSAAuthentication yes
PubkeyAuthentication yes
StrictModes no

然后重载配置:

1
2
$ sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
$ sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

Windows11 开启 WSA

  1. 启用 Hypre-V/Windows 虚拟机监控程序平台 / 虚拟机平台

  1. 在 BIOS 中开启 CPU 虚拟化(Intel Visualization Technology)

  1. 下载 WSA 离线安装包链接,提取码:iogg

解压后使用管理员权限启动 powershell,执行以下命令:

1
Add-AppxPackage -Path MicrosoftCorporationII.WindowsSubsystemForAndroid_1.7.32815.0_neutral___8wekyb3d8bbwe.Msixbundle

安装完毕之后,就可以在开始菜单搜索到 WSA 了:

启动之后打开开发人员模式:

下面可以看到 WSA 的 IP 地址。

安装之后可以往 WSA 安装 APK,需要先下载 ADB,通过 ADB 往 WSA 安装 apk 文件。

使用 adb connect 命令,网络连接 WSA(IP 地址可从 WSA 中查看):

1
adb connect 127.0.0.1:58526

然后使用 adb install 命令安装 apk 即可:

1
adb install base.apk

甚至能装 UE 打出来的 APK 包,运行正常:

甚至能正常运行 LOLM:

WSA 的 Linux 内核版本为 5.10.34.2

Android 版本为 Android 11:

1
2
3
windows_x86_64:/ $ getprop ro.build.version.sdk
getprop ro.build.version.sdk
30

查看内存:

1
cat /proc/meminfo

KMS 激活

管理员权限启动 cmd 或 powershell:

1
2
3
4
5
slmgr.vbs -ipk W269N-WFGWX-YVC9B-4J6C9-T83GX
#slmgr.vbs -s xincehng213618.cn
#kms.srv.crsoo.com 为作者提供。
slmgr.vbs -skms kms.srv.crsoo.com
slmgr.vbs -ato

去除快捷方式 Icon 小箭头

打开注册表位置(没有 Shell Icons 则新建):

1
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons

新建一个字符串值,名称为 29,内容为 C:\WINDOWS\system32\imageres.dll,197,重启即可。

获取抖音的视频下载地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
import re
import webbrowser

def douyinurl(url):
ua = {
'user-agent': "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"}
response = requests.get(url, headers=ua, allow_redirects=False)
url = response.headers['Location']
itemids = re.findall("video/(.*?)/\?", url)[0]
url = "https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=" + itemids
response = requests.get(url, headers=ua)
videovid = response.json()["item_list"][0]['video']['vid']
url = "https://aweme.snssdk.com/aweme/v1/play/?video_id=" + videovid + "&ratio=720p&line=0"
response = requests.get(url, headers=ua, allow_redirects=False)
url = response.headers['Location']
return url

if __name__ == '__main__':
url = input('请输入抖音分享链接:')
t = douyinurl(url)
webbrowser.open(t)

Python 检测文件编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import os
import sys
import chardet

def find_file_by_format(dir,format):
fileArray = []
for root, folders, files in os.walk(dir, topdown=False):
for name in files:
if name.endswith(format):
fileArray.append(os.path.join(root, name))
return fileArray

def code_format_checker(dir,formats):
result_dict = {}
for format in formats:
fileArray = find_file_by_format(dir,format)
for filepath in fileArray:
with open(filepath, 'rb') as f:
s = f.read()
chatest = chardet.detect(s)
result_dict[filepath] = chatest.get('encoding')
# print("%s %s" % (filepath,chatest.get('encoding')) )
f.close()
return result_dict

checkout_encoding = ["ascii","utf-8","utf-8-sig"]

def not_checkout_encoding(dir,formats,checkout_encodings):
invalid_result_dict = {}
for filepath,encoding in code_format_checker(dir,formats).items():
bIsInvalid = True
for checkout_encoding in checkout_encodings:
if encoding is None:
break
if checkout_encoding == encoding.lower():
bIsInvalid = False
break
if bIsInvalid:
invalid_result_dict[filepath] = encoding
return invalid_result_dict

for filepath,encoding in code_format_checker("C:\Users\lipengzha\Documents\UnrealProjects\Client\Config",["ini"]).items():
print("%s %s" % (filepath,encoding))
Collapse

magic mouse 速度

系统默认的跟踪速度:

1
defaults read -g com.apple.mouse.scaling

设置:

1
defaults write -g com.apple.mouse.scaling 7

查看 keystore 的别名信息

通过 keytool 命令行查看:

1
keytool -list -v -keystore fmgame.keystore -storepass xxxxxx

JetbrainsIDE 过滤 Log

需要安装插件:Grep Console

添加过滤设置即可,还可以设置颜色:

Rider for Unreal 添加启动参数

  1. 首先要在 View-Appearance 中开启 Toolbar
  2. 在 ToolBar 右键 Customize Menus and Toolbars


3. 在 Menus and Toolbars-Main Toolbar-Toolbar Run Actions-Run/Debug 下添加 Edit Configurations

4. 启动之后添加参数即可。

VS 启动调试报错

无法启动调试。请通过打开项目属性并导航配置属性”->“调试” 来检查调试器设置。

应该是项目的工作目录没设置对:

VS 项目右键属性,把 Debuger 里的工作目录改成 $(ProjectDir) 即可。

MSBUILD16.10 使用 Rider 错误

使用 Rider 编译 UE4 的错误信息:

1
UnrealBuildTool.csproj: [MSB4057] 该项目中不存在目标"Engine\UE4"

这是 VS2019 MSBUILD 16.10 的一个 bug,官方说要在 16.10.1 中解决这个问题:

部署 trojan

首先需要把域名解析至 VPS IP 地址,然后依次执行以下命令:

1
2
3
4
5
# 安装BBR
wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh && chmod +x bbr.sh && ./bbr.sh

# 安装trojan
curl -O https://raw.githubusercontent.com/atrandys/trojan/master/trojan_mult.sh && chmod +x trojan_mult.sh && ./trojan_mult.sh

查看、修改 trojan 的密码:

1
nano /usr/src/trojan/server.conf

重启服务:

1
sudo systemctl restart trojan

日期格式匹配正则

1
\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}

这个规则可以匹配以下内容:

1
2
3
2021-01-06
2021/01/06
2021.01.06

批量删除微博脚本

粘贴以下代码到微博页面的 console 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'use strict';
var s = document.createElement('script');
s.setAttribute(
'src',
'https://lib.sinaapp.com/js/jquery/2.0.3/jquery-2.0.3.min.js'
);
s.onload = function() {
setInterval(function() {
if (!$('a[action-type="feed_list_delete"]')) {
$('a.next').click();
} else {
$('a[action-type="feed_list_delete"]')[0].click();
$('a[action-type="ok"]')[0].click();
}

// scroll bottom let auto load
$('html, body').animate({ scrollTop: $(document).height() }, 'slow');
}, 800);
};

document.head.appendChild(s);

Apple 软件使用的 TCP/UDP 端口

cmd 添加防火墙规则

如 SwarmCoordinator 需要开放 ping 以及 TCP 的 8008/8099 端口:

1
2
3
netsh advfirewall firewall add rule name="Unreal Swarm ICMPv4 In" dir=in action=allow enable=yes remoteip=Any protocol=icmpv4
netsh advfirewall firewall add rule name="allowSwarmAgent" protocol=TCP dir=out localport=8008-8009 action=allow
netsh advfirewall firewall add rule name="allowSwarmAgent" protocol=TCP dir=in localport=8008-8009 action=allow

netsh 命令行用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
C:\windows\system32>netsh advfirewall firewall add rule

提供的许多参数无效。请查看帮助获取正确语法。

用法: add rule name=<string>
dir=in|out
action=allow|block|bypass
[program=<program path>]
[service=<service short name>|any]
[description=<string>]
[enable=yes|no (default=yes)]
[profile=public|private|domain|any[,...]]
[localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
[remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
[localport=0-65535|<port range>[,...]|RPC|RPC-EPMap|IPHTTPS|any (default=any)]
[remoteport=0-65535|<port range>[,...]|any (default=any)]
[protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
tcp|udp|any (default=any)]
[interfacetype=wireless|lan|ras|any]
[rmtcomputergrp=<SDDL string>]
[rmtusrgrp=<SDDL string>]
[edge=yes|deferapp|deferuser|no (default=no)]
[security=authenticate|authenc|authdynenc|authnoencap|notrequired
(default=notrequired)]

备注:

- 将新的入站或出站规则添加到防火墙策略。
- 规则名称应该是唯一的,且不能为 "all"
- 如果已指定远程计算机或用户组,则 security 必须为
authenticate、authenc、authdynenc 或 authnoencap。
- 为 authdynenc 设置安全性可允许系统动态协商为匹配
给定 Windows Defender 防火墙规则的通信使用加密。
根据现有连接安全规则属性协商加密。
选择此选项后,只要入站 IPsec 连接已设置安全保护,
但未使用 IPsec 进行加密,计算机就能够接收该入站连接的第一个 TCP 或
UDP 包。
一旦处理了第一个数据包,服务器将重新协商连接并对其进行升级,以便所
有后续通信都完全加密。
- 如果 action=bypass,则 dir=in 时必须指定远程计算机组。
- 如果 service=any,则规则仅应用到服务。
- ICMP 类型或代码可以为 "any"
- Edge 只能为入站规则指定。
- AuthEnc 和 authnoencap 不能同时使用。
- Authdynenc 仅当 dir=in 时有效。
- 设置 authnoencap 后,security=authenticate 选项就变成可选参数。

示例:

为不具有封装的 messenger.exe 添加入站规则:
netsh advfirewall firewall add rule name="allow messenger"
dir=in program="c:\programfiles\messenger\msmsgs.exe"
security=authnoencap action=allow

为端口 80 添加出站规则:
netsh advfirewall firewall add rule name="allow80"
protocol=TCP dir=out localport=80 action=block

为 TCP 端口 80 通信添加需要安全和加密的入站规则:
netsh advfirewall firewall add rule
name="Require Encryption for Inbound TCP/80"
protocol=TCP dir=in localport=80 security=authdynenc
action=allow

为 messenger.exe 添加需要安全的入站规则:
netsh advfirewall firewall add rule name="allow messenger"
dir=in program="c:\program files\messenger\msmsgs.exe"
security=authenticate action=allow

为 SDDL 字符串标识的组 acmedomain\scanners 添加
经过身份验证的防火墙跳过规则:
netsh advfirewall firewall add rule name="allow scanners"
dir=in rmtcomputergrp=<SDDL string> action=bypass
security=authenticate

为 udp- 的本地端口 5000-5010 添加出站允许规则
Add rule name="Allow port range" dir=out protocol=udp localport=5000-5010 action=allow
Collapse

Win 检测进程是否存在

如果存在,杀掉进程,不存在就不执行 taskkill 任务:

1
2
tasklist | find /i "swarmagent.exe"
if "%errorlevel%"=="1" (echo "not found swarmagent process") else (taskkill /f /t /im swarmagent*)

使用 tcping 检测端口是否开放

可以使用 tcping 这个工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ tcping 127.0.0.1 10086
# 端口联通的情况
Probing 127.0.0.1:10086/tcp - Port is open - time=10.775ms
Probing 127.0.0.1:10086/tcp - Port is open - time=0.428ms
Probing 127.0.0.1:10086/tcp - Port is open - time=0.344ms
Probing 127.0.0.1:10086/tcp - Port is open - time=0.317ms

Ping statistics for 127.0.0.1:10086
4 probes sent.
4 successful, 0 failed. (0.00% fail)
Approximate trip times in milli-seconds:
Minimum = 0.317ms, Maximum = 10.775ms, Average = 2.966ms

# 未开放端口的情况
Probing 127.0.0.1:10086/tcp - No response - time=2002.595ms
Probing 127.0.0.1:10086/tcp - No response - time=2000.168ms
Probing 127.0.0.1:10086/tcp - No response - time=2000.202ms
Probing 127.0.0.1:10086/tcp - No response - time=2001.308ms

Ping statistics for 127.0.0.1:10086
4 probes sent.
0 successful, 4 failed. (100.00% fail)
Was unable to connect, cannot provide trip statistics

Windows 通过 bat 存储环境变量

设置用户环境变量:

1
setx ENV_NAME env_value

设置系统环境变量:

1
setx ENV_NAME env_value /m

Windows 挂载网络路径

使用 net use 命令:

1
net use * \\YourCompanyComputer "password" /user:"username" /persistent:yes

如:

1
net use * \\192.168.1.111\Game  "password" /user:"imzlp" /persistent:yes

也可以根据条件进行检测,如果已有挂载就不重新执行:

1
2
3
if not exist "T:\" (
net use T: \\192.168.1.111\Game /user:"imzlp" "password"
)

AndroidP HTTP 请求错误

在 Android P 上使用 HTTP 请求上传数据会有以下错误提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
2018-10-10 16:39:21.312 31611-31646/com.xfhy.tinkerfirmdemo W/CrashReport: java.io.IOException: Cleartext HTTP traffic to android.bugly.qq.com not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)
at com.tencent.bugly.proguard.ai.a(BUGLY:265)
at com.tencent.bugly.proguard.ai.a(BUGLY:114)
at com.tencent.bugly.proguard.al.run(BUGLY:355)
at com.tencent.bugly.proguard.ak$1.run(BUGLY:723)
at java.lang.Thread.run(Thread.java:764)
2018-10-10 16:39:21.312 31611-31646/com.xfhy.tinkerfirmdemo E/CrashReport: Failed to upload, please check your network.
2018-10-10 16:39:21.312 31611-31646/com.xfhy.tinkerfirmdemo D/CrashReport: Failed to execute post.
2018-10-10 16:39:21.312 31611-31646/com.xfhy.tinkerfirmdemo E/CrashReport: [Upload] Failed to upload(1): Failed to upload for no response!
2018-10-10 16:39:21.313 31611-31646/com.xfhy.tinkerfirmdemo E/CrashReport: [Upload] Failed to upload(1) userinfo: failed after many attempts

这需要我们在打包时把指定的域名给配置成白名单。

方法如下:

res/xml 下创建 network_security_config.xml 文件

填入以下内容(网址自行修改):

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">android.bugly.qq.com</domain>
</domain-config>
</network-security-config>

然后在 AndroifManifest.xml 中引用该文件:

1
<application android:networkSecurityConfig="@xml/network_security_config"/>

重新打包即可,在运行时会有以下 Log:

1
02-25 21:09:15.831 27760 27791 D NetworkSecurityConfig: Using Network Security Config from resource network_security_config debugBuild: true

黑苹果指南

查看某个进程的端口占用

使用 netstat 命令:

1
2
3
4
5
6
7
8
9
C:\Users\lipengzha>netstat -ano | findstr "231096"
TCP 0.0.0.0:1985 0.0.0.0:0 LISTENING 231096
TCP 0.0.0.0:3961 0.0.0.0:0 LISTENING 231096
TCP 0.0.0.0:3963 0.0.0.0:0 LISTENING 231096
TCP 127.0.0.1:4014 127.0.0.1:12639 ESTABLISHED 231096
TCP 127.0.0.1:4199 127.0.0.1:12639 ESTABLISHED 231096
UDP 0.0.0.0:6666 *:* 231096
UDP 0.0.0.0:24024 *:* 231096
UDP 0.0.0.0:58101 *:* 231096

outguess 图片隐写

把一些文本信息写入到图片中:outguess

查看 jar 中的类和符号信息

可以使用 JD-GUI 来查看:JD-GUI

Win10 开启长路径支持

打开组策略编辑器 (gpedit.msc),依次找到” 本地计算机策略 - 计算机配置 - 管理模板 - 系统 - 文件系统”,找到 “启用 Win32 长路径” 设置为 “已启用”。

CMD 添加系统环境变量

如果要添加至用户的环境变量:

1
2
rem setx JAVA_HOME "%current_dir_name%\jdk18077"
setx VAR_NAME TARGET_PATH

如果要添加至系统的环境变量,则在 setx 之后加上 /M 参数即可。

镜像文件超 4G 的启动盘制作

之前都是使用软碟通来进行启动盘的制作,但是软碟通使用的是 FAT32,不能存储超过 4G 的文件,但是现在 Win10 都已经超过 4G 了,会导致超过 4G 的文件不会被写入到优盘中,导致启动盘制作失败。
解决这个问题可以使用一个新的工具:rufus

Xcode 与 clang 版本对照

Git 文件变动时间

当使用 git clone 或者更新文件时,本地文件的修改时间为变为当前机器的执行时间,那么如何把文件的修改之间保持为这些文件被提交时的时间呢?

Git 有个方法可以获取文件在当前仓库中的最近提交时间:

1
$ git log -1 --format="%ct" FILE_PATH

得到的是一串数字,Unix 时间戳,如 1601541165,表示的是当前文件最近一次提交的时间。

得到这个时间后,可以通过 touch -d 来修改文件的修改时间:

1
$ touch -d "@1601541165" FILE_PATH

注意:在 Unix 时间戳之前需要添加 @,这是 touch 接收的时间格式。

那么如何批量地对整个仓库进行处理呢?可以使用下面的这行脚本:

1
$ git ls-files -z | while read -d '' path; do touch -d "$(git log -1 --format="@%ct" "$path")" "$path"; done

它会把仓库中的文件的修改时间改为文件在当前仓库中最近的提交时间。

注意:如果本地仓库深度为 1,则所有的文件都是最近这次深度的 commit 时间。

Git LFS 的规则问题

在使用 git lfs 时一定要注意.gitattributes 的规则,如果想要使用 lfs 追踪所有的文件:

1
*.* filter=lfs diff=lfs merge=lfs -text

这个规则是有问题的,它会导致所有的文件都被 lfs 追踪,包括.gitignore.gitattributes,在使用 lfs 拉取时会变动这两个文件,导致所有的文件都被 git 检测出变动状态。
那么合理的规则是,包含所有文件的同时要把.gitignore.gitattributes 给排除掉:

1
2
3
*.* filter=lfs diff=lfs merge=lfs -text
.* !filter
.gitattributes !filter

LaTex 插入符号

空格

含义 指令 效果 解释
两个 quad 空格 a \qquad b ab 两个 m 的宽度
quad 空格 a \quad b ab 一个 m 的宽度
大空格 a\ b a b 1/3m 宽度
中等空格 a;b a;b 2/7m 宽度
小空格 a,b a,b 1/6m 宽度
没有空格 ab ab none
紧贴 a!b a!b 缩进 1/6m 宽度

\quad1ememm 代表当前字体下接近字符‘M’的宽度 (approximately the width of an “M” in the current font).

分隔符

使用 \textrm{-} 插入分隔符 - 不会使其被识别为减号。

1
declaration\textrm{-}specifiers_{opt}

效果如下:

declaration-specifiersopt

重置 Bitnami Gitlab 管理员权限账户密码

安装的 bitnami 后 gitlab 的管理员账号密码默认为:

1
2
3
4
# account
user: Administrator
email: admin@example.com
default password: 5iveL!fe

登录 bitnami gitlab 镜像的账户密码:

1
2
user: bitnami
password: bitnami

修改 gitlab 的默认管理员权限的账号密码可以在安装的 bitnami 镜像的环境中执行下列命令:

1
2
3
4
5
6
7
8
$ sudo gitlab-rails console production
irb(main):001:0> u = User.where(id:1).first
=> #<(User) id:1 @root>
irb(main):001:1> u.password = 'newpassword'
=> "newpassword"
irb(main):001:2> u.password_confirmation = 'newpassword'
=> "newpassword"
irb(main):001:2> u.save!

这样就修改完成了。

Adb 命令

首先先要下载 Adb

Adb 安装 Apk

1
$ adb install APK_FILE_NAME.apk

Adb 关闭 app

1
adb shell am force-stop PACKAGE_NAME

Adb 启动 App

安装的 renderdoccmd 是没有桌面图标的,想要自己启动的话只能使用下列 adb 命令:

1
adb shell am start org.renderdoc.renderdoccmd.arm64/.Loader -e renderdoccmd "remoteserver"

adb 启动 App 的 shell 命令模板:

1
adb shell am start PACKAGE_NAME/.ActivityName

这个方法需要知道 App 的包名和 Activity 名,包名很容易知道,但是 Activity 如果不知道可以通过下列操作获取:

首先使用一个反编译工具将 apk 解包 (可以使用之前的 apktools):

1
apktool.bat d -o ./renderdoccmd_arm64 org.renderdoc.renderdoccmd.arm64.apk

然后打开 org.renderdoc.renderdoccmd.arm64 目录下的 AndroidManifest.xml 文件,找到其中的 Application 项:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.renderdoc.renderdoccmd.arm64" platformBuildVersionCode="26" platformBuildVersionName="8.0.0">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature android:glEsVersion="0x00030000" android:required="true"/>
<application android:debuggable="true" android:hasCode="true" android:icon="@drawable/icon" android:label="RenderDocCmd">
<activity android:configChanges="keyboardHidden|orientation" android:exported="true" android:label="RenderDoc" android:name=".Loader" android:screenOrientation="landscape">
<meta-data android:name="android.app.lib_name" android:value="renderdoccmd"/>
</activity>
</application>
</manifest>

其中有所有注册的 Activity,没有有界面的 apk 只有一个 Activity,所以上面的 renderdoccmd 的主 Activity 就是.Loader

如果说有界面的 app,则会有多个,则可以从 AndroidManifest.xml 查找 Category 或者根据命名 (名字带 main 的 Activity) 来判断哪个是主 Activity。一般都是从 lanucher 开始,到 main,或者有的进登陆界面。

PS:使用 UE 打包出游戏的主 Activity 是 com.epicgames.ue4.SplashActivity,可以通过下列命令启动。

1
adb shell am start com.imzlp.GWorld/com.epicgames.ue4.SplashActivity

Adb 传输文件

使用 adb 往手机传文件:

1
2
# adb push 1.0_Android_ETC2_P.pak /sdcard/Android/data/com.imzlp.TEST/files/UE4GameData/Mobile422/Mobile422/Saved/Paks
$ adb push FILE_NAME REMOATE_PATH

从手机传递到电脑:

1
2
# adb pull /sdcard/Android/data/com.imzlp.TEST/files/UE4GameData/Mobile422/Mobile422/Saved/Paks/1.0_Android_ETC2_P.pak A.Pak
$ adb pull REMOATE_FILE_PATH LOCAL_PATH

Adb:Logcat

使用 logcast 可以看到 Android 的设备 Log 信息。

1
$ adb logcat

会打印出当前设备的所有信息,但是我们调试 App 时不需要看到这么多,可以使用 find 进行筛选 (注意大小写严格区分):

1
2
# adb logcat | find "GWorld"
$ adb logcat | find "KEY_WORD"

查看 UE 打包的 APP 所有的 log 可以筛选:

1
$ adb logcat | find "UE4"

如果运行的次数过多积累了大量的 Log,可以使用清理:

1
adb logcat -c

Adb: 从设备中提取已安装的 APK

注意:执行下列命令时需要检查手机是否开放开发者权限,手机上提示的验证指纹信息要允许。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 查看链接设备
$ adb devices
List of devices attached
b2fcxxxx unauthorized
# 列出手机中安装的所有app
$ adb shell pm list package
# 如果提示下问题,则需要执行adb kill-server
error: device unauthorized.
This adb servers $ADB_VENDOR_KEYS is not set
Try 'adb kill-server' if that seems wrong.
Otherwise check for a confirmation dialog on your device.
# 正常情况下会列出一堆这样的列表
C:\Users\imzlp>adb shell pm list package
package:com.miui.screenrecorder
package:com.amazon.mShop.android.shopping
package:com.mobisystems.office
package:com.weico.international
package:com.github.shadowsocks
package:com.android.cts.priv.ctsshim
package:com.sorcerer.sorcery.iconpack
package:com.google.android.youtube

# 找到指定app的的apk位置
$ adb shell pm path com.github.shadowsocks
package:/data/app/com.github.shadowsocks-iBtqbmLo8rYcq2BqFhJtsA==/base.apk
# 然后将该文件拉取到本地来即可
$ adb pull /data/app/com.github.shadowsocks-iBtqbmLo8rYcq2BqFhJtsA==/base.apk
/data/app/com.github.shadowsocks-iBtqbmLo8rYcq2BqFhJtsA==/...se.apk: 1 file pulled. 21.5 MB/s (4843324 bytes in 0.215s)

Adb 刷入 Recovery

下载 Adb,然后根据具体情况使用下列命令 (如果当前已经在 bootloader 就不需要执行第一条了)。

1
2
3
4
5
6
adb reboot bootloader
# 写入img到设备
fastboot flash recovery recovery.img
fastboot flash boot boot.img
# 引导img
fastboot boot recovery.img

adb 端口转发

可以通过 adb 命令来指定:

1
2
3
4
# PC to Device
adb reverse tcp:1985 tcp:1985
# Device to PC
adb forward tcp:1985 tcp:1985

adb: 根据包名查看 apk 位置

可以使用以下 adb 命令:

1
2
$ adb shell pm list package -f com.tencent.tmgp.fm
package:/data/app/com.tencent.tmgp.fm-a_cOsX8G3VClXwiI-RD9wQ==/base.apk=com.tencent.tmgp.fm

最后一个参数是包名,输出的则是 apk 的路径。

adb: 查看当前窗口的 app 的包名

使用以下 adb 命令:

1
2
3
4
5
6
7
8
$ adb shell dumpsys window w | findstr \/ | findstr name=
mSurface=Surface(name=SideSlideGestureBar-Bottom)/@0xa618588
mSurface=Surface(name=SideSlideGestureBar-Right)/@0x619b646
mSurface=Surface(name=SideSlideGestureBar-Left)/@0xea02007
mSurface=Surface(name=StatusBar)/@0x7e4962d
mAnimationIsEntrance=true mSurface=Surface(name=com.tencent.tmgp.fm/com.epicgames.ue4.GameActivity)/@0x43b30a0
mSurface=Surface(name=com.tencent.tmgp.fm/com.epicgames.ue4.GameActivity)/@0xa3481e
mAnimationIsEntrance=true mSurface=Surface(name=com.vivo.livewallpaper.monster.bmw.MonsterWallpaperService)/@0x53e44ae

其中的 mAnimationIsEntrance=true mSurface=Surface(name= 之后,到 / 之前的字符串就是我们的 app 包名。

npm 换源

把 npm 从官方换到淘宝源:

1
$ npm config set registry https://registry.npm.taobao.org

国内速度会快很多。

Chome79 在 Win10 中崩溃

Chrome 自动更新之后所有的页面都变成了这个样子:

解决办法是在 chrome 的快捷方式中添加 -no-sandbox 参数,但会提示_您使用的是不受支持的命令行标记:-no-sandbox。稳定性和安全性会有所下降。_,暂时我还没找到根本解决的办法,暂时先这样。

三大运营商个人轨迹证明方法

一、电信手机用户证明方法

编辑短信 “CXMYD# 身份证号码后四位” 到 10001,授权回复 Y 后,实现 “漫游地查询”,可查询手机号近 15 日内的途径地信息。

二、联通手机用户证明方法

手机发送:“CXMYD# 身份证后四位” 至 10010,查询近 30 天的全国漫游地信息,便于返工辅助排查。

三、移动用户证明方法

编写 CXMYD, 发送到 10086, 再依据回复短信输入身份证后四位,可查询过去一个月内去过的省和直辖市 (无地市)。

每人免费一天查询 10 次。

npm install 报错

在 npm 安装时遇到下列错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
root@VISIONSMILE-PC:/mnt/c/Users/Administrator/Desktop/hexo# npm install hexo-cli -g
npm http GET https://registry.npmjs.org/hexo-cli
npm http GET https://registry.npmjs.org/hexo-cli
npm http GET https://registry.npmjs.org/hexo-cli
npm ERR! Error: CERT_UNTRUSTED
npm ERR! at SecurePair.<anonymous> (tls.js:1370:32)
npm ERR! at SecurePair.EventEmitter.emit (events.js:92:17)
npm ERR! at SecurePair.maybeInitFinished (tls.js:982:10)
npm ERR! at CleartextStream.read [as _read] (tls.js:469:13)
npm ERR! at CleartextStream.Readable.read (_stream_readable.js:320:10)
npm ERR! at EncryptedStream.write [as _write] (tls.js:366:25)
npm ERR! at doWrite (_stream_writable.js:223:10)
npm ERR! at writeOrBuffer (_stream_writable.js:213:5)
npm ERR! at EncryptedStream.Writable.write (_stream_writable.js:180:11)
npm ERR! at write (_stream_readable.js:583:24)
npm ERR! If you need help, you may report this log at:
npm ERR! <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR! <npm-@googlegroups.com>

npm ERR! System Linux 3.4.0+
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "hexo-cli" "-g"
npm ERR! cwd /mnt/c/Users/Administrator/Desktop/hexo
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.10
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /mnt/c/Users/Administrator/Desktop/hexo/npm-debug.log
npm ERR! not ok code 0

解决办法,在 bash 执行下列命令:

1
$ npm config set strict-ssl false

之后重新执行安装即可。

Install 7z on Linux

1
2
3
4
5
6
7
8
$ sudo apt-get update
$ sudo apt-get install p7zip-full
# 压缩
$ 7z a data.7z data.txt
# 显示7z文件中的文件列表
$ 7z l data.7z
# 解压
$ 7z e data.7z

7z 命令行

解压使用如下命令(-y 是碰到提示一律 yes):

1
$ 7z.exe x xxxx.7z -oD:\Extract -y

也可以指定要解压的格式:

1
$ 7z.exe x xxxx.7z -oD:\Extract *.so -r -y

压缩则可以使用以下命令:

1
$ 7z.exe a xxxx.7z COMPRESS_DIR

scp 拷贝文件

使用以下命令可以使用 ssh 从远程拷贝文件到本地:

1
scp -P 22 buildmachine@xx.xx.xx.xxx:/Users/buildmachine/Client/Binaries/IOS/FGame.dSYM D:\

但是这样有一个缺点是当需要输入密码的时候 scp 无法指定密码。

在 Win 上可以用 puttypscp 来解决,它可以指定 -pw 参数,还可以通过 -batch 禁用所有交互提示:

1
pscp.exe -batch -pw 123456 -P 22 buildmachine@xx.xx.xx.xxx:/Users/buildmachine/Client/Binaries/IOS/FGame.dSYM D:\

v2ray 中大量的 67 错误

看到 v2ray 里有大量的下列错误:

1
2020/04/12 17:31:30 tcp:127.0.0.1:53920 rejected  v2ray.com/core/proxy/socks: unknown Socks version: 67

官方说这是因为应用里设置里 http 代理,排查了一下,这是因为在 win10 的设置里开启了代理,在 Win10 设置 - 网络 - 代理关掉系统代理即可。

Chrome 阅读模式

chrome://flags/ 中有 Enable Reader Mode,开启即可。

命令行安装 VS

以下命令控制根据配置安装 VS,并且不启动任何前台程序,等待安装完成:

1
vs_professional.exe --config="D:\config.vsconfig" --quite --wait

NPM: 指定 Packages 的版本

  • ~version “Approximately equivalent to version” See npm semver - Tilde Ranges & semver (7)
  • ^version “Compatible with version” See npm semver - Caret Ranges & semver (7)
  • version Must match version exactly
  • >version Must be greater than version
  • >=version etc
  • <version
  • <=version
  • 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
  • http://sometarballurl (this may be the URL of a tarball which will be downloaded and installed locally
  • * Matches any version
  • latest Obtains latest release

What’s the difference between tilde(~) and caret(^) in package.json?

在命令行启动资源管理器打开文件夹

在 Windows 上的可以通过 cmd 命令来在资源管理器中打开一个文件夹,使用 explorer 命令:

1
explorer.exe /e,/root, F:\Test

注意,最后指定的路径必须是由 \ 组成的路径,如果是反斜杠的则无法打开正确的目录 (打开的是 user/documents 目录)。

在 UE 中使用时我写了一个路径转换的函数,把一个路径中的所有 / 替换为 \\

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FString ConvPath_Slash2BackSlash(const FString& InPath)
{
FString ResaultPath;
TArray<FString> OutArray;
InPath.ParseIntoArray(OutArray, TEXT("\\"));
if (OutArray.Num() == 1 && OutArray[0] == InPath)
{
InPath.ParseIntoArray(OutArray, TEXT("/"));
}
for (const auto& item : OutArray)
{
if (FPaths::DirectoryExists(ResaultPath + item))
{
ResaultPath.Append(item);
ResaultPath.Append(TEXT("\\"));
}
}
return ResaultPath;
}

Windows tree 命令

在 Windows 的 cmd 下可以使用 tree 命令来列出当前文件夹的目录结构。其命令格式为:

1
tree [drive][path] [/F] [/A]

/F:显示每个文件夹中文件的名称
/A:使用 ASCII 字符,而不使用扩展字符

For example:

1
2
3
4
5
6
D:\recastnavigation\RecastDemo\Contrib\SDL>tree /a
+---docs
+---include
\---lib
+---x64
\---x86
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
D:\recastnavigation\RecastDemo\Bin>tree /a /f
文件夹 PATH 列表
卷序列号为 000002D0 ECDB:6872
C:.
| .gitignore
| DroidSans.ttf
| RecastDemo.exe
| RecastDemo.pdb
| SDL2.dll
| Tests.exe
| Tests.pdb
|
+---Meshes
| dungeon.obj
| nav_test.obj
| undulating.obj
|
\---TestCases
movement_test.txt
nav_mesh_test.txt
raycast_test.txt

快速运行一个 http 文件下载服务

可以使用 nodejsserve,安装完 node 之后在目录中执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ npx serve
WARNING: Checking for updates failed (use `--debug` to see full error)

┌──────────────────────────────────────────────────┐
│ │
│ Serving! │
│ │
│ - Local: http://localhost:5000 │
│ - On Your Network: http://192.168.2.83:5000 │
│ │
│ Copied local address to clipboard! │
│ │
└──────────────────────────────────────────────────┘

浏览器即可访问。

另一种方法是下载 hfs,启动之后添加一个目录即可,很简单。

Windows 编译最新版本的 Lua

首先去 lua.org 下载最新的 lua 代码并解压 (目前是 v5.3.5):

1
2
curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz
tar zxf lua-5.3.5.tar.gz

在 windows 上启动 MSVC 的开发者工具命令:开始菜单 -x64 Native Tools Command Prompt,将路径切换到 Lua 源码的 Source 目录吗,使用 cd /d 命令。
然后依次执行下面几条命令:

1
2
3
4
5
6
7
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua535-import.lib /OUT:lua535.dll *.obj
lib /OUT:lua535.lib *.obj
link /OUT:luac.exe luac.o lua535.lib
link /OUT:lua.exe lua.o *.obj

最终编译出 lua.exe/luac.exe/lua535.dll/lua535-import.lib/lua535.lib,这一堆的东西。

Windows 环境变量长度超限制

今天往系统的 PATH 中添加一个新的路径,结果居然提示我太长不能保存。

这岂不是要了老命了,研究了一下,发现可以在系统的 Path 中添加一个另外的环境变量值。

即,现在系统中随便新建一个环境变量,如 %ExternPATH%,然后将该环境变量添加至 PATH 中,ExternPATH 中的值也都可以被查找到。

Epic 账号切换国家区域

Epic 商城是锁国区的,有些内容国内账号没有,而且现在 Epic 商城要求付款账单地址信息与 Epic 账户信息一致,意味着,美元账户付不了国区。如果在 Epic 商城绑定支付信息和购买内容之后是没办法直接在网页上修改的,需要联系人工客服。

首先去 Epic Games | Support Center 提交联系客服的申请,问题描述就用英文说要修改账户的国家和地区从中国转为美国,之后客服会给你邮箱发邮件要求你提供几个信息。

  1. Email address associated with your Epic Games account
  2. Current Epic Games account display name
  3. First and last names of Epic Games account holder
  4. External account currently connected to your Epic Games account, if applicable.
  • This includes Google, Facebook, Twitch, PSN, Xbox, and Switch accounts.
  • Include the platform AND display name of any external accounts.

在邮件里直接回复这些信息之后,他们会给 Epic 账号绑定的邮箱发送一个验证链接,验证之后,再给他们回复邮件说验证成功,之后他们就会给你修改了。

注意:修改国家之后,之前账户绑定的支付信息都会清空,如 Paypal 账号之类的。

PS:Epic 的客服联系渠道还真是超难找…

CMD 添加环境变量

cmd 查看系统的环境变量,在 cmd 窗口中输入 set

将执行路径添加至系统的 PATH 路径,使用 setx

1
setx Path "%PATH%;C:\BuildPath\Adb";

添加自定义的环境变量:

1
setx ANDROID_HOME "%current_dir_name%\android-sdk-windows"

cmd 中获取当前的目录:

1
set "current_dir_name=%cd%"

附上添加 AndroidSDK 环境的 bat:

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
set "current_dir_name=%cd%"
setx JAVA_HOME "%current_dir_name%\jdk18077"
setx ANDROID_HOME "%current_dir_name%\android-sdk-windows"
setx ANDROID_NDK_ROOT "%current_dir_name%\android-ndk-r14b"
setx ANT_HOME "%current_dir_name%\apache-ant-1.8.2"
setx GRADLE_HOME "%current_dir_name%\gradle-4.1"
setx NDK_ROOT "%current_dir_name%\android-ndk-r14b"
setx NDKROOT "%current_dir_name%\android-ndk-r14b"
setx NVPACK_NDK_TOOL_VERSION "4.9"
setx NVPACK_NDK_VERSION "android-ndk-r14b"
setx NVPACK_ROOT "%current_dir_name%"

自动以管理员权限启动 bat

将依赖管理员权限启动的 bat 命令写到 Admin 之后即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
@echo off
cd /d "%~dp0"
cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul
if %errorlevel%==0 goto Admin
if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs"
echo Set RequestUAC = CreateObject^("Shell.Application"^)>"%temp%\getadmin.vbs"
echo RequestUAC.ShellExecute "%~s0","","","runas",1 >>"%temp%\getadmin.vbs"
echo WScript.Quit >>"%temp%\getadmin.vbs"
"%temp%\getadmin.vbs" /f
if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs"
exit

:Admin

CMD 杀掉进程

在 Linux 中可以使用 kill PID 来干掉某一个进程。

在 Cmd 中可以使用 taskkill 来终止进程:

1
taskkill /f /t /im PROCESS_NAME.exe

如:

1
taskkill /f /t /im qq.exe

批量 ping

有时候会有一堆的域名和 ip 需要进行 ping 测试,看是哪些 ping 不通,可以用下面的命令(将待检测的 ip 和域名都放到 ip.txt 中):

1
$ for /f %D in (ip.txt) do (ping %D -n 1 && echo %i>>ok.txt || echo %D >>no.txt)

修改 Epub 书籍的页面翻页方向

我们习惯的书籍是从左往右翻页的,但是在港台有些出版的书籍是从右往左翻页的,很不习惯。
今天我下了一本书就是这个样子的,研究了一下可以修改为从左往右的翻页方式。
首先把目标 epub 文件解压出来,找到 content.opf 文件,打开编辑,找到如下内容:

1
2
<spine page-progression-direction="rtl" toc="ncx">
</spine>

问题就是出在 page-progression-direction="rtl" 这里,从参数上可以看 rtl 就是 right to left 啊,改成 ltr(left to right) 后,把刚解压出来的所有文件压缩成 zip 文件然后把 zip 后缀改为 epub 即可。

无损转换 AZW3 到 EPUB

使用 Calibre 默认的 AZW3 转换到 EPUB 中间是有损压缩的,可以安装 Calibre 的一个插件来实现无损转换。
在 Calibre 的首选项 - 插件下搜索 KindleUnpack 并安装,安装之后重启 Calibre,可以看到工具栏有了一个 KindleUnpack 的按钮。

选中书籍后点击工具栏上的 KindleUnpack 按钮选择 AZW3-UnpackAZW3

路由器级联:使两个路由器在同一网段

今天有个需求,需要把单独连接一个路由器 A 的几台电脑与连接其他路由器 B 的电脑配置在同一个局域网里。
方法为,关闭路由器 A 里的 DHCP,从路由器 B 的 LAN 口拉一条网线过来查到路由器 A 的 LAN 口,其他的设备还接路由器 A 的 LAN 口,在路由器或者电脑的网络设置中设置过 IP 之后,路由器 A 就和路由器 B 连接的设备在同一个局域网下了。

VMWare 扩展 Linux 虚拟机磁盘

首先在虚拟机启动之前 (关闭状态下),调整虚拟机的磁盘大小:

经过漫长的等待…

与网上的其他方法不一样,我不打算列一堆命令,有一个最简单的方法。

那就是在虚拟机设置里添加一个 CD/DVD 的硬件,挂载 GPrated 的镜像,在选择 CD-ROM 加载之后,进去就是图形化的分区工具了,十分方便。

引导菜单:

启动之后:

Linux 查看文件系统类型

查看文件系统类型可以使用以下命令:

1
$ df -Th

Chrome 重启之后就暂停同步

打开 chrome://settings/content/cookies ,仅将本地数据保留到您退出浏览器为止取消勾选。重启 Chrome 即可。

隐藏 bat 的黑窗口

1
2
3
4
5
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
"%~dp0\Engine\Binaries\Win64\UE4Launcher.exe"

保存为.bat,将真正需要执行的命令写入 begin 之后即可。

MBR 无损迁移到 GPT

之前装系统使用的是 MBR 分区表,但是最近要折腾一下黑苹果,四叶草只能 UEFI 启动,所以必须要是 GPT 分区表,但是完全不想完全格掉重装,折腾了一下,可以无损迁移。
首先,要有一个可以启动并且有 GHOST 工具的 U 盘。

  1. 进入 PE, 使用 GHOST 备份当前 MBR 的 C 盘
  2. 备份完成后,删除原 C 盘硬盘的所有分区,修改分区表为 GPT 并创建好分区
  3. 在 PE 中使用 GHOST 将备份的系统还原到 GPT 的分区中
  4. 引导原版的系统镜像 (将 boot/efi/bootmgrbootmgr.efi 放入恢复完成的分区)
  5. 重启进入原版镜像的安装模式,使用修复系统会重建 EFI 的系统引导,修复完成即可。

注意:4-5 两个步骤可以使用其他的引导修复工具替代。

Windows 窗口切换快捷键

Win+Shift+Left/Right:可以控制窗口在多个显示器上左移或者右移;
Win+Shift+Up:保持窗口宽度的同时最大化窗口;
Win+Shift+Down:最小化窗口;

PS:Win+Shift+S 则是屏幕截图。

Linux 创建软链接

1
2
$ ln -s $TargetPath $SoftLinkPath
# ln -s ~/blog newblog

Linux 添加 PATH 路径

Linux 上可以通过 export 来查看当前的 PATH 路径列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ export
declare -x HOME="/root"
declare -x LANG="en_US.UTF-8"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.webp=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.webp=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:"
declare -x MAIL="/var/mail/root"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/etc/ngrok_bin"
declare -x PWD="/root"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="xterm"
declare -x USER="root"
declare -x XDG_DATA_DIRS="/usr/local/share:/usr/share:/var/lib/snapd/desktop"
declare -x XDG_RUNTIME_DIR="/run/user/0"
declare -x XDG_SESSION_ID="2"

或者:

1
$ echo $PATH

输出当前用户的 PATH 路径。

  1. 直接在终端中添加 PATH,只在当前环境有效,退出终端失效:
1
$ export PATH=$PATH:ADD_PATH
  1. 为当前用户添加 PATH 路径,打开 ~/.profile 增加以下内容:
1
export PATH=$PATH:ADD_PATH

重启之后生效。

Windows 查看程序的网络连接

首先在任务管理器中显示进程的 PID,然后在 cmd 下执行命令:

1
netstat -ano|findstr PID

把 PID 换成你的进程 ID 即可。

apt-get update 错误:无法验证签名

如果 apt-get 出现下列错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@gyvrhost:~/downloads/onedrive# sudo apt-get update && sudo apt-get -y --allow-unauthenticated
Hit:1 http://security.ubuntu.com/ubuntu artful-security InRelease
Hit:2 http://archive.ubuntu.com/ubuntu artful InRelease
Hit:3 http://archive.ubuntu.com/ubuntu artful-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu artful-backports InRelease
Get:5 https://netcologne.dl.sourceforge.net/project/d-apt d-apt InRelease [4,893 B]
Err:5 https://netcologne.dl.sourceforge.net/project/d-apt d-apt InRelease
The following signatures couldn't be verified because the public key is not available: NO_PUBKEY EBCF975E5BA24D5E
Reading package lists... Done
W: GPG error: https://netcologne.dl.sourceforge.net/project/d-apt d-apt InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY EBCF975E5BA24D5E
E: The repository 'https://netcologne.dl.sourceforge.net/project/d-apt d-apt InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

如果不修复这个错误回在安装或升级软件包时出现问题,因为 APT 具有一组可信密钥,用于确定是否可以对软件包进行身份验证,从而决定是否可以在系统上安装软件包。
可以执行以下操作将缺失的密钥添加到 APT 密钥管理器:
上面的错误是告诉我们缺少 EBCF975E5BA24D5E 这个键,添加密钥使用以下命令:

1
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EBCF975E5BA24D5E

执行完毕即可解决错误。

Chrome 浏览器由所属组织管理

解决办法,删除:

1
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome

下的 EnabledPlugins 文件夹,重启 Chrome 即可。

CMD 命令:拷贝文件夹

windows 下拷贝多级目录可以使用 xcopy.

1
xcopy /y/i/s/e ..\..\..\Content\Slate UE4Launcher\Engine\Content\Slate

CMD 命令:创建多级目录

1
md 123\456\789

tar.gz 的压缩与解压缩

1
2
3
4
# 压缩
$ tar zcvf target.tar.gz target_dir/
# 解压缩
$ tar zxvf target.tar.gz

使用 Calibre 转换繁体为简体

首先,将原始的繁体书籍 (epub/mobi) 导入 Calibre,然后使用转换:

在弹出的界面中选择搜索 & 替换,加载一个文字替换规则:Calibre 繁体转简体规则

然后点元数据选择输出格式以及文件信息,最终点确定即可开始转换。

从 GooglePlay 下载图书并去除 DRM

Google 图书看书不方便,试了一下怎么把购买过的图书从 GooglePlay 上下载下来。
首先,打开 play.google.com/books,找到你购买过的书,点击下载:

这里并不会把书真的下载下来,而是会下载下来一个 *.ACSM 文件。
然后需要下载 Adobe Digital Editions 来打开它,安装之后,将 *.ACSM 文件拖入_Adobe Digital Editions_的窗口中,会弹出下列窗口:

请选择我想要在不使用 ID 的情况下对我的计算机授权,之后点_下一步_:

授权
之后会自动下载书籍并且会在 Adobe Digital Editions 中打开,但是这些图书文件是使用 DRM 保护的,无法使用其他的阅读器打开。需要去除 DRM 才可以被其他的阅读器打开,需要使用的工具为 Calibre 和 Calibre 的去除 DRM 插件 DeDRM_tools.
下载完 Calibre 之后安装,解压 DeDRM_tools 压缩包。
打开 Calibre 的首选项 - 插件:


点击从文件夹加载插件,选择 DeDRM_plugin.zip

安装完成之后选择文件类型 插件,点自定义插件:

为 ADE 添加一个 key:

然后重启 Calibre.
最后将从 ADE 下载下来的具有 DRM 的图书文件拖入 Calibre 后即去除了 DRM (Calibre Library 里生成的图书文件).

Windows 访问共享提示没有权限使用网络资源

如果 Windows 在访问共享的文件夹时提示:

无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有访问权限。

解决办法:添加 Windows 凭证。
控制面板显示所有控制面板项,搜索凭据管理器,进入后点击 Windows 凭据,然后添加一个 Windows 凭据
根据需要访问的共享的 IP 和账户信息创建即可。

解决 Windows 在英文语言下中文字体太丑的问题

因为在中文语言下我替换了雅黑的字体,看起来不那么虚,但是当我把系统语言切换为 English 后发现中文的字体都很虚啊。
查了一些如何在英文语言下替换中文字体的方法,记录一下。

在英文版 Windows 中默认字体一般都是 Segoe UI、Tahoma、Microsoft Sans Serif 之类,这些字体都是没有中文字库的,所以当需要显示中文字体的时候,就会出现各种难看的文字效果。
解决方法是使用 “字体链接(FontLink)” 技术:就是在使用英文字体时,如果遇到这种字体中没有的字符,就会到注册表相应的位置去找它链接的字体。
英文版 Win7 的默认字体是 Segoe UI, 这是个纯英文字体。所以要显示中文的时候它就会去找它链接的字体。
打开注册表地址:

1
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink

这里面就是各个字体的链接字体的信息。
在这个键值下会发现 Segoe UI,Tahoma 这些常用英文字体的链接,查看 Segoe UI 的值,它的第一行为 Tahoma.TTF,意思就是遇到中文时,它默认到 Tahoma.TTF 文件里去找,如果没有发现这个字,再到第二行的字体里去找。
双击编辑 Segoe UI 的项,可以看到雅黑的链接顺序在中间的位置,我们要做的就是把雅黑的顺序提到最前面:

替换后:

然后重启即可。

以防原链接失效,上面的部分内容摘录自后面的文章,作为本站的备份用。想要了解更具体内容可看这篇文章:解决英文版 Windows 中中文字体难看的问题

修改 Android 的 DNS

编辑 /system/build.prop 加入以下几行:

1
2
3
4
net.rmnet0.dns1=1.1.1.1
net.rmnet0.dns2=8.8.8.8
net.dns1=1.1.1.1
net.dns2=8.8.8.8

保存退出即可 (最好重启或者开关一下飞行模式。

tracert 命令

路由跟踪,查看数据包访问目标所选择的路径。
Tracert 命令使用用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由.

禁用 MIUI 的更新提示

ROOT 手机,安装 RE 文件管理器。
打开 RE,找到路径 /system 下打开 build.prop 编辑:

1
ro.build.version.incremental=V9.5.8.0.OCAMIFA

修改为一个大的版本号:

1
ro.build.version.incremental=V99.5.8.0.OCAMIFA

保存后重启即可。

增强扫描版 pdf

  • 首先下载 ImageMagick 并安装,注意勾选 Install legacy components (convert.exe etc)
  • 然后安装 Ghostscript(目的是为了使用 convert 命令)。
  • 将 pdf 转为图片

假设原始文件名是 origin.pdf, 目标文件名是 target.pdf, 下方的 convert 应替换为实际路径

1
$ convert -density 400 origin.pdf output/%03d.webp

上方的 density 参数指像素密度,数字越高图片质量越高体积越大,如果 pdf 带文字,就设置 300 以上吧。这是影响最终效果的重要参数,如果过低,那么下方再神操作效果也不会很好,过高会导致文件体积过大该指令将整个 pdf 按页转为多张图片,%03d.webp 表示命名为 001.webp,002.webp….(超过 1000 页就应改为 %04d.webp) 转换为图片这一步,是为了获取中间产物进行测试和调整,通常只需截取一部分页面即可 (因为截取一页需要花费数秒时间)

1
2
3
4
#截取第11到第21页
$ convert -density 400 origin.pdf[10-20] output/%04d.webp
#截取第10页
$ convert -density 400 origin.pdf[9] output/%04d.webp
  • 测试转换效果
1
$ convert -level 60,97% -quality 50 output/010.webp preview010.webp

上方的 level 参数是指调整图像通道的级别,60,97% 表示灰度低于 60% 即为黑点,高于 97% 为白点。这里的 60,97 需要反复调节到自己认为达到最佳效果,这是整个过程中最重要的参数,通过该参数实现调整对比度 quality 指输出 jpg 文件质量 (压缩比), 1-100 数字越高质量越高体积越大,出于减少 pdf 文件大小的考虑,应适当调节该参数 (举个例子 density 400 的 jpg 文件可能有 1.4M, 压缩后为 700K, 这样最终的 pdf 文件大小相差一倍,而肉眼无法察觉页面效果有何区别)

二值化图片
扫描的 pdf 很多都是泛黄的,影响观感,可以通过 ImageMagick 将图片处理为黑白的:

1
convert 0020.webp -threshold 55% threshold0020.webp

经过尝试,阈值选择在 140(255*55%)附近时,分割效果较好。灰度值大于该阈值的像素全部变为 255(白色),灰度值低于该阈值的像素全部变为 0(黑色)。

  • 转为 pdf

确定了 density, level 和 quality 的值之后就可以执行转换了可以从原始 pdf 转换

1
$ convert -density 400 origin.pdf -level 40,97% -quality 50 target.pdf

也可以从之前生成的 jpg 转换:

1
$ convert -level 60,97% -quality 50 output/* target.pdf

如果直接从目录转换为 pdf 打开显示有问题,可以将导出的文件批量处理之后再使用福昕之类的软件合并:

1
find . -name "*.webp"|xargs -I {} convert -level 60,97% -quality 50 {} {}_.webp

把当前目录下所有的.webp 增强处理之后另存为 *.webp_.webp.
然后把它们移动到单独的目录 (-I {} 的作用是把后续的 {} 替换为参数):

1
2
$ mkdir finalOutput
$ find . -name "*_.webp"|xargs -I {} mv {} ./finalOutput

然后使用福昕合并成 pdf 文件即可 (顺便也可以做 OCR)。

Windwos 上使用 MinGW 编译 LLVM

首先,下载 LLVMClang 源码,并解压。
将 Clang 的源码 (cfe-6.0.1.src) 目录改名 clang 后放到 LLVM 源码的 tools 目录下 ($LLVM_SRC_ROOT/tools/clang)。
在 LLVM 源码目录右键打开 Git Bash 终端,执行下列命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ mkdir build
$ cd build

# cmake参数
# G为要生成的格式,用MinGW,这里大小写必须写对,写错的话会有提示。
# CMAKE_BUILD_TYPE为构建类型,可以写Debug,Release,MinSizeRel。
# CMAKE_INSTALL_PREFIX为install路径,一般这里路径最好保守一些,尽量不要用中文或空格。
# CMAKE_MAKE_PROGRAM这里写不写都可以,如果用Ninja编译的话,这里就必须写了。
$ cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=D:\LLVM -DCMAKE_MAKE_PROGRAM=mingw32-make.exe ..
# 执行编译
$ mingw32-make
# 编译完毕后执行安装
$ mingw32-make install

安装完之后就可以在 CMAKE_INSTALL_PREFIX 指定的目录看到编译完的 LLVM 和 Clang 了,将其添加到系统 Path 路径即可。
我编译好的版本 (目前最新 LLVM 6.0.1),编译环境为 MinGW64-x86_64-6.2.0-posix-seh-rt_v5-rev1,可以在这里下载。
注:其他的细节可以看 Clang 源码目录下的 INSTALL.TXT 文件。

  • 2018.09.27 这几天 LLVM 出了 7.0.0 版本,果然是版本帝。我又编译了一个 7.0.0 版本的,编译环境与上文相同:点此下载

解决 cmder 中文乱码


打开 cmder 设置 Startup-Environment,添加 set LANG=zh_CN.UTF-8 即可。

apk 的反编译与签名

  1. 安装 java 环境,jdk 下载
  2. 下载最新版本的 apktool.jar,并且重命名为 apktool.jar
  3. 保存下列脚本为 apktool.bat
1
2
3
4
5
@echo off
if "%PATH_BASE%" == "" set PATH_BASE=%PATH%
set PATH=%CD%;%PATH_BASE%;
chcp 65001 2>nul >nul
java -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0\apktool.jar" %*

然后将 apktool.bat 和 apktool.jar 放在同一个目录下。或者直接下载我打包的 apktool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 反编译apk
$ apktool.bat d -o <output_dir> <input.apk>
# 修改完成后重新编译apk
$ apktool.bat b -o <output.apk> <input_dir>

# 生成keystore文件

# -genkey 产生证书文件
# -alias 产生别名
# -keystore 指定密钥库的.keystore文件中
# -keyalg 指定密钥的算法,这里指定为RSA(非对称密钥算法)
# -validity 为证书有效天数,这里我们写的是40000天
$ keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore

# 签名到apk,记得替换<input.apk>为需要签名的apk文件
$ jarsigner -verbose -keystore demo.keystore <input.apk> demo.keystore

查看 keystore 证书指纹

1
keytool -list -v -keystore xxxx.keystore -storepass PASSWORD

树莓派命令行配置连接 Wifi

在树莓派上的 Wifi 连接信息是保存在 /etc/wpa_supplicant/wpa_supplicant.conf 文件中的:

1
2
3
4
5
6
7
8
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid="APName"
psk="password"
key_mgmt=WPA-PSK
}

照着 network 中的配置信息把 ssid 与 psk 填上就可以了。
注意:优先连接的顺序是配置的顺序,如果你希望优先连接某一个 AP,那么将它的配置挪到最前面。

关闭 Windows 休眠来释放磁盘空间

Windows 下的休眠文件 hiberfil.sys 一般很大,都有十几个 G,而我一般也很少用到休眠功能,可以使用下面的命令关闭。
以管理员权限运行 cmd:

1
powercfg -h off

重启系统即可,hiberfil.sys 所占的空间就会被释放了。

远程控制下切换窗口到另一个屏幕

有些 VNC 工具对多屏幕支持不友好,只能显示一个屏幕上的窗口内容,如果所有的打开窗口默认都在另一个屏幕,则软件都操作不了了。
Windows 移动窗口的快捷键是:
Alt+Space 出现菜单,然后按 M,就是移动功能。
可以使用鼠标或者上下左右键来移动窗口到远程可以看到的屏幕。

Windows 窗口快捷键

最大化:在窗口下按:Alt+Space+X
最小化:在窗口下按:Alt+Space+N

Wget 下载网站

1
$ wget -c -r -np -k -L -p api.unrealengine.com/INT/API/

参数如下:

-c 断点续传
-r 递归下载,下载指定网页某一目录下(包括子目录)的所有文件
-nd 递归下载时不创建一层一层的目录,把所有的文件下载到当前目录
-np 递归下载时不搜索上层目录,如 wget -c -r www.xxx.org/pub/path/
没有加参数 - np,就会同时下载 path 的上一级目录 pub 下的其它文件
-k 将绝对链接转为相对链接,下载整个站点后脱机浏览网页,最好加上这个参数
-L 递归时不进入其它主机,如 wget -c -r www.xxx.org/
如果网站内有一个这样的链接:
www.yyy.org,不加参数 - L,就会像大火烧山一样,会递归下载 www.yyy.org 网站
-p 下载网页所需的所有文件,如图片等
-A 指定要下载的文件样式列表,多个样式用逗号分隔
-i 后面跟一个文件,文件内指明要下载的 URL

Linux 查看 nohup.out

1
$ tail -fn 50 nohup.out

WSL 换源

WSL 的 Ubuntu 使用的是 Ubuntu 16.04 版本,可以通过 lsb_release -a 查看:

1
2
3
4
5
6
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial

备份 /etc/apt/sources.list,然后替换其中的内容为国内阿里源:

1
2
3
$ sudo cd /etc/apt
$ sudo mv sources.list sources.list.backup
$ sudo nano sources.list

把下面的内容填入其中,保存退出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse

然后更新即可:

1
$ sudo apt-get update

清理 Mstsc 的历史记录

清理 mstsc 的历史记录只需要把下面这个注册表项里的记录删除即可:

1
[HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default]

修改 Win10 远程连接的默认端口

这几天使用 frp 做内网穿透,在公司也可以通过 mstsc 来访问内网的电脑,但是使用默认的端口 (3389) 感觉又不安全 (总有无良开扫描器的),研究了一下怎么修改 win10 默认的远程连接端口,具体操作如下。

打开下面两个注册表项,依次执行下列操作:

1
2
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Terminal Server/Wds/rdpwd/Tds/tcp
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Terminal Server/WinStations/RDP-Tcp

在这两个注册表项的右侧找到 PortNamber 记录,可以看见其默认值是 3389,修改成所希望的端口 (<65535) 即可(如 11111), 注意使用十进制。

然后还需要修改防火墙的放行端口,因为 Windows 的远程连接默认端口是 3389,所以 3389 防火墙是默认放行的,但是上面修改之后的端口是不行的,所以要修改一下。
依次打开这两个注册表项,执行下面的操作:

1
2
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/SharedAccess/Defaults/FirewallPolicy/FirewallRules
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/SharedAccess/Parameters/FirewallPolicy/FirewallRules

在这两个注册表项的右侧找到这两个记录:RemoteDesktop-UserMode-In-TCPRemoteDesktop-UserMode-In-UDP:
他们的值默认情况下类似下面这样:

1
v2.28|Action=Allow|Active=FALSE|Dir=In|Protocol=6|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28775|Desc=@FirewallAPI.dll,-28756|EmbedCtxt=@FirewallAPI.dll,-28752|

我们只需要将这两个记录里面的 LPort 改为我们上面修改的端口 (11111) 即可。

然后就可以在控制面板/系统和安全/防火墙/高级设置/入站规则里点刷新之后看到我们修改之后的端口了 (我的端口已打码..):

查看 Linux 系统上所有的服务

1
$ service --status-all

注:在我的系统版本 (ubuntu 16.04.3 LTS) 上 iptables 的服务是 ufw

Linux 防火墙放行端口

如果是使用 ufw 服务的话可以使用这种方法:

1
2
$ ufw allow 6060/udp
$ ufw allow 6060/tcp

允许特定端口范围通过防火墙
使用 UFW 指定端口范围时,必须指定规则适用的协议( tcp 或 udp ),以下为示例:

1
2
$ ufw allow 10000:10100/tcp  #允许 10000~10100 端口的 tcp 通过防火墙
$ ufw allow 10000:10100/udp #允许 10000~10100 端口的 udp 通过防火墙

如果是使用 iptable 服务的话可以使用下面的方法:

1
2
3
4
# 接受从端口6060的入站的UDP连接
$ iptables -A INPUT -p udp --destination-port 6060 -j ACCEPT
# 丢弃从6060入站的UDP数据包
$ iptables -A INPUT -p udp --destination-port 6060 -j DROP

更多 ufw 的用法:Ubuntu 18.04 使用 UFW 设置防火墙

iptables 的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
iptables v1.4.21

Usage: iptables -[ACD] chain rule-specification [options]
iptables -I chain [rulenum] rule-specification [options]
iptables -R chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LS] [chain [rulenum]] [options]
iptables -[FZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]
iptables -h (print this help information)

Commands:
Either long or short options are allowed.
--append -A chain Append to chain
--check -C chain Check for the existence of a rule
--delete -D chain Delete matching rule from chain
--delete -D chain rulenum
Delete rule rulenum (1 = first) from chain
--insert -I chain [rulenum]
Insert in chain as rulenum (default 1=first)
--replace -R chain rulenum
Replace rule rulenum (1 = first) in chain
--list -L [chain [rulenum]]
List the rules in a chain or all chains
--list-rules -S [chain [rulenum]]
Print the rules in a chain or all chains
--flush -F [chain] Delete all rules in chain or all chains
--zero -Z [chain [rulenum]]
Zero counters in chain or all chains
--new -N chain Create a new user-defined chain
--delete-chain
-X [chain] Delete a user-defined chain
--policy -P chain target
Change policy on chain to target
--rename-chain
-E old-chain new-chain
Change chain name, (moving any references)
Options:
--ipv4 -4 Nothing (line is ignored by ip6tables-restore)
--ipv6 -6 Error (line is ignored by iptables-restore)
[!] --protocol -p proto protocol: by number or name, eg. `tcp'
[!] --source -s address[/mask][...]
source specification
[!] --destination -d address[/mask][...]
destination specification
[!] --in-interface -i input name[+]
network interface name ([+] for wildcard)
--jump -j target
target for rule (may load target extension)
--goto -g chain
jump to chain with no return
--match -m match
extended match (may load extension)
--numeric -n numeric output of addresses and ports
[!] --out-interface -o output name[+]
network interface name ([+] for wildcard)
--table -t table table to manipulate (default: `filter')
--verbose -v verbose mode
--wait -w wait for the xtables lock
--line-numbers print line numbers when listing
--exact -x expand numbers (display exact values)
[!] --fragment -f match second or further fragments only
--modprobe=<command> try to insert modules using this command
--set-counters PKTS BYTES set the counter during insert/append
[!] --version -V print package version.
Collapse

一些参数缩写:

  • --sport is short for --source-port
  • --dport is short for --destination-port

Linux 下递归删除特定文件

如果我们期望递归删除当前目录下的所有 Binaries 文件夹,可以使用以下命令:

1
$ find . -name "Binaries" | xargs rm -rf

就是先通过 find 找到当前目录下所有的 Binaries 文件夹,然后通过 xargs 这个构造参数列表并运行 rm -rf 命令。

在 WSL 中跑 SS 和 KCP

最近公司把 shadowsocks-windows 的进程给禁用了,ss-qt 的版本有很多问题十分难用。想着继续用其他 SS 的 win 客户端依然治标不治本,我把 shadowsocks-python 跑在了 Win10 的 WSL 里,感觉用起来比 win 客户端稳定很多…
注:kcp 的客户端也可以跑在 WSL 里,直接从 kcptun/release 下载 linux-amd64 版本的即可,具体用法见./client_linux_amd64 -h 的参数。

1
2
3
4
5
# start kcp
$ nohup /etc/client_linux_amd64 --localaddr ${KCP_LOCAL_ADDR} --remoteaddr ${KCP_SERVER_ADDR:KCP_SERVER_PORT} --key ${KCP_PASSWORD} --crypt none --mode fast3 --mtu 1350 --sndwnd 512 --rcvwnd 512 --datashard 10 --parityshard 3 --dscp 0 --quiet false >/dev/null 2>&1 &

# start ss(using kcp)
$ python /usr/local/lib/python2.7/dist-packages/shadowsocks/local.py -s 127.0.0.1 -p ${KCP_LOCAL_ADDR} -k ${SS-SERVER-PASSWORD} -b 0.0.0.0 -l ${SS-LOCAL-PORT} -m aes-256-cfb -t 600

注:其中 shadowsocks 的 - b 参数为 0.0.0.0, 表示允许来自局域网的连接 (注意关闭防火墙)。

这样就不需要读配置文件了,但注意各项参数都改为你自己的配置值。

IDA 的插件和配置

注:版本为 IDA 7.0 Pro
我的 IDA 配色插件 zyantific/IDASkins 和主题:ida_skin, 效果如下:

还有我编译的支持 IDA7.0 的 REhints/HexRaysCodeXplorer:ida7_HexRaysCodeXplorer.

IDA 安装 findcrypt

1
2
3
4
5
# 可能需要先更新pip
$ python -m pip install --upgrade pip

# 之后安装 yara-python
$ pip install yara-python

然后将 findcrypt-yara 仓库里的 findcrypt2.pyfindctypr3.rules 这两个文件放在进入 Ida/plugins 目录下,打开 IDA 即可在插件目录看到 findcrypt 了。

删除包含某些字符的行

在 Linux 下可以使用 sed 命令:

1
2
3
4
5
6
7
8
# 将abc.txt中所有含有"ABC"这个连续字符的行删除并写入到log.txt中
sed -e '/ABC/d/' abc.txt > log.txt
# 将自身所有含有"ABC"这个连续字符的行删除并保存
sed -i -e '/ABC/d' abc.txt

# 要删除的字符参数可以指定多个,只需要指定多个-e
# 将含有ABC和DEF的行都删除
sed -i -e '/ABC/d' -e '/DEF/d' abc.txt

其中 -e 的参数 ABC 也可以使用正则表达式来代替。

启用 Chrome 自动禁用的插件

通过运行 ->gepdit 进入组策略。
计算机配置 -> 管理模板右键选择添加/删除模板(A),导入 Chrome.adm
然后在管理模板下就会有经典管理模板(ADM),依次展开 Google->GoogleChrome-> 扩展程序;双击右侧配置扩展程序安装白名单,启用它并把我们想要启用的扩展程序的 ID (扩展程序 ID 可以从 Chrome-> 扩展程序中查看) 填入其中保存即可,重新打开 Chrome, 那个插件就可以启用了。

注:将 Cortana 的搜索默认使用 Chrome 以及 Google.
使 Cortana 默认使用 Google 作为搜索引擎的插件 CortanaUseGoogle.crx(需要使用上面的方式将该插件加入到扩展程序安装白名单中). 同时组合 EdgeDeflector 可以将 Cortana 使用的默认浏览器由 Edge 改为 Chrome.

VS 附加到进程的错误

今天使用 VS 的 Debug->Attach to process 产生了一个错误:

1
Unable to attach to the process.The Visual Studio 2017 remote Debugger(MSVCMON.EXE) does not appear to be running on the remote computer.This may be because a firewall is preventing communication to the remote computer.Please see Help for assistance on configuring remote debugging.

本来以为是 VS 的配置问题,后来才发现这是因为我在 Proxifier 中把电脑上的所有流量转发到了 SS,没想到 VS 的本地调试也是走网络的,流量通过代理之后一直连接不到本地计算机就会出现这个问题,全局代理需谨慎。

Separate memory location

[ISO/IEC 14882:2014 §1.7.5] A structure declared as:

1
2
3
4
5
6
7
8
struct {
char a;
int b:5,
c:11,
:0,
d:8;
struct {int ee:8;} e;
}

contains four separate memory locations: The field a and bit-fields d and e.ee are each separate memory locations, and can be modified concurrently without interfering with each other. The bit-fields b and c together constitute the fourth memory location. The bit-fields b and c cannot be concurrently modified, but b and a, for example, can be.

Linux 增加 SWAP 大小

有时候给虚拟机能够实际分配的内存大小不能满足于虚拟机的需求,可以扩大 SWAP 来临时解决,方法如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建1G大小的文件(/swap_file为指定存放该文件路径及名字)
$ sudo dd if=/dev/zero of=/swap_file bs=1M count=1024
# 改变创建的swap_file文件权限:
$ sudo chmod 600 /swap_file
# 使用mkswap设置上面创建的文件为SWAP文件
$ sudo mkswap /swap_file
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=f6286522-5b12-46d9-a4a3-ef151547841c
# 启用SWAP文件
$ sudo swapon /swap_file
# 在fstab文件中加入一条记录,开机时挂载该SWAP文件
$ sudo vim /etc/fstab
# 在/etc/fstab中加入下面一行内容
/swap_file swap swap defaults 0 0

Linux 静态 IP 设置

下面需要修改的文件路径为 /etc/network/interface.

1
2
3
4
5
6
7
8
9
10
11
# The loopback network interface
auto lo
iface lo inet loopback

# The primry network interface
auto eth0
# iface eth0 inet dhcp 为自动获取分配IP
iface eth0 inet static
address 192.168.2.111
netmask 255.255.255.0
geteway 192.168.2.1

一些 cmd 命令技巧

cmd 命令里是让他们同时执行几个命令:

1
2
start cmd.exe /c ""
start cmd.exe /c ""

在上面双引号内输入要执行的命令,保存为.bat; 运行时会同时打开两个命令行窗口。
cmd/c 的意思为执行完命令后关闭命令窗口;如果想要执行完不关闭可以使用 /k

cmd 中让命令在后台执行不会阻塞后续命令的方式 (类似于 linux 命令后加 &):

1
2
start /b cmd.exe /c ""
start /b cmd.exe /c ""

start 加入 /b,这两条命令就不会阻塞 (不会等到第一条命令执行完毕之后再执行第二条)。

.bat 后台执行,有些.bat 我们希望开机启动,这时候开机弹出黑框框就不太好,可以使用下面的.vbs 脚本来执行.bat

1
2
3
DIM objShell
set objShell=wscript.createObject("wscript.shell")
iReturn=objShell.Run("cmd.exe /C hideRuningBat.bat", 0, TRUE)