<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>技术向 - 幻愿Recovery 的小站</title>
	<atom:link href="https://blog.eachother.work/category/teko/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.eachother.work</link>
	<description>只是那生命的大雨纷飞， 总不济于这片虚幻到不真实的万里晴空就是了。</description>
	<lastBuildDate>Thu, 19 Mar 2026 05:14:45 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.eachother.work/wp-content/uploads/2024/02/wp-1706767904876-150x150.png</url>
	<title>技术向 - 幻愿Recovery 的小站</title>
	<link>https://blog.eachother.work</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【折腾笔记, 教学向】关于在高iOS、iPadOS系统版本下顺利运行KRKR引擎的实践记录【解决闪退、文件管理困难】</title>
		<link>https://blog.eachother.work/ios-sideload-krkr/</link>
					<comments>https://blog.eachother.work/ios-sideload-krkr/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Wed, 18 Mar 2026 16:27:05 +0000</pubDate>
				<category><![CDATA[想法集]]></category>
		<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">https://blog.eachother.work/?p=299</guid>

					<description><![CDATA[本文遵循 &#160;CC-BY-NC-SA知识共享协议&#160; 。转载请保留原作者署名（幻愿Recove [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>本文遵循 &nbsp;<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.zh-hans" target="_blank" rel="noreferrer noopener">CC-BY-NC-SA知识共享协议</a>&nbsp; 。<br>转载请保留原作者署名（幻愿Recovery），禁作商业用途。<br>本文计划在 幻愿Recovery的哔哩哔哩专栏 、 幻愿Recovery的小站 和 相互科技工作室·博客站点 进行发布，除此之外任何标明作者为幻愿Recovery或未标明出处的转载均为侵权行为。<br>本文所提供的方法、研究思路、最终效果均为学习和交流目的，如有侵权，请通过页面提供的联系方式联系作者，我们会尽快删除。另外，鉴于这只是让一个异常软件恢复正常运行的方案，本作者不对任何（包含非正常使用的行为）后果承担责任。<br>本文中涉及敏感技术问题的部分还请自行询问和研究，我们不提供任何形式的资源分享，也不接受方法失效后的后果。</p>



<h1 class="wp-block-heading">0x00 背景&amp;成果介绍</h1>



<p>最近探究了 <a href="https://mp.weixin.qq.com/s/4qZKNIWcBndMS1pvIyc8Cw" target="_blank" rel="noreferrer noopener">这篇文章</a> （原文链接： <a href="https://mp.weixin.qq.com/s/4qZKNIWcBndMS1pvIyc8Cw" target="_blank" rel="noreferrer noopener">https://mp.weixin.qq.com/s/4qZKNIWcBndMS1pvIyc8Cw</a> ），文中通过iLoader侧载工具，在iOS平台上侧载SideStore和LiveCotainer。再通过快捷指令自动化（好熟悉www这是我玩过好几年的东西）来实现自动续签。这样，在不越狱、不碰代码、不进行任何破坏性或不可逆性操作的前提下，iOS系统也可以像Android系统一样侧载安装任意兼容的ipa软件包。说人话就是，软件安装可以不用通过AppStore了，你只要有安装包，就可以直接像安卓手机一样一键安装。<br>本文也会探讨这部分步骤，以及个人实践过程中发现的一些坑，帮助大家也能正常安装和使用这一整套侧载方案。<br>不过，这次实践带来的一个很有趣的成果就是，可以通过简单的方法来复活Krkr的iOS版本，抑或者称作Xp3player，iOS版本的Krkr模拟器，从而使得iOS/iPadOS设备重新获得Krkr引擎GalGame的运行能力。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/5k2xA" alt=""/></figure>



<h4 class="wp-block-heading"><mark>解决问题的背景</mark></h4>



<p><strong>自从iOS 16以来，AppStore上架的Xp3Player就丧失了GalGame的游玩能力，因为在高版本的系统下，弹出窗口的API逻辑似乎需要修改，当游戏遇到“保存进度”“读取进度”等提示框时，Xp3Player均会直接闪退。</strong><br>此外，即使是低版本iOS用户，Xp3Player近50元的售价也让不少的玩家望而却步，而且由于上架作者长期不活跃，Krkr引擎也长期不更新，出现了许多兼容性问题；加之Xp3Player的文件管理模式本来就及其不友好，本教程希望通过上述全新的方式解决这个问题。</p>



<h1 class="wp-block-heading">0x01 原料</h1>



<p>要完成操作，你需要准备：</p>



<ul class="wp-block-list">
<li>你的iPhone/iPad。</li>



<li>一台电脑，这只需要用到一次，后续包括GalGame文件管理在内的所有操作都不再需要电脑（除非你的续签失效、方法失效或者你主动删除了相关程序）。</li>



<li>一条数据线，同电脑，这通常也只需要一次。</li>



<li>稳定的互联网连接（最好有可靠的代 理连接，否则初次运行很可能失败）。</li>



<li>Apple ID，最好是外区账号，我们需要安装一个外区应用程序来允许自动签名。</li>



<li>一定的互联网、英语能力（会用翻译工具也可以）、技术常识和认知。这些操作不是特别难，但是如果弄不明白什么是后缀名，什么是解压，什么是IP地址，那么建议先去补习相关知识，否则可能会很吃力或者造成失败。</li>



<li>理性的思维、冷静分析的能力、读懂文字并照做的能力、一双手。<br>有关互联网代理和外区Apple ID，恕我不能详细告知解决方案，你可以自己探索，这些属于基础建设，不在本笔记范畴之内。相信你可以自行低成本搞定。</li>
</ul>



<h1 class="wp-block-heading">0x02 软件准备</h1>



<h3 class="wp-block-heading">电脑端</h3>



<p>此处以Windows系统电脑为例。<br>你需要安装 <a href="https://www.apple.com/itunes/" target="_blank" rel="noreferrer noopener">iTunes</a> （ <a href="https://www.apple.com/itunes/" target="_blank" rel="noreferrer noopener">https://www.apple.com/itunes/</a> ）或 <a href="https://www.i4.cn/" target="_blank" rel="noreferrer noopener">爱思助手</a> （ <a href="https://www.i4.cn/" target="_blank" rel="noreferrer noopener">https://www.i4.cn/</a> ）。<br>这是因为如果想要连接iOS设备，必须安装Apple官方提供的驱动程序。使用这两个工具来补全驱动非常简单。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/5kF7P" alt=""/></figure>



<p><br>需要安装 <a href="https://github.com/nab138/iloader/releases/tag/v2.0.6" target="_blank" rel="noreferrer noopener">iLoader</a> （ <a href="https://github.com/nab138/iloader/releases/tag/v2.0.6" target="_blank" rel="noreferrer noopener">https://github.com/nab138/iloader/releases/tag/v2.0.6</a> ）这一程序来在iOS设备上侧载两个应用程序。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/5kJo4" alt=""/></figure>



<p><br>需要一个代理工具，用于通过局域网来给iOS设备提供全局代理环境，这一点我们后面会说。这里我们用紫色的小猫来做演示。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/5kOtS" alt=""/></figure>



<h3 class="wp-block-heading">iOS设备端</h3>



<p>登录美区Apple ID，没有的话可以去购买或者租用他人的账号。<br>安装LocalDevVPN软件。这个程序不提供任何互联网限制解除功能，仅用于提供临时的验证环境。<br>此外，需要“文件”和“快捷指令”两个苹果官方的应用程序。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/5kVhh" alt=""/></figure>



<h1 class="wp-block-heading">0x03 搭建侧载环境</h1>



<ol class="wp-block-list">
<li>关闭iOS设备的“无线热点”功能。 确保Windows电脑和iOS设备在同一个局域网环境下（如果你的路由器开启了AP隔离，不能连接局域网内设备，那可以使用Windows 10/11自带的“移动热点”功能，将iOS设备连接到Windows电脑的热点内，此时Windows电脑的地址是192.168.137.1）。</li>



<li><strong>开启iOS设备的“开发者模式”。</strong> 打开“设置”，进入“隐私与安全”>“开发者模式”，打开开发者模式的开关，此时设备应该会重启以应用更改。<img fetchpriority="high" decoding="async" width="800" height="450" class="wp-image-300" style="width: 800px;" src="https://t.tutu.to/img/5ko6Q" alt=""></li>



<li><strong>连接设备。</strong> 将iOS设备使用数据线连接到Windows电脑。iOS设备端需要信任计算机，并输入系统密码来允许电脑访问。做完这一切后，iTunes或爱思助手应该可以正常连接设备并显示设备信息。注意有些非原装廉价充电线是不支持数据传输的，一定要用支持数据传输的数据线。<img decoding="async" width="800" height="574" class="wp-image-301" style="width: 800px;" src="https://t.tutu.to/img/5ksy6" alt=""></li>



<li><strong>打开iLoader，登录你的Apple ID。</strong> 你不一定需要使用美区ID，但是为了以后能正常签名应用程序，请务必保证此步输入的Apple ID归你所有，不会出现未来密码错误且无法访问的情况。（这时会显示登录设备为MacBook Pro，这是正常现象）如果一切顺利，现在你应该可以看到左侧显示Apple ID已经处于登录状态，右侧iDevice栏内出现了你的设备名称。（如果没有，可以试试手动刷新）。<img decoding="async" width="800" height="500" class="wp-image-302" style="width: 800px;" src="https://t.tutu.to/img/5kEkq" alt=""></li>



<li><strong>安装侧载环境。</strong> 将Anisette服务器切换为“SideStore（.xyz）“，安装器点击“LiveContainer+SideStore（稳定版）”。这一步注意一定要选择二合一的选项，这关乎后文中的Krkr能不能正常安装和方便地使用。</li>



<li>安装完成后，你应该会看到Windows电脑上出现了“进入LiveContainer导入证书”的提示框，iOS设备桌面上出现了LiveContainer一个应用图标。进入iOS的“设置”>“通用”>“VPN与设备管理”，你可以在“开发者App”下找到你的Apple ID，进入并信任其中的应用程序。现在，你应该可以正常打开LiveContainer了。<img loading="lazy" decoding="async" width="800" height="450" class="wp-image-303" style="width: 800px;" src="https://t.tutu.to/img/5kHMr" alt=""></li>



<li>在LiveContainer程序的“设置”板块中找到“导入来自SideStore的证书”。点击执行它。如果不出所料的话，应当失败了，因为想要正常使用这一功能还要一些额外的网络配置。如果你很幸运，成功了，那么你可以跳过下面的几个步骤，直接跳到第五步。</li>
</ol>



<h1 class="wp-block-heading">0x04 通过全局代理登录SideStore</h1>



<h4 class="wp-block-heading">如果提示“未在SideStore登录，执行以下操作。</h4>



<ol class="wp-block-list">
<li>进入iOS的”设置“，确保你现在连接的是WiFi且和电脑处于同一局域网。点开”无线局域网“，点击你的网络名称，进入网络的详细设置，找到最下方的”HTTP代理“，进入。</li>



<li>将”配置代理“改为”手动“，下方”服务器“填入你的电脑在局域网中的IP地址（如果你使用的是上午提到的”Windows 移动热点“的方法，填写192.168.137.1），端口填写代理软件的端口地址。这取决于你用的是什么应用程序，例如我们用紫色小猫的话，这里填写7897。<img loading="lazy" decoding="async" width="800" height="450" class="wp-image-304" style="width: 800px;" src="https://t.tutu.to/img/5kWZ5" alt=""></li>



<li>Windows端代理软件开启全局模式，确保苹果服务器是通过代理访问的。<img loading="lazy" decoding="async" width="800" height="353" class="wp-image-305" style="width: 800px;" src="https://t.tutu.to/img/5kZdB" alt=""></li>



<li>在iOS设备上尝试访问一些网页，如果能够正常访问，那么说明代理生效了。</li>



<li>在LiveContainer的”App“页面左上方找到一个类似于箭头的图标，点击它，应当会进入SideStore。如果没有进入而是返回桌面，重新点击LiveContainer即可，应当这样就会进入SideStore了。</li>



<li>进入SideStore的”Settings“，即设置页面。最上面有一个“Sign in”，意为登录，在这里输入你的Apple ID账号密码，以及可能的二步验证码。（这时会显示登录设备为MacBook Pro，这是正常现象）注意一定要登录和上一步中在iLoader中相同的ID。登录完成后关闭跳出来的说明页面，看到Name以及自己的邮箱地址即为成功。如果出现“The data couldn't be read because it isn't in the correct format.”报错，请检查自己的互联网连接和代理是否正常，然后多试几次。<img loading="lazy" decoding="async" width="800" height="450" class="wp-image-306" style="width: 800px;" src="https://t.tutu.to/img/5kG7G" alt=""></li>



<li>退出SideStore（直接切出多任务，清除掉LiveContainer的后台，再次进入即可）。再次点击“导入来自SideStore的证书”，现在应当可以正常导入。</li>



<li>完成导入后，记得参考第2小步，回到无线局域网设置关闭HTTP代理，防止后续产生网络连接问题。</li>
</ol>



<h1 class="wp-block-heading">0x05 部署自动续签</h1>



<p>现在我们已经完成了自由侧载的部署，但是由于Apple的政策，个人出于开发目的签名安装的应用程序只有七天的有效期，如果七天内不再次签名，应用程序就会提示“不再可用”或者干脆闪退，也就是黑话“掉签”。<br>不过，好在我们可以通过LocalDevVPN这个应用程序，加上SideStore的功能，实现自签名。再加上“快捷指令”应用的“自动化”功能，我们可以定时自动续签应用证书，这样，就可以规避这个问题了。我们先打开一下LocalDevVPN，打开开关，根据其指示部署VPN配置。然后关闭开关规避连接问题。<br>我们打开“快捷指令”应用程序，并安装 <a href="https://www.icloud.com/shortcuts/849ee86deb9d4a7c80ab207521afaf17" target="_blank" rel="noreferrer noopener">“Sideload补丁”</a> 快捷指令（ <a href="https://www.icloud.com/shortcuts/849ee86deb9d4a7c80ab207521afaf17" target="_blank" rel="noreferrer noopener">https://www.icloud.com/shortcuts/849ee86deb9d4a7c80ab207521afaf17</a> ）。<br>打开“快捷指令”应用程序的“自动化”页面，创建在每天凌晨执行的自动化任务（立即运行，运行时不询问，不发送通知），选择“Sideload补丁”快捷指令作为执行对象。<img loading="lazy" decoding="async" width="800" height="450" class="wp-image-307" style="width: 800px;" src="https://t.tutu.to/img/5kTsn" alt=""><br>尝试运行一次Sideload补丁，若不产生任何报错，说明没有问题，以后侧载的应用程序都会通过此快捷指令验证。</p>



<h1 class="wp-block-heading">0x06 通过容器安装Krkr模拟器，并导入Galgame和运行</h1>



<h4 class="wp-block-heading">准备Krkr软件包</h4>



<p>这里给大家提供一下GBox中提供的 <a href="https://cdn.gbox.run/d/apps/Resources/Resource/Kirikiroid2_v1.3.9_v1.ipa" target="_blank" rel="noreferrer noopener">Krkr模拟器软件包</a> （ <a href="https://cdn.gbox.run/d/apps/Resources/Resource/Kirikiroid2_v1.3.9_v1.ipa" target="_blank" rel="noreferrer noopener">https://cdn.gbox.run/d/apps/Resources/Resource/Kirikiroid2_v1.3.9_v1.ipa</a> ），如果失效了也可以通过另一个 <a href="https://1drv.ms/u/c/65e3ac86a47aeb9b/IQDb71UekbpDRrtcToRUjnFBAS-NgtVNYi-DnaGnXzrpRz8" target="_blank" rel="noreferrer noopener">分享链接</a> 下载（ <a href="https://1drv.ms/u/c/65e3ac86a47aeb9b/IQDb71UekbpDRrtcToRUjnFBAS-NgtVNYi-DnaGnXzrpRz8" target="_blank" rel="noreferrer noopener">https://1drv.ms/u/c/65e3ac86a47aeb9b/IQDb71UekbpDRrtcToRUjnFBAS-NgtVNYi-DnaGnXzrpRz8</a> ）。我们将下载链接在Safari浏览器中打开，选择“下载”以下载IPA安装包文件。</p>



<h4 class="wp-block-heading">安装Krkr模拟器</h4>



<p>打开LiveContainer应用程序，在“App”页面点击左上角的加号“+”，在弹出的选择文件窗口的“最近项目”中选中刚刚下载的Krkr模拟器的IPA文件。（物理位置在“文件”应用程序“的”浏览“>”下载“下）<br>很快Krkr模拟器就会完成安装。<br>尝试在LiveContainer内点击Krkr的“启动”，如果能正常运行，恭喜，你已经几乎成功了。<img loading="lazy" decoding="async" width="800" height="450" class="wp-image-308" style="width: 800px;" src="https://t.tutu.to/img/5kg4d" alt=""><img loading="lazy" decoding="async" width="800" height="392" class="wp-image-309" style="width: 800px;" src="https://t.tutu.to/img/5krhH" alt=""></p>



<h4 class="wp-block-heading">准备Galgame文件</h4>



<p>首先我们准备好GalGame的文件，这一步我就不再赘述，真的需要解释的话，先用网盘、数据线、SMB文件共享或者网页下载之类的方式传到iOS设备上，如果需要解压就拿解压专家或者“文件”App解压，最后以能够在“文件”中找到整个GalGame的文件夹作为成功的标志。</p>



<h4 class="wp-block-heading">移动到Krkr的程序目录</h4>



<p>LiveContainer中的所有应用数据都是挂载到“文件”App内的，因此可以近乎像越狱了一样直接修改内部目录文件。<br>我们进入LiveContainer，长按App页面的Krkr模拟器，点击”打开数据文件夹“按钮，即可跳转到”文件“App内的应用路径。记住这个路径，把上一步准备好的文件夹复制下来，进入此文件夹的”Documents“下（长按空白处可粘贴）。<img loading="lazy" decoding="async" width="800" height="450" class="wp-image-310" style="width: 800px;" src="https://t.tutu.to/img/5kyF7" alt=""></p>



<h4 class="wp-block-heading">在Krkr内启动游戏！</h4>



<p>像正常地启动游戏一样，打开LiveContainer内的Krkr模拟器，点击XP3文件即可启动游戏！开始愉快地玩耍吧！<br>这样的一番操作下来，我们发现，Krkr模拟器又可以正常显示所有的弹出窗口了，原先能游玩的Gal也可以正常游玩，大功告成！<img loading="lazy" decoding="async" width="800" height="1634" class="wp-image-311" style="width: 800px;" src="https://t.tutu.to/img/5kQko" alt=""></p>



<h1 class="wp-block-heading">0x07 一些碎碎念</h1>



<p>LiveContainer是一个容器化的安装环境，里面理论上可以无限制安装IPA应用程序，因此诸如洛雪音乐LX Music、E站阅读器JHenTai等乃至第三方下载的软件包，都是可以安装的。<br>不过要注意下，一是最好不要直接用SideStore安装，而是像上面教学的一样用LiveContainer安装，因为SideStore是直接安装签名的程序，根据Apple的政策，有安装个数限制；二是LiveContainer虽然对安装的应用程序有近乎无限大的权限，但是诸如Filza之类的程序是不起作用的，一些需要系统级权限的应用程序功能也可能出现各种问题。<br>如果有一天真的掉签了，也不要慌张，首先去”文件“备份所有的应用程序数据（存档数据），而后从头开始操作即可，如果你的电脑操作比较熟练，这不会需要太长的时间的。</p>



<h1 class="wp-block-heading">0xFF 写在最后</h1>



<p>本文遵循 &nbsp;<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.zh-hans" target="_blank" rel="noreferrer noopener">CC-BY-NC-SA知识共享协议</a>&nbsp; 。<br>转载请保留原作者署名（幻愿Recovery），禁作商业用途。<br>本文计划在 幻愿Recovery的哔哩哔哩专栏 、 幻愿Recovery的小站 和 相互科技工作室·博客站点 进行发布，除此之外任何标明作者为幻愿Recovery或未标明出处的转载均为侵权行为。<br>本文所提供的方法、研究思路、最终效果均为学习和交流目的，如有侵权，请通过页面提供的联系方式联系作者，我们会尽快删除。另外，鉴于这只是让一个异常软件恢复正常运行的方案，本作者不对任何（包含非正常使用的行为）后果承担责任。<br>本文中涉及敏感技术问题的部分还请自行询问和研究，我们不提供任何形式的资源分享，也不接受方法失效后的后果。<br>欢迎大家有空来 <a href="https://eachother.work" target="_blank" rel="noreferrer noopener">我们工作室的小站</a> （ <a href="https://eachother.work" target="_blank" rel="noreferrer noopener">https://eachother.work</a> ）和 <a href="https://blog.eachother.work" target="_blank" rel="noreferrer noopener">我的博客小站</a> （ <a href="https://blog.eachother.work" target="_blank" rel="noreferrer noopener">https://blog.eachother.work</a> ）游玩。我是幻愿Recovery，能在这样绚烂的二次元世界遇到大家，我深感幸运！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/ios-sideload-krkr/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【教学向】iOS 设备通过“自动化”实现基于环境的远程锁定</title>
		<link>https://blog.eachother.work/lock-ios-remotely-with-bluetooth-device/</link>
					<comments>https://blog.eachother.work/lock-ios-remotely-with-bluetooth-device/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Thu, 22 Jan 2026 09:12:52 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=288</guid>

					<description><![CDATA[本教程旨在通过 iOS 官方应用“快捷指令” App 和任意可与你的手机连接的蓝牙设备（如笔记本电脑或智能手环），实现一个“远程锁定设备”的功能。]]></description>
										<content:encoded><![CDATA[
<p></p>



<h1 class="wp-block-heading">0x00 背景与知识</h1>



<p>在生活中，我们常会碰到不得已而将手机借给他人的场景，单一的“引导式访问”功能又无法满足我们的使用需求；亦或者是我们忘记在暂时离开座位时锁定手机；亦或者是我们遇到极端危险的情况，在混乱的环境中手机可能被抢夺而未来得及锁定。此时我们就需要一种类似于“汽车远程钥匙”的机制，用来强制锁定我们的设备，防止隐私泄露和财产损失。对于初入社会的大学生而言，这也是一个很实用的功能（至少我就是在食堂遇到所谓“学姐实习の蜜汁小任务”后想到制作这个小脚本的）。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MSPQ4" alt=""/></figure>



<p><br>本教程旨在通过 iOS 官方应用“快捷指令” App 和任意可与你的手机连接的蓝牙设备（如笔记本电脑或智能手环），实现一个“远程锁定设备”的功能。<br>本脚本的诞生受启发于 Lenovo TB-8703F 原生 Android 6.0 的“基于环境锁定设备”的功能，该功能可在离开常用地点或与某蓝牙设备断开连接时自动锁定平板。如果你的设备是 Android 系统的，或许你可以在系统设置里找到类似的功能。</p>



<h1 class="wp-block-heading">0x01 安装“快捷指令” App</h1>



<p>本教程针对的是 iOS 设备。我们前往 App Store 搜索并安装 Apple 官方的“快捷指令”应用程序。此应用程序是一个用户自行写作脚本来实现对应功能的 App，我们将用到其中的“自动化”功能。这个 App 属于系统应用，具有锁定系统等权限。如果有兴趣，也可以自行探索进阶用法。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MS79S" alt=""/></figure>



<h1 class="wp-block-heading">0x02 连接设备</h1>



<p>随后，我们需要准备好已经和你的手机连接好的设备。我们这里拿<strong>带有蓝牙功能的 Windows 笔记本</strong>和<strong>小米手环</strong>举例子。</p>



<ul class="wp-block-list">
<li>对于 <strong>Windows 电脑</strong><br>我们开始菜单找到“手机连接”功能（如果是厂家预装的 Windows 11 电脑，通常系统自带了此功能）.<img loading="lazy" decoding="async" width="750" height="477" class="wp-image-289" style="width: 750px;" src="https://t.tutu.to/img/MSDeh" alt=""><br>我们按照软件的提示，连接并设置手机设备（你可能要在 iOS 设备上安装一个“连接至 Windows” App 方可完成配置）。该应用程序也可以实现设备通知的接收和 Call Kit 的转接。<br><img loading="lazy" decoding="async" width="750" height="477" class="wp-image-290" style="width: 750px;" src="https://t.tutu.to/img/MSKgQ" alt=""><br>顺利连接后，你可以在 iOS 设备的蓝牙设置中看见电脑的名称和其右侧的“已连接”字样。</li>



<li>对于 <strong>小米手环</strong>（以及类似的智能穿戴设备）<br>这类设备一般而言在开箱使用时就会要求你下载应用程序并与手机完成配对。如果你是在另一台手机上配对的手环，你可能需要使用“连接新手机”功能配对当前手机。<br>这类设备能够按照本文操作设置成功的三个条件是，其能在手机蓝牙设置中显示、其平时能够和手机保持连接状态，以及可以主动断开和手机的蓝牙连接（包括但不限于重启手环、手环主动关机、开启飞行模式等）。<br>即使后续你恢复了设备与手机的连接，手机也会因为“自动化”脚本已经执行的原因，保持在锁定状态，直到你主动解锁。<br><img loading="lazy" decoding="async" width="750" height="477" class="wp-image-291" style="width: 750px;" src="https://t.tutu.to/img/MSn86" alt=""></li>
</ul>



<h1 class="wp-block-heading">0x03 配置自动化脚本</h1>



<p>打开“快捷指令” App，点击右上角的“+”图标，新建一个规则，命名为“锁定屏幕”。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MSpnq" alt=""/></figure>



<p><br>进入“自动化”页面，我们新建一个自动化规则，条件选取“蓝牙”，点选“下一步”。在下一步条件设定中，我们勾选用于控制锁定的设备，将条件设置为“断开连接”，并选择“立即运行”，这样快捷指令执行前就不需要额外的确认执行。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MSINA" alt=""/></figure>



<p><br>下一步，操作选择刚刚新建的“锁定屏幕”快捷指令。完成自动化创建。这样，我们就完成了自动化规则的配置。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MShwj" alt=""/></figure>



<h1 class="wp-block-heading">0x04 测试效果</h1>



<ul class="wp-block-list">
<li>对于 Windows 电脑的方案<br>在屏幕右下角的“控制中心”中关闭蓝牙，自动化规则在侦测到蓝牙断开后运行，锁定 iOS 设备屏幕。</li>



<li>对于 穿戴设备的方案<br>重新启动手环，此时手环与手机断开连接，自动化规则在侦测到蓝牙断开后运行，锁定 iOS 设备屏幕。</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MSNSP" alt=""/></figure>



<p>此现象证明设置成功。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/lock-ios-remotely-with-bluetooth-device/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【教学向】iOS设备通过“快捷指令”配置可自定义的悬浮窗</title>
		<link>https://blog.eachother.work/ios-float-window-with-shortcutsapp/</link>
					<comments>https://blog.eachother.work/ios-float-window-with-shortcutsapp/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Wed, 21 Jan 2026 05:08:45 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=286</guid>

					<description><![CDATA[本文主要介绍了一种方式，可以使 iOS 设备通过一系列的操作技巧，以悬浮窗的形式调用用户脚本，从而实现许多层面上的功能增强。]]></description>
										<content:encoded><![CDATA[
<p></p>



<h1 class="wp-block-heading">0x00 背景与知识</h1>



<p>iOS 的系统相对而言较为封闭，应用程序的权限管控极为严格，也没办法实现类似于安卓应用程序悬浮窗的功能。不过 iOS 系统自带了一个近似悬浮窗的功能，即为“辅助触控”，可以在屏幕上显示附加菜单以实现返回主屏幕、屏幕转向等附加操作。而许多人不知道的是，除了直接点按“辅助触控”图标显示菜单以外，还可以自行定义双击和长按这个按钮时所出发的操作。配合“快捷指令”这款用户自行编写简易脚本的应用程序，我们可以实现一些用于增强系统功能的类“悬浮窗”功能。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MO8u6" alt=""/></figure>



<p></p>



<h1 class="wp-block-heading">0x01 系统配置与基础快捷指令编写</h1>



<p>首先我们在 App Store 下载和安装来自 Apple 官方的“快捷指令”应用程序。通过右上角的“+”图标，我们新建两个快捷指令，并命名为“辅助触控编辑器 - 双击”和“辅助触控编辑器 - 长按”，在其中插入一个操作“运行快捷指令”，其中参数暂时留空即可。这样操作是为了在将来编辑操作时，我们可以轻松地切换到不同的功能而不必返回设置重新勾选或者重写快捷指令。如果你需要替换掉原有的辅助触控菜单，同理也可创建“辅助触控编辑器 - 单击”。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MOkdr" alt=""/></figure>



<p><br>导航至“设置”>“辅助功能”>“触控”>“辅助触控”，打开辅助触控开关。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MO0D5" alt=""/></figure>



<p><br>并将“自定义操作”下的“轻点两下”和“长按”分别设为我们刚刚创建好的对应快捷指令。快捷指令往往显示在所有选项的最下方，如果你存储的快捷指令较多，这一步会比较困难，这也是我们需要先创建一个快捷指令来避免频繁重新设置的原因。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MOqAB" alt=""/></figure>



<p></p>



<p>至此为止，我们已经完成了所有关于此“悬浮窗”的前期操作，我们现在可以实现通过双击或者长按“辅助触控”图标，来运行我们设置的一系列操作了。</p>



<h1 class="wp-block-heading">0x02 案例：在任何界面轻松地唤出 Gemini 的悬浮窗口</h1>



<p>编写如左图所示的快捷指令，并将其设为我们前文中提到的“运行快捷指令”中的目标。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MO94G" alt=""/></figure>



<p><br>（请注意，Gemini AI的访问具有一定的网络要求，如果你没有一定的网络环境，也可以试着将 Gemini 的地址更改为国内更加友好的 AI 提供商地址，如 Deepseek 和 星火 等）<br>现在，当你长按“辅助触控”图标时，即可看到弹出了一个小窗口，其中可以使用 Gemini 网页版。同时，也不会导致你正在使用的应用程序中断。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MOaCn" alt=""/></figure>



<p></p>



<h1 class="wp-block-heading">0x03 案例：简单的播放控制按钮</h1>



<p>这也是我最早想自定义这个功能的原因。我翻了一下，系统自带的功能里是没有播放控制这个选项的，但是当我们在大冬天，一手揣兜而无法调出控制中心控制音乐暂停和播放时，我们就很需要这个悬浮窗帮助我们来控制。<br>如左图创建一个快捷指令，并同上述步骤应用到控制器中。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MOCzH" alt=""/></figure>



<p><br>现在，你可以通过长按”辅助触控“图标的方式来暂停和续播你的音乐了。</p>



<h1 class="wp-block-heading">0x04 案例：剪贴板的快速编辑</h1>



<p>”哔哩哔哩“等应用程序中，我们有时需要复制视频简介内容或者他人的评论内容，而后从其中截取某几个文字，进行发送或搜索。然而这些应用程序为了省事或者操作便利，往往不允许选择文字的某一部分，我们只能复制整一块文字。<br>我们当然可以采用复制到微信文字输入框或者备忘录的方式来编辑一小段文字，但是借助今天我们制作的快捷指令，可以将此操作变得更加轻松。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MOhJd" alt=""/></figure>



<p><br>我们编写如左图的快捷指令，其中，第二个操作名为”请求输入“。注意我们需要展开”请求输入“操作，并将”默认回答“设置为变量”剪贴板“，这样，快捷指令才能将我们的剪贴板内容展示在对话框中。随后，同上述步骤，将控制器的执行目标设为此快捷指令。<br>完成这一系列操作后，你就可以轻松地操作自己剪贴板内的内容了。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MOBGq" alt=""/></figure>



<p></p>



<h1 class="wp-block-heading">0x05 小结</h1>



<p>本文主要介绍了一种方式，可以使 iOS 设备通过一系列的操作技巧，以悬浮窗的形式调用用户脚本，从而实现许多层面上的功能增强。<br>其实该玩法可以实现的操作很多很多，”快捷指令“原本就是一个类似用户脚本的平台，通过许多应用程序的支持、系统操作和API调用能力，可以实现许多轻量级的 APP。原本是有若干个平台，可以提供许多快捷指令的下载的，不过近些年来热度过去，也渐渐淡出了人们的视野。<br>祝各位玩得开心！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/ios-float-window-with-shortcutsapp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【教学向】如何在中国注册一个可用的Steam账号并安装正确的Steam？</title>
		<link>https://blog.eachother.work/how-to-register-steam-in-chinese-network/</link>
					<comments>https://blog.eachother.work/how-to-register-steam-in-chinese-network/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 07:49:50 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=284</guid>

					<description><![CDATA[Steam是全球知名的在线游戏商店以及玩家互动平台。与此同时，Wallpaper Engine等系统工具和Bl [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Steam是全球知名的在线游戏商店以及玩家互动平台。与此同时，Wallpaper Engine等系统工具和Blender等专业软件的上架，也让大学生拥有一个Steam账号变得十分必要（迫真）。<br>然而由于种种原因，新手在入门Steam时总会遇到重重困难——无法通过的人机验证，抑或是假冒的客户端。本文旨在通过简单的步骤，使得你能够使用简单的方法，免费且快速地完成Steam账号的注册，同时为安装Steam平台与基础的使用提供指导。</p>



<h1 class="wp-block-heading">0x00 准备工作</h1>



<p>你需要准备</p>



<ul class="wp-block-list">
<li>一台可以接入互联网的计算机</li>



<li>可用的手机号码和电子邮箱</li>



<li>一双手、脑子、眼睛</li>
</ul>



<h1 class="wp-block-heading">0x01 通过 蒸汽平台 注册Steam账号</h1>



<p>很多时候我们没办法连接到Steam社区完成账号的注册，如果使用网络代理，也很有可能会被“机器人验证”步骤卡在门外。实际上，在中国的网络环境下，也可以使用“蒸汽平台”来完成Steam账号的注册。（非引流）蒸汽平台是Steam在中国大陆地区的代理商，其账号数据和Steam是互通的，因此我们先在蒸汽平台注册好账号，稍后便可以在Steam中激活使用。<br>我们打开<a href="https://store.steamchina.com/">蒸汽平台</a> （https://store.steamchina.com/）。在右上角点击“登录”。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDb9A" alt=""/></figure>



<p><br>在此处向下滑动页面，可以找到“创建账户”选项，我们进入。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDHNI" alt=""/></figure>



<p><br>此处，我们根据提示，输入自己的手机号、邮箱地址和实名认证信息，完成人机验证，即可完成注册。<br>需要注意的是，来自蒸汽平台的电子邮件可能会被邮箱识别为垃圾邮件，因此验证码可能需要前往邮箱的“垃圾邮件”文件夹内寻找。【账户名称】需要英文（和数字）组成，不能与已经在Steam社区中存在的用户重复，不能出现中文。<br>完成后，你可以安装和直接使用蒸汽平台。但是实际上，此处安装的并不是真正的Steam，而是Steam的一个国内代理版本。如果需要继续安装Steam，请完成下方步骤。</p>



<h1 class="wp-block-heading">0x02 安装Steam客户端并激活Steam账户</h1>



<h3 class="wp-block-heading">注：如果你不知道什么是【网络代理】，也没有可用的加速器和节点，请你直接在上一步安装蒸汽平台使用即可。</h3>



<p><em>本文不会提供推荐的代理提供商或者加速器，因为本文没有商业性质。如果你有需要，可以自行研究用什么来加速Steam访问。</em><br>前往<a href="https://store.steampowered.com/">Steam官方网站</a>【请避免从搜索引擎上直接搜索和进入Steam，尤其是新手，网络上有大量来路不明的虚假平台。】：https://store.steampowered.com/<br>这次，我们找到页面右上角的“安装Steam”，下载和运行Steam客户端的安装包。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDWOi" alt=""/></figure>



<p><br>这一步如果你无法进入上述地址，或者下载速度奇慢，说明你的加速器或网络代理没有生效。<br>安装完成后，在桌面上可以找到Steam图标，打开它，输入刚刚在【蒸汽平台】创建的账户名称和密码。<br>首次从蒸汽平台登录到Steam会要求你激活你的Steam账户，接受所有弹出的用户条款，而后再次选择登录即可。所有需要验证码的场合都会向你在蒸汽平台设定的电子邮件地址发送验证码（不出所料的话这次不会再被扔进垃圾邮件里了www）。<br>如若顺利，Steam打开的客户端页面如下图所示。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDXQJ" alt=""/></figure>



<p></p>



<h1 class="wp-block-heading">0x03 Steam的一些机制和使用小技巧</h1>



<h3 class="wp-block-heading">关于Steam客户端</h3>



<p>Steam客户端分为几个板块，我们最主要用到的分别是商店、库和社区（个人资料）。<br>一般而言，“商店”和“社区”是需要代理或者加速器才能够正常连接的，而浏览自己的Steam游戏库、下载和安装游戏、游玩许多游戏（除了一些国内不支持的游戏）是不用加速的。<br>“商店”是你购买新游戏和添加免费游戏的地方。Steam商店中的游戏就像是货架上的商品，你可以在商店中找到，可以在游戏详情页下载试玩版、添加到愿望单和购物车，以及进行购买。而将免费游戏添加到库，或购买完整游戏后，你才能在“库”里找到你的游戏，并下载和安装。这就是玩家所说的“入库”操作。<br>以Blender为例，我们可以在商店的搜索栏中搜索“Blender”并点击第一项进入Blender的详情。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDzHM" alt=""/></figure>



<p><br>你可以点击“添加到库”按钮，将其添加到你的Steam库。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDyfg" alt=""/></figure>



<p><br>随后，你就可以在“库”中找到你的游戏并进行下载了。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MD3Ym" alt=""/></figure>



<p></p>



<h3 class="wp-block-heading">关于下载</h3>



<p>需要说明的一点是，Steam的下载服务并不需要加速，在国内的网络环境也是有很好的优化的。如果你开着代理或加速器进行 库中的游戏下载，可能会导致你的流量被大量消耗（例如一个CS：GO要将近50GB，安装一次有些代理套餐的流量就见底了）。因此，建议每次下载游戏时关闭代理或加速器，并按照以下步骤将下载服务地区切换到国内，来高速、低成本地下载。</p>



<h4 class="wp-block-heading">1.导航到“库”&gt;“管理下载”</h4>



<p></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDcNX" alt=""/></figure>



<p></p>



<h4 class="wp-block-heading">2.点击右上角的齿轮状按钮，打开设置</h4>



<p></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDiSK" alt=""/></figure>



<p></p>



<h4 class="wp-block-heading">3.将“下载地区”设定为地理位置离自己较近的地区。</h4>



<p>客户端会要求你重启Steam以完成地区切换。<br>进行上述操作后，你的下载地区就会变更到可用的高速节点。</p>



<h3 class="wp-block-heading">关于好友</h3>



<p>Steam的好友位是有限的，可以通过升级Steam等级来提高上限。不过，这前提是你要能够添加好友。然而Steam有一个“付款门槛”，为了防止机器人添加好友发送垃圾信息的现象泛滥，你必须在Steam商店中消费至少5美元（约40元）才能正常主动添加好友，否则即使你知道对方的好友代码，也是不能添加对方的。不过，若是你希望添加的对方达到了付款门槛，它他可以通过输入你的好友代码来添加你。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDTLz" alt=""/></figure>



<p><br>如上图，打开顶部工具栏的“好友>添加好友”即可找到你的好友代码。<br>被请求添加好友、收到礼物、获取到物品后，你都会收到“Steam通知”，你可以通过工具栏右上角的“铃铛”状图标查看通知。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDr8k" alt=""/></figure>



<p></p>



<h3 class="wp-block-heading">有关价格的小技巧</h3>



<p>（这里没有营销目的，单纯推荐一个好用的免费工具）<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDtQj" alt=""/></figure>



<p><br>Steam上的正版游戏往往是不便宜的，但是在适当的时机入手，就能以低价玩到高品质的正版游戏了。Steam的黑话“史低”就是说这款游戏目前在售价格为历史最低价，这个时候入手往往是值得的。<br>有一个公益小工具，即<a href="https://steamdb.info/">SteamDB</a>，可以方便地查询Steam商品的价格走势，帮助你进行购买决策，如果你了解如何进行Steam转区，还可以让你获取到不可思议的低价。我这里放一个链接（https://steamdb.info/），如有需要可以常常去看一下。如果史低价格还是在预期之上，还可以当“等等党”，等到下次促销，也许价格是会更低的。一款游戏的史低价格往往分布在三个时间点：</p>



<ul class="wp-block-list">
<li>Steam季节促销</li>



<li>对此款游戏有特殊意义的时刻（如周年庆、某些纪念活动）</li>



<li>游戏主题相关的促销活动（如视觉小说节，以及此教程写成时的推理游戏节）<br>有时某些游戏还会限免赠送。这里就不多赘述。祝各位玩的开心！</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/how-to-register-steam-in-chinese-network/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【教学向】如何利用端口映射穿透公网进行MC联机</title>
		<link>https://blog.eachother.work/mcconnect/</link>
					<comments>https://blog.eachother.work/mcconnect/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Wed, 26 Nov 2025 06:41:32 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=283</guid>

					<description><![CDATA[0x00 背景知识 众所周知，我们的互联网看似可以将全世界的设备进行连接，实际上却被非对称NAT划分为了一个个 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">0x00 背景知识</h1>



<p>众所周知，我们的互联网看似可以将全世界的设备进行连接，实际上却被非对称NAT划分为了一个个小的“局域网”。虽然说我们在各种查询网站上可以获取到自己的IP地址，但是这个地址实则是和许多同一区域下的设备共同使用的。这么一来，这个IP地址实际上并不能被你所掌控，你也没办法顺你所愿地用IP地址连接多台设备。诸如MC服务器联机的操作，也无从下手。<br>当然，你也许常听说“公网IP”这个说法。相对于IP地址完全被运营商掌握、个人设备无法随意使用的普通环境，具有公网IP的家用宽带或服务器，可以直接获得一个IPv4地址的支配权，换句话说，开放一个端口进行联机也是可以的，这个设备IP地址面向整个互联网都可以被连接。很可惜的是，几乎所有的国内运营商都把公网IP的申请卡得死死的，个人（尤其是校园网、家庭等学生非宽带户主的环境）很难取得一个公网IP。<br>在这种情况下，我们该如何打通内网环境，使得自己真正拥有一个对互联网开放的地址和端口呢？<br>我们在本文中探讨一种名为FRP的技术用法，这种技术的原理就是：在互联网上有一台具有公网IP的服务器（由服务商提供），作为房主的玩家首先与此服务器进行连接，随后服务器会打开一个端口，转发所有发送和接收的数据包，分发给房主和成员，从而达到MC联机的效果。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDvCi" alt=""/></figure>



<p><br>注意：本文以 SakuraFrp 和 浮居内网穿透 为例进行讲解，旨在教学图形化操作界面和命令行化FRP.exe的使用，各位可以在网络上自行寻找符合需求的服务提供商，无推广意图。</p>



<h1 class="wp-block-heading">0x01 对 Minecraft 进行必要的设置</h1>



<h4 class="wp-block-heading">注：若所有成员均拥有 Minecraft 正版，可忽略此步骤</h4>



<p>Minecraft 的后期版本引入了联机的正版验证要求，并且使用原生客户端无法关闭或修改认证服务器，如果我们不关闭正版验证，那么即便我们有公网IP也是无法正常联机的（会显示“无效会话：请尝试重启客户端”）。<br>如果不依赖于Mods，我们就只能通过架设 Minecraft 服务器，关闭 online-mode 配置项，来解决这一问题了。不过作为普通玩家，如果对纯净游戏没有什么执念，其实完全也可以通过添加Mod的方式来关闭正版验证。<br>这里以HMCL为例添加Mod。<br>（在已经安装好游戏和模组加载器的前提下）打开HMCL， 进入“实例列表（旧版本：游戏列表）”，点击准备联机的游戏版本。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MD83R" alt=""/></figure>



<p><br>这里我使用的版本是1.20.1，模组加载器为NeoForge。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDU0z" alt=""/></figure>



<p><br>依次进入“模组管理”和“下载”。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDk5e" alt=""/></figure>



<p><br>我们搜索并下载LSP（Lan Server Properties），点击进入后选择正确的游戏版本，并进行安装。<br>值得一提的是，LSP似乎并不支持所有的游戏版本和模组加载器。如果不能正常使用的话，请检查一下是不是装错版本了（游戏版本和模组加载器版本），如果LSP不支持你的游戏版本，你还可以试试下列类似的Mod：</p>



<ul class="wp-block-list">
<li>Custom LAN（Fabric）</li>



<li>LAN World Plug-n-Play<br>等到你的模组安装完成，你就可以启动游戏了。<br>开启你需要联机的世界，进入游戏菜单，点击“对局域网开放”，出现如下界面。<br><br>我们将“端口号”改为25565，并将“正版验证”禁用。此后点击“创建局域网世界。（注意：如果Windows 防火墙弹出警告窗口，请务必选择允许！）当你看见提示”本地游戏已在端口[25565]上开启，你的联机就成功创建了。</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MD9vg" alt=""/></figure>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDaEm" alt=""/></figure>



<h1 class="wp-block-heading">0x02 注册你的端口映射服务</h1>



<p>打开你的端口映射服务商地址。<br>我们这里以此两个服务为例：<br>樱花内网穿透SakuraFRP： https://www.natfrp.com/<br>优点：免费，有简单的控制面板开启关闭，技术门槛低<br>缺点：速度较慢，流量每日签到比较麻烦，高峰时段可能遇到严重的拥堵和无空闲隧道可用的情况。你可能需要进行<strong>实名认证</strong>才能使用端口映射的全部功能。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDRKM" alt=""/></figure>



<p><br>浮居内网穿透FUJUFrp： https://www.frp.cool/<br>优点：速度较快，可用的节点一般都比较流畅和空闲，购买后流量速度无限制<br>缺点：需要购买（10r/月）方可使用，没有图形化启动器只能手动启动隧道，有一点技术门槛<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDRKM" alt=""/></figure>



<p></p>



<h1 class="wp-block-heading">0x03 部署隧道，启动隧道</h1>



<p>本节我们分开讲述两个服务的使用方法。</p>



<h4 class="wp-block-heading">如果你正在使用 SakuraFrp：</h4>



<p>请确保你已经在网站管理后台的“用户>实名认证”内完成了<a href="https://www.natfrp.com/user/realname">实名认证</a>。<br>进入网站的“服务>软件下载”，点击绿色的下载按钮，下载并安装Windows启动器。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDIIK" alt=""/></figure>



<p><br>安装好以后打开，主页应该长这样：<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDNJj" alt=""/></figure>



<p><br>啥？你问我为什么你没有隧道？我们还没建呢！看下去，别着急。<br>我们回到网页端，来到“首页”，这里你可以先签到领个流量包，免得流量跑没了。<br>点击账号信息右上方的“复制访问密钥”。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDP3A" alt=""/></figure>



<p><br>复制成功后，来到启动器的”设置“中，把刚刚的访问密钥粘贴到“账户”中的“访问密钥”框框里面，点击登录。不出意外的话，你就可以看见你的用户信息了。这里我们可以修改一下设置，开启开机自启。如果你会魔法，你还可以打开”绕过系统代理“，要不然把另外一个流量跑光了还又卡又慢就不好了（雾）。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MD7qP" alt=""/></figure>



<p>我们回到”隧道“页面，点击标题旁边的”+“，进入添加隧道页面。<br>这里我们一般选择离我们地理位置最近的一个节点。<br>如果你看到剩下寥寥几个节点可用，而且都是国外的或者很偏远的，那恭喜你，现在是高峰期，等会再来，或者氪个金，或者去试试第二个服务吧。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDD54" alt=""/></figure>



<p><br>隧道类型这边我们选择TCP（当然如果你是开基岩版服务器就选UDP，其他FTP、RDP之类的你自己网上搜一下去吧（雾））<br>隧道名字自己取一个，不重要。本机IP选127.0.0.1，本地端口选择25565.<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDKTS" alt=""/></figure>



<p><br>好了之后就创建，创建以后回到隧道页面，把对应隧道的那个开关给打开。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDnmh" alt=""/></figure>



<p><br>前往“日志”页面，你应该可用看到“TCP 隧道启动成功“的信息，而后还有两个网址。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDpKQ" alt=""/></figure>



<p><br>这里的“使用xxx:xxx连接你的隧道”就是你的服务器地址了。</p>



<h4 class="wp-block-heading">如果你正在使用 浮居内网穿透：</h4>



<p>打开网页，登录进入后台。点击“创建隧道“，可看见如图所示的页面：<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M7i0n" alt=""/></figure>



<p><br>如果没看见可用服务器，那就是你没有买服务。去首页有地方可以买，买好激活码就去首页提供的地址激活就好。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M7QzG" alt=""/></figure>



<p><br>如图填写隧道信息，隧道类型选TCP，本地地址依旧127.0.0.1，本地端口依旧25565.<br>远程端口你随便填一个五位数上去，如果重复不能用，你就再填一个，直到成功创建为止。<br>点击“完成创建”保存你的隧道，如果一切顺利的话，显示“隧道创建成功”。<br>接下来进入网页左侧的“软件下载”，下载amd64架构对应的软件。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M74GH" alt=""/></figure>



<p><br>解压软件到一个你找得到的位置，可以得到下图所示目录。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M7t5d" alt=""/></figure>



<p><br>我们回到网页，进入“配置文件”。<br>选择你刚才开隧道的对应的服务器。我这里没马内购买隧道了（月中大学生饿饿QAQ）。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M7YDw" alt=""/></figure>



<p><br>如果一切顺利，“配置文件内容”这个区域会显示一串配置文件内容（其中带有你的隧道名称字样）。我们把它复制下来，回到软件目录下，用记事本或者你喜欢的代码编辑器打开配置文件frpc.ini，将配置文件的所有内容粘贴进去，如图所示。<br>其中，server_addr的值就是你的服务器域名（图中是cn-zj1-….），remote_port（你刚才自己填的，图中是16991）即为你的服务器端口。用英文冒号“:”连接一下，获得"cn-zi1-a8ldj1kk.frp.cool:16991"，这就是你的服务器地址了。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M7wv7" alt=""/></figure>



<p><br>保存（Ctrl+S）配置文件，关闭配置文件窗口，双击"双击运行.bat"。<br>不出意外的话，现在会弹出一个命令行弹窗：“Start proxy success.”，即为启动成功。<br>注意：在你不需要玩，关闭联机之前，这个命令行窗口都不可以关上。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/MDmJJ" alt=""/></figure>



<p></p>



<h1 class="wp-block-heading">0x04 连接到服务器</h1>



<p>你的朋友安装与你版本相同、Mods配置正确的Minecraft，并启动游戏。<br>点击“多人游戏”，添加服务器，名字随便取一个，地址填写上一步获得的服务器地址，随后点击“完成”。<br></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://t.tutu.to/img/M7xbI" alt=""/></figure>



<p><br>不出意外的话，现在就可以正常联机了。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/mcconnect/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>一种对处于冰点还原状态下的一体机硬盘进行修改、自定义自启动和安装倒计时组件的方法分享</title>
		<link>https://blog.eachother.work/startup-with-recv/</link>
					<comments>https://blog.eachother.work/startup-with-recv/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Sun, 23 Feb 2025 01:57:45 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=260</guid>

					<description><![CDATA[此方案可以在保持打开冰点还原的情况下，修改受保护磁盘分区内的文件，从而调用需要自启动的程序，并且可以轻松地通过未设置还原的数据盘来进行管理自定义的启动项。如果你有一定的编程能力，你亦可轻松地运用此方法来完成极多的系统自定义操作。]]></description>
										<content:encoded><![CDATA[
<p>许多学校为了方便教室用电子白板的管理、防止学生安装未经授权的应用程序，会开启集控后台的“冰点还原”功能（不同品牌与型号所用名称可能不同）。此功能会在系统关机时清除本次开机对硬盘进行的更改（虽然这个说法并不严谨，因为非正常关机是没用的），从而达到将系统“冰冻”在刚开启此功能时的样子。</p>



<p>然而这一功能也使得电教爱好者发觉，白板的可玩性和可维护性都大幅降低。一方面，旧班级在桌面上留下的古董课件极大地增加了文件管理的难度，并且例如某某影音无法卸载所带来的广告弹窗问题亦挥之不去。另一方面，在我的情况里，我无法为白板安装自己编写的<a href="https://github.com/TekoDotIO/AutoFileBAK">文件同步</a>与<a href="https://github.com/TekoDotIO/HiDesktop">桌面小组件</a>（如高考倒计时、通知文字、辅助触控、一言等），也就无法用自己的能力做出贡献。</p>



<p>在一段时间的探索后，我总结出了一个方案，此方案可以在保持打开冰点还原的情况下，修改受保护磁盘分区内的文件，从而调用需要自启动的程序，并且可以轻松地通过未设置还原的数据盘来进行管理自定义的启动项。如果你有一定的编程能力，你亦可轻松地运用此方法来完成极多的系统自定义操作。</p>



<h2 class="wp-block-heading" id="◯、局限性与我对原理的思考">◯、局限性与我对原理的思考</h2>



<p>首先请各位读者知悉，我的方法实测可用，但并不是最保守与稳妥的方法，如果可行，或者你有仅凭文件系统+自启动无法实现的需求，请考虑申请解除冰点还原或参阅<a href="https://blog.eachother.work/seewo-win11-23h2/" data-type="post" data-id="229">本文</a>重装系统以强制解除还原。</p>



<p>我所述的这种操作方法也有局限性。如上所言，这种基于 PE 的方法只能让你修改文件，搭配批处理或自编程序可以修改一部分系统设置，而想要进行与系统关联极强、设置时间极长与设置过程极复杂的操作，是做不到的。我这里列举一些没有可行性的操作，如果有此类需求，建议移步其他操作方法：</p>



<ul class="wp-block-list">
<li>安装程序，并且此程序对环境或注册表设置有极大依赖。</li>



<li>卸载无法通过直接删除文件移除的软件。（如驱动等）</li>



<li>更改“免打扰”（专注助手）等无法用 Win32 Api 访问的系统设置。</li>
</ul>



<p>可以做什么：</p>



<ul class="wp-block-list">
<li>自定义一个需要开机自启的程序</li>



<li>整理文件，移除桌面上无用的文件，并添加指向数据盘的快捷方式（如各科文件夹）</li>



<li>用自定义程序修改壁纸、默认音量等</li>



<li>解决冰点还原所致 OneDrive 错误弹窗与音量无法显示等问题</li>



<li>强制移除某某影音等带有广告程序的软件。</li>
</ul>



<p>而至于这种方法的发现，则是因为我某天想起了一个名为“影子系统”的软件，对比两个软件的行为与功能，我发觉二者应该是基于同样原理的，而“影子系统”这个软件要在 winlogon 开机阶段（即“欢迎”界面）才会生效，也就是说在此之前系统盘都是可修改的，可参见下图。</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://p.imghz.com/2025/02/23/67ba7a508589e.png" alt="" style="width:620px;height:auto"/></figure>



<p>也就是说，在 winlogon 之前修改文件，或者干脆不启动硬盘内系统，就可以做到修改文件了。这一下子提醒我了 Windows PE 工具，只要用 WinPE（即 U 盘内的维护系统），就能达成我们的目的了。</p>



<p>理论存在，实践开始。</p>



<p>⚠️ <strong>警告：请务必报备并确保人身与文件安全，本教程与作者不对操作者引发的后果负责！</strong></p>



<h2 class="wp-block-heading" id="一、原料与准备工作">一、原料与准备工作</h2>



<ul class="wp-block-list">
<li>一台工作正常的希沃一体机。</li>



<li>一体机附带的遥控器或自备的键鼠。</li>



<li>一个 U 盘，烧录有类似于 <a href="https://firpe.cn/page-247">FirPE</a> 的 Windows PE 维护系统：烧录教程可参阅<a href="https://www.bmabk.com/index.php/post/268860.html">此处</a>。</li>



<li>事先准备好的自启动脚本*/命好名且目标位置正确的快捷方式文件/需存入或替换的文件。</li>



<li>（可选）一个屏幕键盘程序与一个编辑器程序，以防万一。</li>



<li>一双手、敏捷的大脑、应变能力。</li>
</ul>



<p>⚠️ *下文中将会教学如何编写此脚本，你应当在实操前构思并编写好。</p>



<h2 class="wp-block-heading" id="二、（可选）自启动程序的架构设计与脚本编写">二、（可选）自启动程序的架构设计与脚本编写</h2>



<p>这一步仅针对需要部署自启动程序的情况，我将以自己编写的 <a href="https://github.com/TekoDotIO/HiDesktop">HiDesktop 桌面小组件</a>程序为例。</p>



<p>我们知道，在 Windows 中开机自启一个程序，通常有四种方式：<a href="https://www.cnblogs.com/jijm123/p/12456093.html">“启动”文件夹</a>、<a href="https://www.cnblogs.com/siyunianhua/p/18100689">注册表</a>、<a href="https://www.cnblogs.com/cleverZane/p/9258710.html">任务计划程序</a>和 Windows 服务。用户可以轻松自定义的是前三种，我已将概述贴在上面，这里我们只能修改文件系统，因此选用第一个方案：</p>



<pre class="wp-block-code"><code>C:\ProgramData\Microsoft\Windows\Start Menu\Startup\</code></pre>



<p>上述即为 Windows 启动文件夹。你可以自己放一个文件进去试试，它会在开机后自动运行。如果你想在资源管理器中找到此文件夹，请注意，部分路径可能显示为中文（Start Menu→开始菜单；Startup→启动），并且你需要<a href="https://www.sysgeek.cn/show-hidden-files-on-windows/">显示隐藏的文件项目</a>，在某些奇葩系统上还要<a href="https://www.cnblogs.com/zhiders/p/17793204.html">提权文件夹</a>以访问。（笑，Windows 总是那么让人头痛）</p>



<p>我们将在这里放置一个 Windows 批处理文件，并利用其执行数据盘内的另一个脚本。这样，我们就可以在不进行第二次 PE 操作的前提下，自定义设置我们的启动项了。</p>



<pre class="wp-block-code"><code>::filename: start.bat ; lang: Windows CMD
@echo off
title 正在执行设置.
color 0a
echo 正在执行设置，请勿关闭或点击此窗口…!
start D:\startup.bat</code></pre>



<p>解释：@echo off 用于关闭命令提示，使脚本显示的有效信息更多。后文中的警告是为了防止有人误触脚本窗口致使执行中断，最后一行执行了 D 盘（假定为数据盘）下已存在的另一个脚本文件 startup.bat，从而自启动它。</p>



<pre class="wp-block-code"><code>::filename: startup.bat ; lang: Windows CMD
@echo off
echo 这是一个自启动的脚本.
cd D:\
D:
cd D:\widgets
start Widgets.MVP.exe</code></pre>



<p>解释：此文件即为你的自定义启动项，在我的案例中，我的小组件程序位于 D:\widgets\Widgets.MVP.exe，而直接用 start 启动它，会导致程序的执行目录不正确，因此我们先用 cd 命令定位到组件程序所在文件夹，有关为何切换盘符要再次书写盘符请参阅此处。</p>



<p>注意：你的程序应确保能在目标系统的环境中运行，你要先做好测试。我开发的上述 <a href="https://github.com/TekoDotIO/HiDesktop">HiDesktop</a> 项目依赖于 .NET 桌面运行时，故在编译时须<a href="https://www.cnblogs.com/yilezhu/p/9703460.html">以独立方式部署</a>，以规避希沃原生 Windows 10 缺失 .NET 环境的问题。</p>



<h2 class="wp-block-heading" id="三、进入-pe，修改文件。">三、进入 PE，修改文件。</h2>



<p>插入 U 盘启动一体机，开机完成后直接重启，看见“Press &lt;F2&gt; to setup, &lt;F7&gt; to boot menu.”字样时，按下遥控器的 F7 键进入启动菜单（不同品牌型号此处会有所不同），并用上下键选择装有 PE 的 U 盘分区（我的是分区 2），确定，Loading Files 完成后，即可顺利进入 PE 系统。</p>



<p>在 Windows PE 环境下，你会发现磁盘图标上并没有冰点图标——冰点还原并未生效，你可以自由修改文件了！</p>



<p>承接第二步，我们将 start.bat 放入启动文件夹 C:\ProgramData\Microsoft\Windows\Start Menu\Startup\ 中，将 startup.bat 放入 D 盘根目录“D:\”，并按预定计划放置小组件等程序，就成功构造了一个自启动项！</p>



<p>重启至正常系统，可以发现更改生效。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://p.imghz.com/2025/02/23/67ba7a5085b16.png" alt=""/></figure>



<p>其他的操作可自行进行，而有关前文中的几个应用案例，我也会择时写作发布。敬请关注喽~</p>



<h2 class="wp-block-heading" id="四、写在最后">四、写在最后</h2>



<p>本文遵循&nbsp;<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.zh-hans">CC-BY-NC-SA知识共享协议</a>&nbsp;。</p>



<p>转载请保留原作者署名（幻愿Recovery），禁作商业用途。</p>



<p class="has-text-color has-link-color has-medium-font-size wp-elements-dd8792a45b563cd560d96ff48796813b" style="color:#ff0000"><strong>再次声明：本文是实验性笔记内容，请作为参考使用。原作者不对读者行为造成的后果承担责任。</strong></p>



<p>文中可能用到第三方素材与互联网上收集的内容，如有侵权，请联系我们，我们会及时删除有关内容。</p>



<p>完成于 2025 年 2 月 10 日 21:32:37。</p>



<p>附：桌面路径：（Users 用户；Public 公用；Desktop 桌面）</p>



<pre class="wp-block-code"><code>C:\Users\(用户名)\Desktop\
C:\Users\Public\Desktop\</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/startup-with-recv/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>记一次希沃一体机装Win11 23H2的经历</title>
		<link>https://blog.eachother.work/seewo-win11-23h2/</link>
					<comments>https://blog.eachother.work/seewo-win11-23h2/#comments</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Wed, 22 Jan 2025 12:01:20 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=229</guid>

					<description><![CDATA[在一名电教的求生之路上，系统重装是一门必修课，在受够了希沃原生系统的各种运行库阉割和功能滞后，以及冰点还原的顶 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>在一名电教的求生之路上，系统重装是一门必修课，在受够了希沃原生系统的各种运行库阉割和功能滞后，以及冰点还原的顶级折磨后，我毅然决然地决定将我们班白板…隔壁的选修教室白板升级到 Windows 11 23H2。</p>



<p>咳…至于为什么不直接上本班的白板，我是基于自己的考量，俗话说，好事多磨，尽管我已不是第一个把白板刷上 Win11 的电教（那家伙实在是坑了我一次）（事后补充：具体情况具体分析，我只是自己遇到这个问题...！哎呦别打我...！），我还是没有把握能够一马平川地完成整个过程（后文也证实了这一点）。找到一个时机，寒假前最后一周，下午最后一节都是自由活动课，由于此时已是年休老师少（我想报备都找不到人），加之万一失败了还有一节课甚至一个假期时间来应对，又及这个教室陈年闲置，不知哪位先贤播下360的种子，已是开出了有燎原之势的全家桶广告之花，我便打算借这个机会将其重装，试水。</p>



<p>当然，我的操作已向年级主任所在班级的电教报备。</p>



<p><strong><mark style="background-color:rgba(0, 0, 0, 0);color:#fe1212" class="has-inline-color">如果有小伙伴希望一试，请务必先确保自己的人身安全，并做好资料备份工作与应急预案！</mark></strong></p>



<h2 class="wp-block-heading">0.准备工作/原料</h2>



<ul class="wp-block-list">
<li>一台工作正常的希沃一体机。</li>



<li>希沃一体机配备的遥控器（或用键盘代替）。</li>



<li><a href="https://firpe.cn/page-247">FirPE维护系统</a> 或 其他可用的 WinPE 。</li>



<li>一个U盘，大小 16GB 以上为宜，烧有上述 PE 维护系统。</li>



<li>Windows11 23H2简体中文版官方镜像，可以在 <a href="https://next.itellyou.cn/">Next,iTellYou</a> 或 <a href="https://www.microsoft.com/zh-cn/software-download/windows11">微软官网</a> 获取。</li>



<li><a href="https://firpe.cn/page-196">EasyRC 便携版</a>（包含在FirPE中）。</li>



<li>无线网络连接。这一点尤其重要！据考察，重装后我校LAN口IoT连接会失效，如无网络将无法完成激活、Office下载以及驱动下载！</li>



<li>(可选) 预下载的 IntelUHD 与 i5-8400 核显驱动程序 以及 Microsoft 365 离线安装包。在线下载用时可能较久。</li>



<li>(可选) 其他可选的 互联网配置 与 代理工具。如果你有可用的此类网络节点，建议拷贝待命。驱动下载时它可能是救命稻草。</li>



<li><a href="https://otp.landian.vip/zh-cn/">Office Tool Plus 工具</a>。</li>



<li>MAS 激活脚本 或其他可用的激活工具。具体下载方式请自行寻找。</li>



<li>一双手，敏捷的大脑，应变能力。</li>
</ul>



<p><strong><mark style="background-color:rgba(0, 0, 0, 0);color:#f90000" class="has-inline-color">△ 警告：再次强调，请在操作前确保人身安全，必要时进行报备，安装过程可能出现未知错误，需要较深的经验，不建议小白与云玩家上手。C盘资料会全部丢失，敬请备份。由本笔记带来的一切后果，与本站与作者无关！</mark></strong></p>



<h2 class="wp-block-heading">1.初期工作 - 一种故障的产生与解决方案。（可选）</h2>



<p>烧写带有 WinPE 的U盘，这一步 <a href="https://www.bmabk.com/index.php/post/268860.html">教程</a> 很多，也不太容易出错，我在本篇就不多赘述了。</p>



<p>这一步是可选的，出现的原因主要是，有趁这个空子找空教室玩白板的同学占领了我们的实验用机，因此，我们在早上制造了一些小混乱，以便后续操作。</p>



<p>插上U盘，正常开机，进入桌面后直接重启白板。等到白板出现启动界面 “Press &lt;F2&gt; to setup, &lt;F7&gt; to boot menu.” 时，按下遥控器的F7键，进入启动菜单，选择U盘 PE 所在分区（我的是在 Partition 2 )，回车，稍许等待后成功进入 WinPE 。值得一提的是，在 WinPE 里对硬盘进行的改动是可以线开冰点还原的。(有关这点的探究，我今后还会写文讲述)，因此对于有冰点的设备，本文依旧生效，我进入 “C:\Windows” ，将 explorer.exe 剪切到C盘根目录备份。这么一来，我们便制造了一个故障 —— 白板无法正常进入桌面。</p>



<p>但随后我们面临一个问题：没有重启的菜单，该如何进入 WinPE 呢？要知道，在希沃 LOGO ，即开机时按 F7 ，是无法进入启动菜单的，有的设备因引导损坏或无法进入系统，也会面临无法进入PE的问题，但这并非无解，我们上划屏幕，选 “通道” ，进入 HDMI 源而非 “内置电脑” ，随后长按电源键关机，再次开机。此时白板应当使用了上次使用的源，显示“无信号”，此时再次切回 “内置电脑” 源，白板的内置主机才会唤醒启动，这时，我们就可以看到 “&lt;F7&gt; to boot menu” 的页面了。</p>



<p>接下来，正式开始刷上 Win11 !</p>



<h2 class="wp-block-heading">2.Win11系统的基本部署。</h2>



<p>希沃一体机并不支持 TPM 2.0 平台，因此无法满足 Win11 的安装要求，然而，我们仍然可以用一些别的办法绕过这一检测，在一体机上“硬上” Win11 。</p>



<p>我用的是 FirPE 自带的 EasyRC 软件，这个软件在部署系统的同时，也可以跳过一大堆无用的设置环节，省时省力，也免得卡在网络或账户环节。</p>



<p>进入 EasyRC ，选中镜像，切换系统为 Windows 11 专业版 ，选择C盘（请注意观察盘符，不要把镜像放在即将安装的磁盘！)，确认无误后开始重装，这个过程是自动的，大概要 25 ~ 30 分钟，你可以先去吃个饭，泡杯茶。后面麻烦的事还不少。</p>



<p>与此同时，一体机会自己准备设备，启动服务，进入 OOBE ，最后进入桌面。</p>



<h2 class="wp-block-heading">3.驱动程序与基本系统设置。</h2>



<p>现在，不出意外地， Windows 的天坑：驱动程序，出意外了。不出所料的话，我们正面对着一块 800 × 600 的致命比例屏幕，并且分辨率和缩放设置统统无法使用，这是 Intel 的核显驱动丢失所致。所幸 WLAN ，触摸和 USB 都能正常工作（也只是正常工作而已，驱动也是残缺的）。</p>



<p>我们直接在 Intel 的官网下载 <a href="https://www.intel.cn/content/www/cn/zh/support/detect.html">英特尔® 驱动程序和支持助理</a> 即可。这一点也有点迷啊， Intel 的下载中心在我的尝试中，速度奇慢，并且搜索结果还有未登录限制，戴尔的官网上似乎有一个可用的驱动，但不是核显的也于事无补，而至于国内的几个驱动助手。我的建议是不要用。下得慢逼你开一个根本用不到的会员不说，还指不定哪天给你捆绑得满屏一刀999（ ）</p>



<p>这里我比较建议用代理加速下载，先装上软件，丢入订阅链接（此部分不作详细解释，请自行探索），选择线路，开启系统代理。我用的工具是 Clash For Windows ，实测要开启 TUN 才能对那个面板生效。在 CFW 主页点击“服务模式”的“管理”，直接安装。 CFW 很快会重启，如果“服务模式”右侧的小地球变绿了，即安装成功。打开 TUN模式 的开关， Clash 的虚拟网卡就会接管设备的网络（一开始系统角标可能提示断网，能打开<a href="http://google.com">特征网站</a>即可，无需在意）。在这之后，开始 / 重新开始 面板中驱动的下载，速度应当大幅提升。</p>



<p>在核显驱动补全后，一体机会短暂黑屏，而后来到 1920*1080 的分辨率。我选择把显示设置开到 3840*2160 的 4K 分辨率，缩放 200% ，虽然没有 60Hz 的刷新率，但上台操作会舒服许多。同样，安装声卡和网卡的新版驱动，系统安装的大部分步骤便完成了。</p>



<p>同时也记录一部分遇到的问题。</p>



<p>Q：没法输入文字，虚拟键盘没有正常呼出，右下角键盘图标消失。<br>A:长按任务栏，在“任务栏设置”中启用键盘与触摸板。顺便也可以关掉些无用的图标。<br>Q：CFW中大部分代理超时。<br>A：如果你们的局域网没有特别屏蔽这类服务，可能是卡DNS了，参阅<a href="https://sobaigu.com/clash-timeout-failed-by-dns.html">本文</a>。<br>Q：没有声音/外置设备失灵。<br>A：驱动缺失。这会在驱动补全后得到修复。<br>Q：桌面上出现捆绑应用/广告。<br>A：可能是用了非官方镜像/恶意PE软件所致。强烈建议使用原版镜像与FirPE等纯净的维护工具。<br>Q：下载的文件莫名消失/打不开。<br>A：检查下，如果是在压缩包里，先拖出来再打开，激活脚本/注册机之类程序可能会被 Windows安全中心娘 吃掉（雾）。下个火绒安全让它接管，或者打开开始菜单，所有应用， Windows安全中心 ，防护选项，把几个防护（实时扫描等）全关掉即可。（当然前提是你确保文件可信安全）</p>



<p>P.S. 我在这一步上也是被另一位电教坑惨了。（事后补充：具体情况具体分析，我只是自己遇到这个问题...！哎呦别打我...！）据他所言，驱动之类“只要开 Windows Update 补全就好了。” 结果我试了下，in my case，它根本识别不了这是什么设备，更不用说装驱动了更新就装了几个补丁完事。后面国外站驱动下得死慢，要不是我随身带了CFW和订阅估计都暴毙了。（）</p>



<h2 class="wp-block-heading">4.后续部署激活，Office和希沃软件。</h2>



<p>OS 激活和 Office 激活都可以用 MAS 。这个话题请自行探索。</p>



<p>可以用 <a href="https://otp.landian.vip/zh-cn/">Office Tool Plus</a> 来轻松地部署 PPT 和 Word 等软件。不太建议在一体机上用 WPS ，这软件自己其实就有点捆绑软件的通病，对触摸的支持也实在不友好。 Microsoft Office 就我个人而言，还是一体机的最佳选择。打开 Office Tool Plus，部署，添加产品，Microsoft 365 企业版，体系结构改为64位，安装方式改为 Office Tool，开始部署。接下来就是漫长的等待了。一切就绪后，激活，点开一个 Office 软件，接受协议，就OK了。</p>



<p>对于我校而言，希沃的软件有 希沃白板 一个就足矣。可以在 <a href="https://e.seewo.com/">易+官网</a> 轻松地找到安装包。实测了一下，以前装过 希沃白板 的设备，即使重装，白板的授权也是不会掉的，安装打开也是直接进 白板模式 。用不着担心不登录就用不了之类的。 班级优化大师 、 希沃视频展台 等也可以在 <a href="https://e.seewo.com/">此处</a> 找到，如果你嫌麻烦，也可以直接在他们的官网下载 “电子白板全家桶” 一键安装。</p>



<p>值得注意的是，据说装了 希沃管家 后，集控那边开了 冰点还原 的话，又会给你锁回去（当然还是 Win11 ，只是定格在了装好管家的一次启动），因此建议把这个放在一切的最后，这也是我没装全家桶的原因。当然这个我也只是道听途说。而另一位电教称，重装会直接脱控，要学校老师来重新连接过，管家才会生效，真实与否，我就不得而知了。如果有小伙伴知道答案，欢迎在评论区留言口牙~</p>



<h2 class="wp-block-heading">5.写在最后</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>“我们一直奔跑，我们也曾跌倒。但如此挫折，岂能挡住少年前进的步伐？冰点还原，冰不住炽热的心；扫码解锁，锁不了出逃的魂。不忘初心，踔厉奋发——愿这方寸屏幕永是净土，愿这青春野心终不辜负。”</p>
<cite>Bilibili up主：<a href="https://www.bilibili.com/opus/732839107268444241">刻御晴空</a></cite></blockquote>



<p>这个方案并不是完美无缺的。一些希沃独有的驱动无法被安装，长按关机之类的一小部分几乎无用的功能也是一直处于失效状态，但这次历练也确实是我电教生涯的，乃至技术生涯的重要一步。至少在被流氓软件的广告逼得团团转的老师面前，我自此可以勇敢地举起手: “我会，我修过，让我来！”</p>



<p>本文遵循 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.zh-hans">CC-BY-NC-SA知识共享协议</a> 。</p>



<p>转载请保留原作者署名（幻愿Recovery），禁作商业用途。</p>



<p><strong><mark style="background-color:rgba(0, 0, 0, 0);color:#fa0000" class="has-inline-color">再次声明：本文是实验性笔记内容，请作为参考使用。原作者不对读者行为造成的后果承担责任。</mark></strong></p>



<p>文中可能用到第三方素材与互联网上收集的内容，如有侵权，请联系我们，我们会及时删除有关内容。</p>



<p>完成于 1 月 22 日  20 : 01 : 45 。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/seewo-win11-23h2/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>【旧文重发】ASP.NET+MVC入门踩坑笔记 ：创建项目 项目配置运行 以及简单的Api搭建</title>
		<link>https://blog.eachother.work/aspnet-junior/</link>
					<comments>https://blog.eachother.work/aspnet-junior/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Thu, 06 Jan 2022 14:07:03 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=159</guid>

					<description><![CDATA[本文于2022-01-06 22:07以“枫叶1003”的名称在博客园首次发布，此处仅做存档。（点击此处阅读原 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>本文于2022-01-06 22:07以“枫叶1003”的名称在博客园首次发布，此处仅做存档。（<a href="https://www.cnblogs.com/fengye1003/p/aspdotnet_mvc_01.html" data-type="link" data-id="https://www.cnblogs.com/fengye1003/p/aspdotnet_mvc_01.html">点击此处阅读原文</a>）</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p>前段时间研究了下ASP.NET,刚开始也是随便找网上的各种教程来看,但是鉴于本人技术有限,还是走了相当长的一段弯路的.所以我写下了这篇文章.希望各位刚刚入坑的ASP.NET开发者们能够少走弯路,专业的开发者也请给予指点,谢谢各位了.</p>



<p>PS:本人没有系统地学过ASP.NET(因为我是学生党55555)以及.NET知识,也是通过探索略知一二,文中可能不准确的表达和术语,恳请大佬们指正.</p>



<p>好了 正片开始喽</p>



<h2 class="wp-block-heading">#1 从创建项目说起</h2>



<p>阅读本章节 , 你将了解到 :</p>



<p>-如何在VS配置ASP.NET环境</p>



<p>-如何创建一个基本的ASP.NET项目</p>



<p>如果各位学习过 C# , 就一定知道 VS 是什么东西,即 Visual Studio , 本机演示版本为 2022 . ASP.NET 要求微软提供的 .NET Core 框架与 SDK . 你可以直接在 Visual Studio Installer 里面找到 ASP.NET 和 Web 开发 , 直接勾选它们并且安装即可 .</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639631-651526362.png" alt=""/></figure>



<p>下载安装后 , 你就可以在"创建新项目"时找到 ASP.NET模板了.</p>



<p>我们这里使用 MVC Api 框架 , 所以选择 ASP.NET Core Web Api .</p>



<p>如果你正在使用 vs2019 , 那么你需要创建的是 ASP.NET Core 应用程序 , 并且在创建项目后弹出的对话框内选择 Api .&nbsp;</p>



<p>(当然 , 如果你要选择另一个带有 MVC 的也可以)</p>



<p>框架版本什么的可以自己选 , 个人喜欢 .NET 3.1 Core . 当然 , 如果你要用顶级语句等高版本 C# 才支持的功能 , 那么 .NET 6.0 请.</p>



<p>配置 HTTPS 的话视具体情况而定 . 个人喜欢关掉 .</p>



<p>万事俱备以后 , 点击"创建" , 一个新的 ASP.NET 项目就 duang 的一下诞生了 !</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639567-83423047.png" alt=""/></figure>



<h2 class="wp-block-heading">#2 配置调试器 , 以及编译/执行文件方面的说明</h2>



<p>阅读本章节 , 你将了解到 :</p>



<p>-如何使用命令行调试ASP.NET应用程序</p>



<p>-如何启动ASP.NET应用程序</p>



<p>-如何允许外网访问Api</p>



<p>关于调试 :&nbsp;</p>



<p>大家可能已经看到 , VS2019 与 VS2022 对 ASP.NET 项目的默认调试配置是 "IIS Express". 这确实是微软所推荐的调试 ASP.NET 应用程序的最佳选项 , 但是经过一段时间的使用 , 我的感受只能用三个字来概括 : "糟透了" .</p>



<p>首先 IIS Express 默认是不提供命令窗口的 , 这意味着你无法查看你的程序用 Console.WriteLine() 所输出的日志 .</p>



<p>其次 , IIS Express 对性能并不友好 . 本人使用的是渣机 , 因此不知道中高端机器的 IIS Express 是否也受到此问题的困扰 : 点击调试以后 , IIS Express 和浏览器窗口确实第一时间启动了 , 但是从它开始启动到能够正常调试 , 几乎需要加载两分钟 ! 而如果直接双击生成的 exe 文件执行 , 从启动到服务状态只需要5秒左右 .</p>



<p>最后 , 也是我放弃 IIS Express 的原因 , 我有一次使用 IIS Express 调试时 , 发现无法启动 IIS Express 了 , 并且给了我一个报错 : "尝试启动 IIS Express时出现以下问题" . 没错 , 就那么一个提示框 , 上面也只有这么几个字 . 至于它所说的 "以下问题" , 我这辈子可能都不会知道了 . 尽管重装系统后发现这个问题解决了 , 但是我已经对其产生了抵触 .</p>



<p>好了 , 说了那么多 , 接下来就讲讲如何将调试程序设置为直接启动 exe 程序吧 . (喜欢IIS Express的同志们忽略即可)</p>



<p>首先我们点击调试框右侧的箭头 , 展开调试菜单 . 然后点击 "[项目名称] 调试属性" 进入配置文件编辑页面.如下图</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639592-282160045.png" alt=""/></figure>



<p>接着 , 新建一个 "项目" 类型的配置文件 , 命名可以随意 .</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639548-802446398.png" alt=""/></figure>



<p>而后 , 将页面滚动到下侧 , 勾选 "启动浏览器" 并将 URL 修改为 http://localhost:5000 . 如下图</p>



<p>(关于为什么使用 5000 端口 : IIS Express 所指定的端口并不是 5000 , 但是如果你使用命令行方式启动编译后的程序 , 其默认分配的端口即是 5000 端口 (Now listening on localhost:5000) .</p>



<p>如果 5000 端口被占用了 , 可以设置命令行参数 "-urls http://*:[可用的端口号]" , 端口号可以视具体情况而定 . 下面的启动浏览器 URL 中的端口号也要一起改 . )</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639567-661111551.png" alt=""/></figure>



<p>最后 , 如下图 , 在配置文件菜单选择刚刚创建的配置文件 , 就可以通过快捷按钮启动命令行方式的调试啦 !</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639576-692950799.png" alt=""/></figure>



<p>关于编译出来的程序 :&nbsp;</p>



<p>大家可能已经试过了 , 调试时 , 你没有办法从局域网内通过 IP+端口的方式访问正在运行的 Api . 实际编译出来的程序也是如此 , 初始状态下只能从 localhost , 也就是本机进行访问 , 如果你从外部访问 , 就会出现 "xxx拒绝了我们的连接" . 那么 , 如何解决这个问题 , 使得来自所有 IP 的设备来访问已经编译完成的 Api 呢 ?</p>



<p>解决方案有很多种 .&nbsp;</p>



<p>其一就是通过 IIS 部署 Api , 这也是比较主流的方式 , 比较适合需要多次更新应用程序以及有一个集中管理后台的开发者们 . 网上这方面的文章很多 , 但是如果你自己配置 , 并且不太懂 IIS 的运行原理 , 那么就很有可能配置出错 (反正我是直接用不了 , 所以就不多介绍这个方法) .</p>



<p>其二就是给 .NET 添加启动参数 , 这里着重介绍一下 .</p>



<p>首先把你的整个编译后输出的文件夹拷贝到你的服务器上 (本地打开也可以) , 然后检查你的 .NET 版本 . 特别要注意 , 服务器上要预先安装好与项目目标平台的 .NET Core for Servers.</p>



<p>然后用 cmd 定位到目录下 , 执行</p>



<pre class="wp-block-code has-small-font-size"><code>dotnet &#91;项目名称].dll --urls http://*:&#91;端口号]</code></pre>



<p>比方说我的项目的 dll 文件是 project.dll , 文件位于 C:\wwwroot\project.dll , 需要部署到 5000 端口 , 那么我就应该执行</p>



<pre class="wp-block-code has-small-font-size"><code>cd C:\wwwroot\
dotnet project.dll --urls http://*:5000</code></pre>



<p>当然你如果嫌这样太麻烦 , 你也可以写一个 cmd 脚本 (批处理文件) 来执行命令 .</p>



<p>如下图 , 出现了运行提示 , 就是成功了 .</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639621-930651696.png" alt=""/></figure>



<p>如果你发现报错 "'dotnet' 不是内部或外部命令，也不是可运行的程序或批处理文件。" 或者是一个带链接的运行库错误 , 那么需要去微软官网下载对应版本的 .NET Core 运行库 , 记得一堆要下载服务器 (Server) 版本的 , 就是旁边带 "Run Server Apps" 的包 .</p>



<p>微软 .NET 官网 :&nbsp;<a href="https://dotnet.microsoft.com/zh-cn/download/dotnet" target="_blank" rel="noreferrer noopener">点击前往</a></p>



<h2 class="wp-block-heading">#3 配置 API 路由 , 创建不带参数的 GET 方法</h2>



<p>阅读本章节 , 你将了解到 :</p>



<p>-如何配置ASP.NET MVC路径</p>



<p>-如何创建基本的ASP.NET接口</p>



<p>-如何通过浏览器调试基础的ASP.NET项目</p>



<p>-控制器(Controller)该如何使用</p>



<p>项目创建好了 , 接下来就是开始敲代码咯 (激动) .</p>



<p>来到 VS 右侧的解决方案资源管理器 , 展开 Controllers文件夹 , 这里用于存放你的 Api 控制器 , 借助控制器 , 你才能通过类似 localhost:5000/api/core/method 的 URL 访问到你的 Api 方法 . 在以上链接中 , core 就是你的控制器名称 , 而后面的 Method 则是方法名称 .</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639541-116230379.png" alt=""/></figure>



<p>控制器文件的名称以及文件内控制器的名称可以随意更改 , 建议二者保持一致 .&nbsp;</p>



<p>另外 , 这里要特殊强调的是 , 控制器名称末尾必须带有 Controller 字样 . 并且应当添加继承 ":ControllerBase" , 如下图所示 .</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639576-1317013459.png" alt=""/></figure>



<p>其中 , Api 是控制器名称 .</p>



<p>当然你可能也注意到了 , 在控制器上面还有一行 Route 代码 , 这也就是我们所说的路由设置 .</p>



<p>那么什么是路由设置呢 ? 举这样一个例子 : 假如控制器 Api 下有一个 Index() 方法 , 如下所示设置路由</p>



<pre class="wp-block-code has-small-font-size"><code>&#91;ApiController]
&#91;Route("&#91;controller]/&#91;action]")]
public class ApiController : ControllerBase
    {
        &#91;HttpGet]
        public ActionResult&lt;string&gt; Index()
        {
            return "Hello world!";
        }
    }</code></pre>



<p>此时 , 路由就是 [controller]/[action] . 假使应用程序在 localhost:5000 运行 , 请问 , 我该如何访问 Index() 方法并得到返回值 "Hello world!" 呢 ? (无奖竞猜)</p>



<p>没错 , 我们应该访问 localhost:5000/Api/Index</p>



<p>值得一提的是 , 控制器以及后面要讲的参数和原生 C# 不同 , 它们对大小写不敏感 , 例如 Api 和 api 在实际上是同一个控制器 , 而以下写法:</p>



<p>localhost:5000/api/Index</p>



<p>localhost:5000/Api/Index</p>



<p>localhost:5000/Api/index</p>



<p>localhost:5000/api/index</p>



<p>对于 ASP.NET 控制器而言 , 这些写法指向的控制器以及方法都是一致的 , 都是位于 Api 或 api 控制器下的 Index() 或 index() 方法.</p>



<p>我们再次设置路由 , 如下 :</p>



<pre class="wp-block-code has-small-font-size"><code>&#91;ApiController]
    &#91;Route("api/&#91;controller]/&#91;action]")]
    public class ApiController : ControllerBase
    {
        &#91;HttpGet]
        public ActionResult&lt;string&gt; Index()
        {
            return "Hello world!";
        }
    }</code></pre>



<p>好了 , 这次你知道应该如何访问 Index() 方法了吗 ?</p>



<p>正解 : localhost:5000/api/Api/Index</p>



<p>如上 , 前面的一个 api 是既定的路径 , 后面的 Api 代表 Api 控制器 , 而 Index() 表示该控制器下的 Index() 方法 .</p>



<p>return 语句在这里就是返回值 , 即显示在浏览器上的信息 .</p>



<p>[HttpGet] 语句定义了 Index() 是一个 GET 类型的 HTTP 协议 Api</p>



<p>同理 , 我们来制作一个简单的用于获取时间的 Api .</p>



<pre class="wp-block-code has-small-font-size"><code>using System;
using Microsoft.AspNetCore.Mvc;//MVC框架

namespace ApiDemo.Controllers
{
    &#91;ApiController]//声明控制器
    &#91;Route("api/&#91;controller]/&#91;action]")]//设置路由
    public class ApiController : ControllerBase//定义Api控制器
    {
        &#91;HttpGet]//使用GET HTTP方法
        public ActionResult&lt;string&gt; GetTime()//定义方法
        {
            return DateTime.Now.ToString();//调用System.DateTime.Now获取当前时间并输出
        }
    }
}
</code></pre>



<p>到此为止 , 一个简单的 ASP.NET 应用程序就制作完成啦 .</p>



<p>我们尝试运行一下 .</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202201/2547887-20220106220639548-2137489416.png" alt=""/></figure>



<p>成功了 !</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/aspnet-junior/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【旧文重发】在树莓派用C#+Winform实现传感器监测</title>
		<link>https://blog.eachother.work/openenvlite/</link>
					<comments>https://blog.eachother.work/openenvlite/#respond</comments>
		
		<dc:creator><![CDATA[幻愿Recovery]]></dc:creator>
		<pubDate>Mon, 20 Sep 2021 01:07:10 +0000</pubDate>
				<category><![CDATA[技术向]]></category>
		<guid isPermaLink="false">http://eachother.work/?p=151</guid>

					<description><![CDATA[此篇博文于2021-09-20 09:07 使用“枫叶1003”的名称首次发布于博客园。（点击此处阅读原文）  [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>此篇博文于2021-09-20 09:07 使用“枫叶1003”的名称首次发布于博客园。（<a href="https://www.cnblogs.com/fengye1003/p/15313595.html" data-type="link" data-id="https://www.cnblogs.com/fengye1003/p/15313595.html">点击此处阅读原文</a>）</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p>最近学校里发了个任务，说要做一个科技节小发明，然后我就掏出我的树莓派准备大干一场。</p>



<p><strong>调料</strong></p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202109/2547887-20210919083536795-612789160.png" alt=""/></figure>



<p>Raspberry Pi 3B+<br>树莓派GPIO扩展板<br>3.5寸电容触摸屏（GPIO接口）<br>土壤湿度传感器（GPIO接口）<br>光照传感器（GPIO接口）<br>由于作品已经交上去了 这里只能先放个以前的图</p>



<p>这里展示的是土壤湿度传感器，光照传感器道理一样</p>



<p><strong>第一步 安装mono</strong></p>



<p>树莓派不能直接运行C#图形化应用程序，去网上搜了一下解决方案，WPF框架是肯定没戏，不过我看到了一个叫mono的项目，可以在Linux平台运行Winform程序，还有这等好事？！赶紧整！</p>



<p>国际惯例哈，更新软件源<br><code>sudo apt-get update</code><br>然后执行安装命令<br><code>sudo apt-get install mono-complete -y</code><br>如果没法安装就检查你的软件源是否包含mono，我个人推荐清华大学的开源镜像站<br>最后我们检查是否安装成功<br><code>mono</code><br>如果不报错，就是安装成功了</p>



<p><strong>第二步 探索GPIO</strong></p>



<p>环境搭建好了，然而我对GPIO接口所知甚少，还是上网查查<br>连接传感器，首先是单片机和检测头的连接，母对母两条杜邦线搞定<br>然后是树莓派和单片机，VCC接3.3V或者5V，GND接树莓派GND，DO接任意GPIO空闲接口<br>树莓派的GPIO对应表可以在网上搜或者看下面的字符画</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202109/2547887-20210919222016955-685584182.png" alt="" style="width:636px;height:auto"/></figure>



<p>一开始使用CSDN上某个大佬的GPIO类<br><a href="https://www.cnblogs.com/fengye1003/p/15313595.html">https://blog.csdn.net/weixin_30878361/article/details/97233437</a><br>结果测试了好久都抛异常，如果哪位大佬知道如何调用可以在评论区告诉我，感谢</p>



<p>于是我果断放弃了这个现成的类库，然后去读了下传感器的文档，发现文档里有一个很有意思的命令<br><code>gpio readall</code><br></p>



<p>赶紧跑到树莓派终端上，运行它！</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p style="font-size:0.8rem">pi@raspberrypi:~ $ gpio readall<br>+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+<br>| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |<br>+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+<br>| | | 3.3v | | | 1 || 2 | | | 5v | | |<br>| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |<br>| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |<br>| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |<br>| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |<br>| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |<br>| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |<br>| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |<br>| | | 3.3v | | | 17 || 18 | 1 | OUT | GPIO. 5 | 5 | 24 |<br>| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |<br>| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 1 | OUT | GPIO. 6 | 6 | 25 |<br>| 11 | 14 | SCLK | ALT0 | 1 | 23 || 24 | 0 | OUT | CE0 | 10 | 8 |<br>| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |<br>| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |<br>| 5 | 21 | GPIO.21 | IN | 0 | 29 || 30 | | | 0v | | |<br>| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |<br>| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |<br>| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |<br>| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |<br>| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |<br>+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+<br>| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |<br>+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+</p>
</blockquote>



<p>从这里看可能不太直观哈，放个图</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202109/2547887-20210919215731160-780382991.png" alt=""/></figure>



<p>然后把传感器从水里拿出来，再次readall</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p style="font-size:12px">pi@raspberrypi:~ $ gpio readall<br>+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+<br>| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |<br>+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+<br>| | | 3.3v | | | 1 || 2 | | | 5v | | |<br>| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |<br>| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |<br>| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |<br>| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |<br>| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |<br>| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |<br>| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |<br>| | | 3.3v | | | 17 || 18 | 1 | OUT | GPIO. 5 | 5 | 24 |<br>| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |<br>| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 1 | OUT | GPIO. 6 | 6 | 25 |<br>| 11 | 14 | SCLK | ALT0 | 1 | 23 || 24 | 0 | OUT | CE0 | 10 | 8 |<br>| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |<br>| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |<br>| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |<br>| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |<br>| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |<br>| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |<br>| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |<br>| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |<br>+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+<br>| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |<br>+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+</p>
</blockquote>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202109/2547887-20210919220014319-536482242.png" alt=""/></figure>



<p>可以看到BCM为6，接口号29发生了变化，在水中是0，不在水中是1.<br>OK 搞清楚了，接下来就好办了</p>



<p><strong>第三步 撰写代码</strong></p>



<p>首先写个UI，没UI设计头脑的我就简单粗暴解决了</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://img2020.cnblogs.com/blog/2547887/202109/2547887-20210919222108740-1952735383.png" alt=""/></figure>



<pre class="wp-block-code" style="font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.042), 0.9rem);"><code>namespace OpenEnvLite
{
partial class Form1
{
///


/// 必需的设计器变量。
///

private System.ComponentModel.IContainer components = null;
    /// &lt;summary&gt;
    /// 清理所有正在使用的资源。
    /// &lt;/summary&gt;
    /// &lt;param name="disposing"&gt;如果应释放托管资源，为 true；否则为 false。&lt;/param&gt;
    protected override void Dispose(bool disposing)
    {
        if (disposing &amp;&amp; (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows 窗体设计器生成的代码

    /// &lt;summary&gt;
    /// 设计器支持所需的方法 - 不要修改
    /// 使用代码编辑器修改此方法的内容。
    /// &lt;/summary&gt;
    private void InitializeComponent()
    {
        this.title = new System.Windows.Forms.Label();
        this.土壤湿度 = new System.Windows.Forms.Label();
        this.土壤湿度显示 = new System.Windows.Forms.Label();
        this.亮度 = new System.Windows.Forms.Label();
        this.亮度显示 = new System.Windows.Forms.Label();
        this.label2 = new System.Windows.Forms.Label();
        this.label1 = new System.Windows.Forms.Label();
        this.button2 = new System.Windows.Forms.Button();
        this.SuspendLayout();
        // 
        // title
        // 
        this.title.AutoSize = true;
        this.title.Font = new System.Drawing.Font("宋体", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.title.ForeColor = System.Drawing.Color.White;
        this.title.Location = new System.Drawing.Point(12, 36);
        this.title.Name = "title";
        this.title.Size = new System.Drawing.Size(187, 29);
        this.title.TabIndex = 1;
        this.title.Text = "土壤属性探测";
        // 
        // 土壤湿度
        // 
        this.土壤湿度.AutoSize = true;
        this.土壤湿度.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.土壤湿度.ForeColor = System.Drawing.Color.White;
        this.土壤湿度.Location = new System.Drawing.Point(43, 89);
        this.土壤湿度.Name = "土壤湿度";
        this.土壤湿度.Size = new System.Drawing.Size(94, 21);
        this.土壤湿度.TabIndex = 6;
        this.土壤湿度.Text = "土壤湿度";
        // 
        // 土壤湿度显示
        // 
        this.土壤湿度显示.AutoSize = true;
        this.土壤湿度显示.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.土壤湿度显示.ForeColor = System.Drawing.Color.White;
        this.土壤湿度显示.Location = new System.Drawing.Point(143, 89);
        this.土壤湿度显示.Name = "土壤湿度显示";
        this.土壤湿度显示.Size = new System.Drawing.Size(73, 21);
        this.土壤湿度显示.TabIndex = 7;
        this.土壤湿度显示.Text = "检测中";
        // 
        // 亮度
        // 
        this.亮度.AutoSize = true;
        this.亮度.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.亮度.ForeColor = System.Drawing.Color.White;
        this.亮度.Location = new System.Drawing.Point(63, 110);
        this.亮度.Name = "亮度";
        this.亮度.Size = new System.Drawing.Size(52, 21);
        this.亮度.TabIndex = 8;
        this.亮度.Text = "亮度";
        // 
        // 亮度显示
        // 
        this.亮度显示.AutoSize = true;
        this.亮度显示.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.亮度显示.ForeColor = System.Drawing.Color.White;
        this.亮度显示.Location = new System.Drawing.Point(143, 110);
        this.亮度显示.Name = "亮度显示";
        this.亮度显示.Size = new System.Drawing.Size(73, 21);
        this.亮度显示.TabIndex = 9;
        this.亮度显示.Text = "检测中";
        // 
        // label2
        // 
        this.label2.AutoSize = true;
        this.label2.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.label2.ForeColor = System.Drawing.Color.White;
        this.label2.Location = new System.Drawing.Point(27, 174);
        this.label2.Name = "label2";
        this.label2.Size = new System.Drawing.Size(189, 21);
        this.label2.TabIndex = 10;
        this.label2.Text = " 微型土壤探测系统";
        // 
        // label1
        // 
        this.label1.AutoSize = true;
        this.label1.Cursor = System.Windows.Forms.Cursors.Default;
        this.label1.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.label1.ForeColor = System.Drawing.Color.White;
        this.label1.Location = new System.Drawing.Point(27, 142);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(189, 21);
        this.label1.TabIndex = 10;
        this.label1.Text = "相互科技 版权所有";
        // 
        // button2
        // 
        this.button2.BackColor = System.Drawing.Color.Black;
        this.button2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        this.button2.ForeColor = System.Drawing.Color.White;
        this.button2.Location = new System.Drawing.Point(191, 26);
        this.button2.Name = "button2";
        this.button2.Size = new System.Drawing.Size(74, 39);
        this.button2.TabIndex = 13;
        this.button2.Text = "刷新";
        this.button2.UseVisualStyleBackColor = false;
        this.button2.Click += new System.EventHandler(this.button2_Click);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.BackColor = System.Drawing.Color.Black;
        this.ClientSize = new System.Drawing.Size(266, 235);
        this.Controls.Add(this.button2);
        this.Controls.Add(this.label1);
        this.Controls.Add(this.label2);
        this.Controls.Add(this.亮度显示);
        this.Controls.Add(this.亮度);
        this.Controls.Add(this.土壤湿度显示);
        this.Controls.Add(this.土壤湿度);
        this.Controls.Add(this.title);
        this.ForeColor = System.Drawing.Color.White;
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        this.Name = "Form1";
        this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
        this.Text = "Form1";
        this.TopMost = true;
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.Label title;
    private System.Windows.Forms.Label 土壤湿度;
    private System.Windows.Forms.Label 土壤湿度显示;
    private System.Windows.Forms.Label 亮度;
    private System.Windows.Forms.Label 亮度显示;
    private System.Windows.Forms.Label label2;
    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.Button button2;
}
}</code></pre>



<p>这是设计器代码 然后是主要代码</p>



<pre class="wp-block-code" style="font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.042), 0.9rem);"><code>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Globalization;
using System.IO;
using System.Diagnostics;
using System.Collections;

namespace OpenEnvLite
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

    public static string Bash(string command)
    {
        var escapedArgs = command.Replace("\"", "\\\"");
        var process = new Process()
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "/bin/bash",
                Arguments = $"-c \"{escapedArgs}\"",
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true,
            }
        };
        process.Start();
        string result = process.StandardOutput.ReadToEnd();
        process.WaitForExit();
        process.Dispose();
        return result;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        string SenseWater = Bash("gpio readall");
        if (SenseWater.Contains("|   5 |  21 | GPIO.21 |   IN | 0 | 29 |"))
        {
            土壤湿度显示.Text = "湿度正常";
        }
        else
        {
            土壤湿度显示.Text = "湿度过低";
        }
        string SenseLight = Bash("gpio readall");
        if (SenseLight.Contains("| 40 | 1 | IN   | GPIO.29 | 29  | 21  |"))
        {
            亮度显示.Text = "亮度过低";
        }
        else
        {
            亮度显示.Text = "亮度正常";
        }
    }
}
}</code></pre>



<p>搞定！<br>如果要调节传感器的灵敏度可以用十字起子转动单片机上的电阻。<br>光敏电阻和湿度电阻道理是一样的。<br>最后导入exe文件到树莓派，使用mono运行<br><code>mono -run test.exe</code><br>test.exe换成自己程序的名字，运行后点击刷新可以正常显示<br>大功告成！</p>



<p>该项目在gayhub 啊不github开源：<br><a href="https://www.cnblogs.com/fengye1003/p/15313595.html">https://github.com/fengye1003/OpenEnvLite</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.eachother.work/openenvlite/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
