Deprecated: Creation of dynamic property Typecho\Widget\Request::$feed is deprecated in /www/wwwroot/blog.iletter.top/var/Widget/Archive.php on line 246
白荼日记 - DelLevin
http://blog.iletter.top/author/1/
DelLevin
-
MookNote:为记录而生
http://blog.iletter.top/archives/522/
2026-03-09T22:06:00+08:00
一款专注于个人记录的极简工具,让每一份感动与思考都有迹可循。在这个信息爆炸的时代,我们每天都在消费大量的内容——看一部电影、读一本书、产生一个灵感。然而,这些内容往往如流水般逝去,留下的只有模糊的记忆。MookNote 诞生于对简洁工具的追求。我相信,好的工具应该像纸笔一样自然,不打扰思考,只记录生活。它不应该有繁琐的注册流程,不应该将你的数据存储在陌生的服务器上,更不应该用花哨的功能分散你的注意力。我厌烦了一款软件让用户不断地注册来注册去,使用手机号验证来验证去,数据部不于自己,甚至自己写的笔记也不属于自己,我不喜欢这样,我想一款优秀的软件应该抛去繁杂的设计,就像太极一般的黑白两色。就像专业的人做专业的事情一样,MookNote主打记录生活一切有迹可循的影视娱乐,想法笔记。MookNote名字的由来也是让我冥思苦想,Mo取自Movie的前两个字母ok取自book的后两个字母,Note则名为笔记,名字就这么来了。影视,书籍,笔记的三项生活记录,因为热爱,所以记录,因为想法,所以书写。目前笔记还处于基础功能的版本,希望各位能多给我提提建议,我也会在其中做一些取舍,能与不能我都会一一记录下来的。在此,希望大家能多多帮助我这一个不知名的小开发者。最后的最后,感谢阿里千问的通义灵码,让我一个小小的java开发者接触到Android开发,帮了我的大忙,帮了我最纯真的梦想。下载地址:https://mooknote.iletter.top/#/
-
安卓模拟器无法连接网络问题
http://blog.iletter.top/archives/521/
2026-03-08T12:11:00+08:00
简短解释打开你安卓SDK的存放目录,然后找到emulator文件夹并进入打开终端调用emulator程序修改模拟器DNS配置 , 命令如下emulator -avd 模拟器名称 -dns-server 8.8.8.8 114.114.114.114如果你不知道模拟器名称可以使用下面命令emulator -list-avds步骤及命令1.打开终端键盘win+R,输入cmd2.切换到Android SDK目录下的emulator文件夹下cd 盘符:存放路径/sdk/emulator3.获取模拟器名称emulator -list-avds4.设置模拟器DNSemulator -avd 模拟器名称 -dns-server 8.8.8.8 114.114.114.114
-
immich搭建随笔docker-compose版
http://blog.iletter.top/archives/520/
2026-02-23T19:12:00+08:00
家里有一个二十年前的主机,自从改成服务器之后加装了好几块硬盘使用。今天心血来潮想装一下immich相册服务,结果抛弃了cpu满载了,更别说immich的机器学习了。所以改用了自己的macmini主机作为一个服务器使用。折腾了一天,也算是折腾好了,因为好多地方需要运行的时候下载模型文件,所以我选择下载好了,通过映射的方式挂载进去。docker-compose.ymlname: immich_server
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:v2
volumes:
- /Users/mac/Documents/docker/dockge/docker/stacks/immich/data:/data
- /Users/mac/Documents/docker/dockge/docker/stacks/immich/img:/img
- /etc/localtime:/etc/localtime:ro
environment:
- REDIS_HOSTNAME=
- REDIS_PORT=
- REDIS_PASSWORD=
- REDIS_DBINDEX=2
# 如果 Immich Server 本身还需要数据库连接信息(通常需要),请添加
- DB_HOSTNAME=database # 使用内部服务名
- DB_PORT=5432
- DB_USERNAME=
- DB_PASSWORD=
- DB_DATABASE_NAME=
ports:
- 2283:2283
depends_on:
- database
restart: always
healthcheck:
disable: false
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:v2
volumes:
- model-cache:/cache
# 将你存放模型的目录挂载到容器的 /cache/clip
- /Users/mac/Documents/docker/dockge/docker/stacks/immich/ViT-B-32__openai:/cache/clip/ViT-B-32__openai
- /Users/mac/Documents/docker/dockge/docker/stacks/immich/XLM-Roberta-Large-Vit-B-16Plus:/cache/clip/XLM-Roberta-Large-Vit-B-16Plus
- /Users/mac/Documents/docker/dockge/docker/stacks/immich/facial-recognition:/cache/facial-recognition
environment:
- REDIS_HOSTNAME=
- REDIS_PORT=
- REDIS_PASSWORD=
- REDIS_DBINDEX=2
# 如果 ML 服务也需要数据库连接信息,请添加
- DB_HOSTNAME=database
- DB_PORT=5432
- DB_USERNAME=
- DB_PASSWORD=
- DB_DATABASE_NAME=
restart: always
healthcheck:
disable: false
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23
environment:
POSTGRES_PASSWORD:
POSTGRES_USER:
POSTGRES_DB:
POSTGRES_INITDB_ARGS: --data-checksums
volumes:
- /Users/mac/Documents/docker/dockge/docker/stacks/immich/db:/var/lib/postgresql/data
shm_size: 128mb
restart: always
healthcheck:
disable: false
volumes:
model-cache: null
networks: {}
服务详解 (Services)immich-server (主服务器)作用: 这是 Immich 的核心应用服务器,处理所有主要逻辑,如 API 请求、用户界面、照片上传/下载等。镜像: ghcr.io/immich-app/immich-server:v2 - 拉取并使用 Immich 官方 v2 版本的服务器镜像。卷 (Volumes):/Users/mac/.../data:/data: 将宿主机上的 /Users/mac/.../data 目录挂载到容器内的 /data 路径,用于存储用户上传的原始媒体文件。/Users/mac/.../img:/img: 将宿主机上的 /Users/mac/.../img 目录挂载到容器内的 /img 路径,这里是用于机器学习使用的(如缩略图)。/etc/localtime:/etc/localtime:ro: 将宿主机的本地时间文件挂载到容器内,并设置为只读 (ro),确保容器内的时间与宿主机同步。环境变量 (Environment):REDIS_*: 配置服务器如何连接到外部的 Redis 服务DB_*: 配置服务器如何连接到内部的 PostgreSQL 数据库(服务名为 database,端口 5432,用户名/密码/数据库名均为 postgres/postgres/immich)。数据库存储元数据、用户信息等。端口 (Ports): - 2283:2283 - 将宿主机的 2283 端口映射到容器的 2283 端口。这意味着您可以通过 http://localhost:2283 访问 Immich 的 Web 界面。依赖 (depends_on): depends_on: [database] - 确保在启动 immich-server 之前,database 服务必须先启动并运行。重启策略 (restart): always - 无论退出状态如何,Docker 总是尝试重启该容器。健康检查 (healthcheck): disable: false - 启用默认的健康检查机制,以监控容器是否正常运行。immich-machine-learning (机器学习服务)作用: 负责执行图像分析任务,如人脸识别、物体识别、场景分类等。这些任务基于预先训练好的 AI 模型。镜像: ghcr.io/immich-app/immich-machine-learning:v2 - Immich 官方的 v2 版本机器学习服务镜像。卷 (Volumes):model-cache:/cache: 挂载一个名为 model-cache 的命名卷到容器的 /cache 路径,用于存放模型文件。接下来的三行将宿主机上特定的模型文件夹直接挂载到容器内的对应路径:ViT-B-32__openai: CLIP 模型,用于图像和文本匹配。XLM-Roberta-Large-Vit-B-16Plus: 另一个 CLIP 模型,支持多语言。facial-recognition: 人脸识别模型。环境变量 (Environment): 与 immich-server 类似,配置了相同的 Redis 和数据库连接信息,以便它能与主服务和数据库交互。database (PostgreSQL 数据库)作用: 存储 Immich 的所有非媒体数据,如用户账户、相册信息、文件元数据、人脸识别结果等。镜像: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:... - 这是一个经过特殊定制的 PostgreSQL 14 镜像,内置了 vectorchord 和 pgvectors 扩展,专门用于高效处理向量相似性搜索(这是 AI 图像分析功能的关键)。环境变量 (Environment): 设置了数据库的超级用户密码、用户名和默认数据库名。卷 (Volumes): - /Users/mac/.../db:/var/lib/postgresql/data - 持久化数据库文件到宿主机,防止容器删除后数据丢失。共享内存 (shm_size): 设置为 128mb,为数据库提供必要的共享内存空间,提升性能。重启策略 & 健康检查: 同样设置了 always 重启和启用健康检查。卷 (Volumes)model-cache: 这是一个命名卷 (named volume)。它不直接映射到宿主机的特定路径,而是由 Docker 在其管理的目录下创建和维护。在这里,它主要用于给机器学习服务提供一个持久化的空间来缓存模型或中间计算结果,保证容器重启后模型数据依然可用。网络 (Networks)networks: {}: 这里没有显式定义任何网络。Docker 会自动为这个 immich_server 项目创建一个默认的桥接网络 (bridge network)。immich-server 和 immich-machine-learning 通过 DB_HOSTNAME=database 这个环境变量,利用 Docker 的内部 DNS 功能,可以直接通过服务名 database 在这个默认网络上找到并连接到 immich_postgres 容器。总结: 这个 docker-compose.yml 文件定义了一个完整的 Immich 运行环境,包含一个 Web 服务器、一个机器学习分析服务和一个专用的 PostgreSQL 数据库。它通过卷实现了数据持久化,并通过环境变量配置了各组件间的连接信息。
-
Win11打开文件夹显示找不到应用程序
http://blog.iletter.top/archives/519/
2026-01-04T14:05:00+08:00
按【 Win + R 】组合键,打开运行,输入【regedit】命令,按【确定或回车】打开注册表编辑器;注册表编辑器窗口,依次展开到以下路径:HKEY_CLASSES_ROOT\Folder\shell在【Shell】下通常默认有下图几项,如果有其它第三方软件命名项,我们可以【右键删除】;左侧列表中,点击【shell】,在右侧双击名称为【默认】的项;将数值数据【清空】,最后点击【确定】;以上设置完成后,重启电脑再看是否正常。
-
linux服务器实现webdav挂载
http://blog.iletter.top/archives/518/
2025-12-30T14:35:53+08:00
使用 davfs2 (推荐用于标准WebDAV)安装 davfs2在 Debian/Ubuntu:sudo apt update && sudo apt install davfs2在 CentOS/RHEL (可能需要EPEL源):sudo yum install davfs2创建挂载点sudo mkdir /home/dellevin/zhang/jellyfin/media/webdav/g3配置 davfs2 凭证编辑 /etc/davfs2/secrets 文件,添加一行:/home/dellevin/zhang/jellyfin/media/webdav/g3 webdav账户 webdav密码设置文件权限:sudo chmod 600 /etc/davfs2/secrets挂载 WebDAVsudo mount -t davfs http://webdav地址/path /home/dellevin/zhang/jellyfin/media/webdav/g3卸载sudo umount /home/dellevin/zhang/jellyfin/media/webdav/g3
-
碎片化时代构筑的一个碎片的人
http://blog.iletter.top/archives/517/
2025-12-27T00:03:00+08:00
碎片化时代构筑的一个碎片的人我有一个习惯,就是喜好回顾自己的曾经。虽然我对我的同学和好友常说“人生本就应该往前看,一直回头,永远不会长大。”可是真到自己的头上我却是做不到。曾经的我喜好写日记,随笔,虽然烂的不行,但是每当我回顾的时候,不管当时是喜是忧。那份曾经用自己残缺的文笔封印住的悸动,在回顾的时候总会有些松动。自从工作以后,日记随笔的频率越来越低的,多的反倒是工作的日志。我就像是丢失了近两年的记忆一般,在今晚回顾的时候竟然空无一物,望着空荡荡的日记,我不禁一次又一次的问自己,我到底是谁?在这个碎片化的时代,信息爆炸的初期,良莠不齐的信息大批量的涌入我们的视野。我们看着,嬉笑着,怒骂着,感叹着,然后继续面无表情的获取下一条信息,这些残缺无比的信息构筑了一个个残缺无比的人。一碰就碎。贫瘠的知识,片面的视野还有一个麻木的青年。我不禁一次又一次的问自己,“你愿做一位痛苦的苏格拉底还是一只快乐的猪?”。我一遍又一遍的告诉自己,“我要做一位痛苦的苏格拉底”。可是这样真的好累啊。这两年我的生活如同“一只快乐的猪”,可是这真的是我自己吗?我也不知道了。或许我不应该上学的。我应该像村里的其他人一样,辍学,外出打工,最后遇见一位女生,结婚生子,然后慢慢的老去,结束自己的一生。谁能告诉我,人生到底是什么?
-
宝塔面板V11.4精简去除vip以及其他推广功能
http://blog.iletter.top/archives/516/
2025-12-21T22:57:03+08:00
该操作仅适用于宝塔面板 V11.4,其他版本需要自行测试。功能隐藏:关闭不必要的功能设置->常用设置->面板栏隐藏,隐藏如下功能WAF、WP Tools、多用户、邮局、节点管理不想用,隐藏就行了。去除首页的软件推荐功能。一开始我本以为这个是在utils-lib.js里面带着的,后来通过减慢请求查看到是在请求里面带着的。通过搜索关键词get_pay_type发现,是通过getRecommendContent这个请求函数带过来的。所以我们需要在这里设置返还值为空即将getRecommendContent=()=>useAxios.post("ajax/get_pay_type")替换成getRecommendContent=()=>{return []}去除日志部分的 SSH 登录日志删掉如下部分{path:"ssh",name:"ssh",meta:{title:"SSH登录日志"},component:()=>__vitePreload(()=>import("./index57.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},去除 SSL 部分的 自动部署删掉如下部分{path:"auto-deploy",name:"auto-deploy",meta:{title:"自动部署"},component:()=>__vitePreload(()=>import("./index89.js?v=1766131796").then(e=>e.i),__vite__mapDeps([]),import.meta.url)},去除 安全部分的 安全检测和违规词检测删掉如下部分{path:"safe-detect",name:"safe-detect",meta:{title:"安全检测"},component:()=>__vitePreload(()=>import("./index46.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},{path:"keyword",name:"keyword",meta:{title:"违规词检测"},component:()=>__vitePreload(()=>import("./index47.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},去除 PHP网站安全 入侵防御 系统加固 扫描感知 部分删掉如下部分,{path:"php-safe",name:"php-safe",meta:{title:"PHP网站安全"},component:()=>__vitePreload(()=>import("./index48.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},{path:"intrusion",name:"intrusion",meta:{title:"入侵防御"},component:()=>__vitePreload(()=>import("./index49.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},{path:"fixed",name:"fixed",meta:{title:"系统加固"},component:()=>__vitePreload(()=>import("./index50.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},{path:"network-scan",name:"network-scan",meta:{title:"扫描感知"},component:()=>__vitePreload(()=>import("./index51.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)}去除网站界面 的漏洞扫描 和 网站安全找到 index74.js漏洞扫描删除如下部分{type:"custom",render:()=>w(P,{onClick:ee},{default:()=>{var e,t;return[S("漏洞扫描"),w("span",{class:"ml-4px py-1px px-4px text-center font-bold ".concat((null==(e=Se.value)?void 0:e.loophole_num)>0?"text-danger":"text-warning")},[null==(t=Se.value)?void 0:t.loophole_num])]}})},网站安全删除如下部分,{type:"custom",render:()=>w(P,{onClick:te},{default:()=>{var e,t;return[S("网站安全"),w("span",{class:"ml-4px py-1px px-4px text-center font-bold ".concat((null==(e=Se.value)?void 0:e.web_scaning_times)>0?"text-danger":"text-warning")},[null==(t=Se.value)?void 0:t.web_scaning_times])]}})}去除 table 表格的右侧的统计和 waf{onClick:e=>{le(e,"monitor-setting")},title:"统计"},{onClick:e=>{le(e,"bt_waf")},title:"WAF"},去除网站安全和防篡改找到 index235.js删除该部分{label:"防篡改",name:"antiTamper",lazy:!0,render:()=>r(()=>import("./index463.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},{label:"网站安全",lazy:!0,name:"siteSecurity",render:()=>r(()=>import("./index464.js?v=1766131796"),__vite__mapDeps([]),import.meta.url)},Css隐藏:主要路径为/www/server/panel/BTPanel/static/css/style.css 一下更改需要在此文件内进行调整,如需更改其他部分会另作说明去除顶部的企业版tag.icon-end-time-free[data-v-402b09ab]{ 后面添加 display:none;软件商店的推广 banner.recom-view[data-v-81e888c5]{ 后面添加 display:none去除底部的vip推广找到如下路径的/www/server/panel/BTPanel/static/css里面的style.css搜索advantage-view吧这里面的display:flex改成display:none去除网站里面的 waf 图标.svgtofont-left-waf:before{content:""} 替换成 .svgtofont-left-waf:before{dispaly:none;content:""}
-
笔记本断电后自动关机python命令
http://blog.iletter.top/archives/503/
2025-12-16T10:46:00+08:00
自己的笔记本被自己改成了win server服务器,外加来电自启+小爱同学控制开关机,可以说很好了,但是笔记本却没有断电自动关机这个东西,原本想把电池扣了,换上usp的,但是有一点成本在的,果断放弃。后来更改电源计划,99%的时候进行关机,但是盖上盖子,断开远程的时候,睡眠状态了就,不会进行关机操作。索性写了这个python代码import sys
import win32api
import win32gui
import win32con
import pythoncom
import psutil
import threading
import time
import subprocess
SHUTDOWN_DELAY_SECONDS = 60
class PowerListenerWindow:
def __init__(self):
self.is_plugged_in = True # 初始假设为连接电源
self.shutdown_timer = None
self.last_unplugged_time = None
wc = win32gui.WNDCLASS()
wc.lpfnWndProc = self.wnd_proc
wc.lpszClassName = 'MyPowerListenerClass'
wc.hInstance = win32api.GetModuleHandle(None)
class_atom = win32gui.RegisterClass(wc)
# Create a hidden window
self.hwnd = win32gui.CreateWindow(
class_atom,
'PowerListener',
0, 0, 0, 0, 0,
0, 0, wc.hInstance, None
)
def wnd_proc(self, hwnd, msg, wparam, lparam):
if msg == win32con.WM_POWERBROADCAST:
if wparam == win32con.PBT_APMPOWERSTATUSCHANGE:
# print("[WM_POWERBROADCAST] 电源状态可能已更改 (PBT_APMPOWERSTATUSCHANGE)") # 简化日志
self.check_and_print_status() # 调用更新后的检查函数
elif wparam == win32con.PBT_ACPIRESUMEAUTOMATIC or wparam == win32con.PBT_ACPIRESUMESUSPEND:
# print(f"[WM_POWERBROADCAST] 系统从睡眠/休眠恢复 (wParam={wparam})") # 简化日志
pass # 可根据需要添加恢复逻辑
elif wparam == win32con.PBT_APMSUSPEND:
# print("[WM_POWERBROADCAST] 系统即将进入睡眠/休眠 (PBT_APMSUSPEND)") # 简化日志
pass # 可根据需要添加休眠前逻辑
return win32gui.DefWindowProc(hwnd, msg, wparam, lparam)
def cancel_pending_shutdown(self):
"""取消任何待定的关机操作"""
if self.shutdown_timer and self.shutdown_timer.is_alive():
self.shutdown_timer.cancel()
self.shutdown_timer = None
def schedule_shutdown(self):
"""在指定延迟后执行关机"""
print(f"警告:设备未充电,将在 {SHUTDOWN_DELAY_SECONDS} 秒后关机!")
self.execute_shutdown()
def execute_shutdown(self):
"""实际执行关机操作"""
# 再次确认是否仍然未充电,避免在检查间隙插上了电源
try:
battery_check = psutil.sensors_battery()
if battery_check and not battery_check.power_plugged:
print("--- 执行关机 ---")
# 使用 subprocess 调用 Windows 关机命令
# /s 关机, /t 5 延迟5秒, /c 添加消息
subprocess.run(["shutdown", "/s", "/t", "5", "/c", "Battery low and not charging. Shutting down in 5 seconds..."], check=True)
# 等待一下,让关机命令生效
time.sleep(10)
sys.exit(0) # 正常退出监听器
else:
print("--- 电源状态已恢复,取消关机 ---")
except psutil.Error as e:
print(f"查询电源状态失败: {e}")
# 查询失败,出于安全考虑,可以选择不关机或记录日志
except subprocess.CalledProcessError as e:
print(f"执行关机命令失败: {e}")
except Exception as e:
print(f"执行关机时发生未知错误: {e}")
def check_and_print_status(self):
"""Helper function to query and print current status and manage shutdown timer"""
try:
battery = psutil.sensors_battery()
was_plugged_in = self.is_plugged_in # 记录之前的状态
if battery:
self.is_plugged_in = battery.power_plugged
# 简化状态打印,仅在状态变化时提示
# plugged_status_str = "已充电/接入电源" if self.is_plugged_in else "未在充电"
# print(f"当前电源状态: {plugged_status_str}, 电量: {battery.percent}%")
if not self.is_plugged_in:
# 检测到未充电
if was_plugged_in or self.shutdown_timer is None:
# 如果之前是充电的,或者是第一次检测到未充电且无定时器
print(f"提示:笔记本电脑当前未在充电! 电量: {battery.percent}%. 将在 {SHUTDOWN_DELAY_SECONDS} 秒后关机.")
self.cancel_pending_shutdown() # 先取消旧的(理论上不应该有)
# 启动新的 60 秒关机定时器
self.shutdown_timer = threading.Timer(SHUTDOWN_DELAY_SECONDS, self.schedule_shutdown)
self.shutdown_timer.start()
# else: 已经在倒计时中,无需重复启动
else:
# 检测到已充电
if not was_plugged_in: # 如果之前是未充电的
print("提示:电源已连接,取消关机计划。")
# 取消任何待定的关机
self.cancel_pending_shutdown()
else:
# print("无法获取电池信息,可能不是笔记本电脑或传感器不可用。") # 简化日志
self.is_plugged_in = True # 默认为连接(安全起见)
self.cancel_pending_shutdown() # 取消关机
except Exception as e:
print(f"查询电源状态时出错: {e}")
# 出错时也应取消关机以防万一
self.cancel_pending_shutdown()
def start_message_loop(self):
print("Windows 电源监听器已启动...")
print("请插拔电源测试功能。按 Ctrl+C 退出。")
# 初始检查一次状态
self.check_and_print_status()
try:
while True:
pythoncom.PumpWaitingMessages()
win32api.Sleep(5000) # 每5秒处理一次消息队列
except KeyboardInterrupt:
print("\n收到退出指令,正在关闭...")
finally:
self.cancel_pending_shutdown() # 确保退出时取消定时器
win32gui.DestroyWindow(self.hwnd)
print("监听器已关闭。")
# 编译
# pyinstaller --noconfirm --onefile --hidden-import=win32timezone powerOffShutDown.py
if __name__ == "__main__":
listener = PowerListenerWindow()
listener.start_message_loop()
-
将bat脚本设置成windows服务
http://blog.iletter.top/archives/502/
2025-12-02T13:46:29+08:00
步骤 1: 下载 NSSM访问 NSSM 官方网站:http://nssm.cc/download下载适用于你系统架构(通常是 64-bit x64)的最新版本。解压下载的 ZIP 文件。你会得到一个包含 nssm.exe 的文件夹(例如 win64 文件夹里有 nssm.exe)。步骤 2: 将 NSSM 添加到系统 PATH为了在任何地方都能使用 nssm 命令,建议将其路径添加到系统的环境变量 PATH 中。打开“控制面板” -> “系统和安全” -> “系统” -> “高级系统设置”。点击“环境变量”。在“系统变量”或“用户变量”中找到 Path,选中它并点击“编辑”。点击“新建”,然后粘贴你解压出来的 nssm.exe 所在的完整目录路径(例如 D:\tools\nssm-2.24\win64)。 请务必将路径修改为你实际解压的路径。点击“确定”保存所有更改。关闭并重新打开命令提示符窗口,以使 PATH 变更生效。步骤 3: 使用 NSSM 创建服务以管理员身份 打开命令提示符 (CMD) 或 PowerShell。输入以下命令来启动 NSSM 的图形安装界面:nssm install frp_client_service(frp_client_service 是你将要创建的服务名称,你可以根据需要修改,但不能包含空格)。在弹出的 NSSM 配置窗口中:Path: 浏览并选择你的 start.bat 文件路径:D:\appStable\frp-client\start.bat。Startup directory: 自动填充为 .bat 文件所在的目录,即 D:\appStable\frp-client。请确认此目录正确。这是程序运行时的工作目录。Arguments: 如果你的 start.bat 脚本需要额外的命令行参数,可以在这里填写。通常 .bat 文件不需要在此处添加参数。其他选项卡(如 Details, Log on, Dependencies, Process, Shutdown, Exit actions, I/O Priority)可以根据需要进行配置,但对于大多数情况,默认设置即可。Details: 可以给服务起个易读的显示名称(Display name),比如 "FRP Client",以及描述(Description)。Log on: 默认是使用本地系统账户,通常足够了。I/O Priority: 如果担心性能,可以将优先级设为 Normal。确认所有信息无误后,点击 Install service 按钮。步骤 4: 启动并测试服务可以通过 NSSM GUI 来管理服务:nssm edit frp_client_service # 编辑服务
nssm start frp_client_service # 启动服务
nssm stop frp_client_service # 停止服务
nssm remove frp_client_service # 删除服务或者使用 Windows 内置的 服务管理器:按 Win + R 键,输入 services.msc 并回车。在服务列表中找到你刚刚创建的服务(名称是你在 NSSM 中指定的 Display name 或服务名 frp_client_service)。右键单击该服务,选择“启动”。检查状态是否变为“正在运行”。步骤 5: 设置开机自启在 Windows 的 服务管理器 (services.msc) 中,找到你的 frp_client_service 服务。右键单击该服务,选择“属性”。在“常规”选项卡下,将“启动类型”设置为 自动。点击“应用”和“确定”。现在,这个 FRP 客户端就会作为 Windows 服务运行,并且在系统开机时自动启动了。
-
pycharm远程开发
http://blog.iletter.top/archives/501/
2025-11-06T22:18:00+08:00
首先创建新的ssh项目填写相关参数这里需要上传linux的安装包,因为下载的话一直失败无法下载成功,我们选择上传和上传路径pycharm地址:https://www.jetbrains.com/zh-cn/pycharm/download/other.html破解文件下载地址:ja-netfilter-2025.3.0.zip弄完之后,会让你填写远程pycharm的验证,在这之前退出一下我们需要填写编辑一下文件vim pycharm64.vmoptions里面填写关于破解文件的相关信息-Xms256m
-Xmx2048m
-XX:ReservedCodeCacheSize=512m
-XX:+UseG1GC
-XX:SoftRefLRUPolicyMSPerMB=50
-XX:CICompilerCount=2
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-XX:+IgnoreUnrecognizedVMOptions
-XX:CompileCommand=exclude,com/intellij/openapi/vfs/impl/FilePartNodeRoot,trieDescend
-ea
-Dsun.io.useCanonCaches=false
-Dsun.java2d.metal=true
-Djbr.catch.SIGABRT=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-Djdk.attach.allowAttachSelf=true
-Djdk.module.illegalAccess.silent=true
-Dkotlinx.coroutines.debug=off
-Dide.show.tips.on.startup.default.value=false
-Dsun.tools.attach.tmp.only=true
-Dawt.lock.fair=true
-javaagent:/root/ja-netfilter/ja-netfilter.jar
--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED
之后再次打开pycharm远程,填写激活码6ZLWI4KV9Y-eyJsaWNlbnNlSWQiOiI2WkxXSTRLVjlZIiwibGljZW5zZWVOYW1lIjoi5rC45LmF5r+A5rS7IHd3d8K3YWppaHVvwrdjb20iLCJsaWNlbnNlZVR5cGUiOiJQRVJTT05BTCIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IkdPIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUzAiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRNIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJDTCIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlNVIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0MiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRTIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSRCIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJTRiIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJEQlIiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJNIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJJSSIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiRFBOIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEQiIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiREMiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUiIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlNWIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IldTIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJQU0kiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUENXTVAiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiQUlMIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUyIsInBhaWRVcFRvIjoiMjAyNS0xMS0yMyIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQUlIiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiRFAiLCJwYWlkVXBUbyI6IjIwMjUtMTEtMjMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUERCIiwicGFpZFVwVG8iOiIyMDI1LTExLTIzIiwiZXh0ZW5kZWQiOnRydWV9XSwibWV0YWRhdGEiOiIwNDIwMjUxMDI0UFBBTTAwMDAwNUEwMDAwMDBYQyIsImhhc2giOiI3NTkxODgyNy8wOjEzODU1MTE2NSIsImdyYWNlUGVyaW9kRGF5cyI6NywiYXV0b1Byb2xvbmdhdGVkIjpmYWxzZSwiaXNBdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJ0cmlhbCI6ZmFsc2UsImFpQWxsb3dlZCI6dHJ1ZX0=-jEJB+XsDL603fDEvkpWiZmuv+g4j7nLQ2jwzghoDP8KuxfCXLPG6LFK4C00mUzUX23i+T9XB9hAp83icdF+YuVESTTbPPxLQVCzk2uIskO8s/g4BZacTQD5IsHVDjRmv5HWtuakqNVUzbatF+yc0ut58PfrPsnKMrp1yFBQEvw3Ch1gghbm85UsTQ4zW2C05QSQDrLSlQB4M/cZ6OTI22NtPSrfJxyfdUhVEnQQqO6uQqrqa7CX8ZuC+ZKsap4tnaXmHG4hfUlZdO7PTlZfV20n9mtJxZSftqZUgeJzreporG7C2bX1mIDlkAECzkMU5gmJzlUQ6499xz2O2Upx7Wg==-MIIETDCCAjSgAwIBAgIBETANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTI0MDkyMDEyMTEyN1oXDTI2MDkyMjEyMTEyN1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyNDA5MjAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7SH/XcUoMwkDi8JJPzXWWHWFdOZdrP2Dqkz2W8iUi650cwz2vdPEd0tMzosLAj7ifkFEHUyiuEcL//q9d9Op7ZsV23lpPXX8tFMLFwugoQ9D8jDLT/XP9pp/YukWkKF5jpNbaCvsVQkDdYkArBkYvhH3aN4v9BkEsXahfgLLOPe4IG2FDJNf9R4to9V1vt+m2UVJB0zV4a/sVMKUZLgqKmKKKOKoLrE3OjBlZlb+Q0z2N5dsW0hDEVRFGmBUAbHN/mp44MMMvEIFKfoLIGpgic92P2O6uFh75PI7mcultL6yuR48ajErx8CjjQEGOSnoq/8hD+yVE+6GW2gJa2CPvAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUb5NERj05GyNerQ/Mjm9XH8HXtLIwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBALq6VfVUjmPI3N/w0RYoPGFYUieCfRO0zVvD1VYHDWsN3F9buVsdudhxEsUb8t7qZPkDKTOB6DB+apgt2ZdKwok8S0pwifwLfjHAhO3b+LUQaz/VmKQW8gTOS5kTVcpM0BY7UPF8cRBqxMsdUfm5ejYk93lBRPBAqntznDY+DNc9aXOldFiACyutB1/AIh7ikUYPbpEIPZirPdAahroVvfp2tr4BHgCrk9z0dVi0tk8AHE5t7Vk4OOaQRJzy3lST4Vv6Mc0+0z8lNa+Sc3SVL8CrRtnTAs7YpD4fpI5AFDtchNrgFalX+BZ9GLu4FDsshVI4neqV5Jd5zwWPnwRuKLxsCO/PB6wiBKzdapQBG+P9z74dQ0junol+tqxd7vUV/MFsR3VwVMTndyapIS+fMoe+ZR5g+y44R8C7fXyVE/geg+JXQKvRwS0C5UpnS5FcGk+61b0e4U7pwO20RlwhEFHLSaP61p2TaVGo/TQtT/fWmrtV+HegAv9P3X3Se+xIVtJzQsk8QrB/w52IB3FKiAKl/KRn1egbMIs4uoNAkqNZ9Ih2P1NpiQnONFmkiAgeynJ+0FPykKdJQbV3Mx44jkaHIif4aFReTsYX1WUBNu/QerZRjn4FVSHRaZPSR5Oi82Wz0Nj7IY9ocTpLnXFrqkb/Kt3S6B9s2Kol3Lr1ElYA这一步可能会提示This license xxxx has been suspended可以设置一下代理就可以了