5 Commits

8 changed files with 52 additions and 269 deletions
-3
View File
@@ -1,3 +0,0 @@
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
-42
View File
@@ -1,42 +0,0 @@
name: 构建二进制可执行文件
on:
workflow_dispatch:
pull_request:
paths:
- "language.cs"
# 只在源代码被更新时运行
push:
paths:
- "language.cs"
jobs:
build:
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
artifact: language
- runner: ubuntu-26.04-arm
artifact: language_arm
steps:
- uses: actions/checkout@v7
- name: 编译
run: |
docker run --rm \
-v "${{ github.workspace }}":/src \
-w /src \
alpine:latest /bin/sh -c '
apk update
apk add build-base dotnet10-sdk clang
dotnet publish language.cs /t:Rebuild --disable-build-servers --force '
- name: 重命名
if: ${{ matrix.runner == 'ubuntu-26.04-arm' }}
run: sudo mv artifacts/language/language artifacts/language/language_arm
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: artifacts/language/${{ matrix.artifact }}
+5 -2
View File
@@ -1,2 +1,5 @@
.vscode
artifacts
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
/.vs
-11
View File
@@ -1,11 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
+16 -65
View File
@@ -1,74 +1,25 @@
## 简介
将Linux的系统语言切换到简体中文
# 一键切换Ubuntu系统到简体中文
## 这个程序有且仅在Ubuntu系统上测试过,18.04及以上应该都不会有问题,非Debian系列应该都用不了
## 支持的系统
- Debian
- Armbian
- Ubuntu
- Arch Linux
- CachyOS
***
## 测试通过的系统
### **x86_64**
| 系统名称 | 版本 |
| - | - |
| Debian | 13.2 <br/> 11.6 |
| Ubuntu | 26.04 LTS <br/> 25.10 <br/> 25.04 <br/> 24.10 <br/> 24.04.1 LTS <br/> 22.04 LTS <br/> 20.04 LTS |
| Arch Linux | 滚动发行 |
### **aarch64**
| 系统名称 | 版本 |
| - | - |
| Debian | 11.5 |
## 编程语言
C++
原本shell那个版本已经被彻底淘汰了,因为我从头到尾就不会bash,用cpp还能做更多设置
***
## 使用方法
### **x86_64**
确保已经安装wget或者有其他方法可以传输文件
```shell
sudo su
wget https://github.com/TheWhiteDog9487/lag2cn/releases/latest/download/language
chmod +x language
./language
rm language
apt update && apt install -y wget
```
### **aarch64**
***
下载程序
```shell
sudo su
wget https://github.com/TheWhiteDog9487/lag2cn/releases/latest/download/language_arm
chmod +x language_arm
./language_arm
rm language_arm
wget https://raw.githubusercontent.com/TheWhiteDog9487/ubuntu-language-onekey-zh_cn/main/language
```
## 关于可用性
对每一个系统版本进行实际测试是不现实的,我会尽量保证可用性,但是更新之后的测试只会在最新版本进行
并且,由于各种系统版本众多来源复杂,哪怕是最新版本也未必100%可用
故此,如果您在使用过程中遇到问题,请在GitHub仓库打开一个新的issue,我会尽力处理
## 如果你想自行编译
所需依赖项:
- .NET 10 SDK
- Clang
- build-base或其他等效工具集
推荐使用Alpine Linux进行编译,因为Alpine的系统libc就是musl,编译出的产物可以直接用而不需要管目标系统glibc的版本问题
您可以使用下面的Docker命令获得一个Alpine环境
运行程序
```shell
docker run --rm -it -v .:/src -w /src alpine
```
如果您位于中国大陆境内,推荐先对apk进行换源,以加速软件包下载
```shell
# https://help.mirrors.cernet.edu.cn/alpine/
printf '%s' 'https://mirrors.cernet.edu.cn/alpine/latest-stable/main
https://mirrors.cernet.edu.cn/alpine/latest-stable/community
' | tee /etc/apk/repositories
```
安装依赖项
```shell
apk update
apk add --no-cache clang build-base dotnet10-sdk
```
然后进行编译
```shell
dotnet publish language.cs
```
你需要的ELF会出现在`artifacts/language/`文件夹内
sudo chmod o+x language
sudo ./language
```
BIN
View File
Binary file not shown.
+31
View File
@@ -0,0 +1,31 @@
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
auto check() {
cout << "请输入您的选项(输入y或者yes继续)";
string userin;
cin >> userin;
if (userin == "y" or userin == "yes")
return;
else
cout << "输入不正确欸,如果想停止本程序的话请按下Ctrl+C" << endl;
check();}
int main(){
cout << "提示:本程序需要root权限,如果您不是以root运行的本程序,请Ctrl+C终止并重新提权运行" << endl;
cout << "如果确认权限没有问题,请输入y或者yes";
check();
cout << "即将开始安装并配置简体中文语言包,请输入y或者yes继续,或者按Ctrl+C终止本程序";
check();
system("apt install -y language-pack-zh-hans");
system("locale-gen zh_CN.UTF-8");
system("mv /etc/default/locale /etc/default/locale.backup");
system("touch /etc/default/locale");
system("echo LANG=\"zh_CN.UTF-8\" > /etc/default/locale");
cout << "原/etc/default/locale已经备份为/etc/default/locale.backup" << endl;
cout << "即将重启以应用语言设置,请保存您未完成的工作以防数据丢失" << endl;
cout << "输入y或者yes重启或者按Ctrl+C终止本程序" << endl;
check();
system("reboot");}
-146
View File
@@ -1,146 +0,0 @@
#!/usr/bin/env -S dotnet --
// https://learn.microsoft.com/zh-cn/dotnet/core/sdk/file-based-apps
#:property PublishAot=true
#:property StaticExecutable=true
#:property OptimizationPreference=Speed
// #:property OptimizationPreference=Size
#:property InvariantGlobalization=true
// ↑ 这个东西需要libicu
// #:property StackTraceSupport=false
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
void CheckUser(string DisplayMessage = "即将开始更新语言配置"){
Console.WriteLine(DisplayMessage);
Console.WriteLine("按回车继续,按Esc取消");
while (true){
var KeyInfo = Console.ReadKey(true);
if (KeyInfo.Key == ConsoleKey.Enter){
return; }
else if (KeyInfo.Key == ConsoleKey.Escape){
Environment.Exit(0); } } }
bool IsRunningInsideWSL(){
string VersionFile = File.ReadAllText("/proc/version");
string KernelOsReleaseFile = File.ReadAllText("/proc/sys/kernel/osrelease");
if (VersionFile.Contains("Microsoft") || VersionFile.Contains("WSL")){
return true; }
if (KernelOsReleaseFile.Contains("microsoft") || KernelOsReleaseFile.Contains("WSL")){
return true; }
return false; }
void ExecuteCommand(string Command,
List<string>? Arguments = null,
Action<int, string, string?>? WhenErrorThrown = null){
List<string> StandardError = [];
int ExitCode = 0;
try{
using var Process = new Process();
Process.StartInfo.FileName = Command;
if (Arguments != null){
foreach (var Argument in Arguments){
Process.StartInfo.ArgumentList.Add(Argument); } }
Process.StartInfo.RedirectStandardError = true;
Process.ErrorDataReceived += (_, Event) => {
if (Event.Data != null){
Console.WriteLine(Event.Data);
StandardError.Add(Event.Data + "\n"); } };
Process.Start();
Process.BeginErrorReadLine();
Process.WaitForExit();
ExitCode = Process.ExitCode;
if (ExitCode != 0){
throw new Exception($"命令执行失败,退出代码: {ExitCode}"); } }
catch (Exception ExceptionInstance){
WhenErrorThrown ??= (ExitCode, StandardError, ExceptionMessage) => {
Console.WriteLine(@$"
命令执行失败
退出代码: {ExitCode}
stderr: {StandardError}
异常信息: {ExceptionMessage ?? ""}"); };
WhenErrorThrown(ExitCode, string.Join("\n", StandardError), ExceptionInstance.Message);
throw; } }
string OsDescription = RuntimeInformation.OSDescription;
if (Enum.TryParse<SupportedLinuxDistributions>(OsDescription.Split(' ')[0], out var CurrentSystem) == false){
if (OsDescription.Contains("Arch Linux")){
CurrentSystem = SupportedLinuxDistributions.ArchLinux; }
else{
string CurrentSupportedLinuxDistributions = string.Join(", ", Enum.GetNames<SupportedLinuxDistributions>());
string Message = @$"
当前系统为 {OsDescription}
当前仅支持 {CurrentSupportedLinuxDistributions}
强行使用可能会造成不可预知的问题
为避免出现故障,程序会强制退出
如果是误报,请在GitHub仓库打开一个新的issue。
".Trim();
throw new NotSupportedException(Message); } }
if (Environment.IsPrivilegedProcess == false) {
using var Process = new Process();
Process.StartInfo.FileName = "sudo";
Process.StartInfo.ArgumentList.Add(Environment.ProcessPath ?? throw new Exception("无法获取当前程序路径"));
Console.WriteLine("更改语言文件需要root权限,当前用户权限不足");
Console.WriteLine("正在尝试使用sudo重新运行程序");
Console.WriteLine("如果您当前登录的用户拥有密码,请在sudo提示符中输入密码");
Process.Start();
Process.WaitForExit();
Environment.Exit(Process.ExitCode); }
Console.WriteLine($"探测到当前系统为 {OsDescription}");
switch (CurrentSystem){
case SupportedLinuxDistributions.Debian or SupportedLinuxDistributions.Armbian: {
CheckUser();
Console.WriteLine("正在检查语言配置");
string[] NewContent = [];
using var FileStream = new FileStream("/etc/locale.gen", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
using (var StreamReader = new StreamReader(FileStream, Encoding.UTF8, true, 1024, true)){
NewContent = [.. StreamReader.ReadToEnd()
.Split("\n")
.Select(Line => Line.Trim())
.Select(Line => {
if (Line.Contains("zh_CN.UTF-8 UTF-8")){
Line = "zh_CN.UTF-8 UTF-8"; }
return Line; } ) ]; }
FileStream.SetLength(0);
FileStream.Seek(0, SeekOrigin.Begin);
using (var StreamWriter = new StreamWriter(FileStream, Encoding.UTF8)){
foreach (var Line in NewContent){
StreamWriter.WriteLine(Line); } }
Console.WriteLine("正在生成语言配置");
ExecuteCommand("locale-gen");
Console.WriteLine("正在更新语言配置");
ExecuteCommand("update-locale", ["LANG=zh_CN.UTF-8"]);
break; }
case SupportedLinuxDistributions.Ubuntu: {
CheckUser("即将开始安装中文语言包");
Console.WriteLine("正在更新apt软件包源");
ExecuteCommand("apt", ["update"]);
Console.WriteLine("正在安装中文语言包");
ExecuteCommand("apt", ["install", "language-pack-zh-hans", "-y"]);
Console.WriteLine("正在更新语言配置");
ExecuteCommand("update-locale", ["LANG=zh_CN.UTF-8"]);
break; }
case SupportedLinuxDistributions.ArchLinux or SupportedLinuxDistributions.CachyOS: {
CheckUser();
Console.WriteLine("开始更新语言配置");
ExecuteCommand("localectl", ["set-locale", "LANG=zh_CN.UTF-8"]);
if (IsRunningInsideWSL()){
// https://wiki.archlinuxcn.org/wiki/%E5%9C%A8_WSL_%E4%B8%8A%E5%AE%89%E8%A3%85_Arch_Linux#%E4%BF%AE%E6%94%B9%E5%8C%BA%E5%9F%9F%E8%AE%BE%E7%BD%AE
Console.WriteLine("检测到您正在WSL中运行Arch Linux,正在创建 /etc/locale.conf -> /etc/default/locale 符号链接");
if (File.Exists("/etc/default/locale")){
File.Move("/etc/default/locale", "/etc/default/locale.bak", true); }
File.CreateSymbolicLink("/etc/default/locale", "/etc/locale.conf"); }
break; } }
Console.WriteLine("配置完成,更改将在您下一次登录Shell时生效,按任意键退出");
Console.ReadKey(true);
enum SupportedLinuxDistributions {
Debian,
Armbian,
Ubuntu,
ArchLinux,
CachyOS }