C# 实用代码分享
1. 获取其他程序的句柄模拟键盘按键
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace 命名空间
{
internal class 类名
{
[DllImport("user32.dll")]
internal static extern int SetForegroundWindow(IntPtr ip);//获取窗口句柄
internal static void Main()
{
Process process = Process.GetProcessById(PID);
SetForegroundWindow(process.MainWindowHandle);
SendKeys.SendWait("");
// ^ = Ctrl
// % = Alt
// {按键 数字} = 按{按键}{数字}次
}
}
}
2. 内嵌类库加载(先将类库改为内嵌资源)
⚠️ 注意:需在 AssemblyInfo.cs 中添加资源语言配置
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
string name = "程序的命名空间.文件夹名." + new AssemblyName(args.Name).Name + ".dll";
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
byte[] assData = new byte[stream.Length];
stream.Read(assData, 0, assData.Length);
return Assembly.Load(assData);
};
[assembly: NeutralResourcesLanguage("zh-CN", UltimateResourceFallbackLocation.MainAssembly)]
3. 提取内嵌文件
internal class Extract
{
internal static void File(string fn, string of)
{
BufferedStream bs = null;
FileStream fs = null;
try
{
Assembly a = Assembly.GetExecutingAssembly();
bs = new BufferedStream(a.GetManifestResourceStream(fn));
fs = new FileStream(of, FileMode.Create, FileAccess.Write);
byte[] buffer = new byte[1024];
int length;
while ((length = bs.Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, length);
}
fs.Flush();
}
finally
{
if (fs != null) fs.Dispose();
if (bs != null) bs.Dispose();
}
}
}
4. 配置文件写法
INI 配置文件(不推荐)
> ⚠️ 需要调用 kernel32.dll,安全性较差JSON 配置文件(推荐)
// 读取配置
internal static dynamic Read(string keywords)
{
StreamReader sr = File.OpenText("config.json");
JsonTextReader jtr = new JsonTextReader(sr);
JObject jo = (JObject)JToken.ReadFrom(jtr);
dynamic value = (dynamic)jo[keywords];
sr.Dispose();
return value;
}
// 写入配置
internal static void Write(string keywords, dynamic newVaelue)
{
string str = File.ReadAllText("config.json");
dynamic jo = JsonConvert.DeserializeObject(str);
jo[keywords] = newVaelue;
File.WriteAllText("config.json", JsonConvert.SerializeObject(jo, Formatting.Indented));
}
示例 config.json:
{
"对象名一": "字符串",
"对象名二": 0,
"对象名三": false
}
5. 收集目录内指定格式文件
using System;
using System.IO;
namespace MusicCollector
{
public class MainClass
{
public static void Main()
{
Console.Write("请输入目录路径: \n>");
string inputPath = Console.ReadLine();
string outputPath = inputPath + "\\Output";
if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath);
DirectoryInfo di = new DirectoryInfo(inputPath);
CollectFiles(di, outputPath);
Console.WriteLine("完成!");
Console.ReadKey();
}
private static void CollectFiles(DirectoryInfo dir, string output)
{
foreach (FileInfo file in dir.GetFiles())
{
if (file.Extension == ".ogg")
{
string destPath = Path.Combine(output, 正在加载文章内容...
quot;{dir.Name}{file.Extension}");
if (File.Exists(destPath)) destPath = Path.Combine(output, 正在加载文章内容...
quot;{dir.Name}_new{file.Extension}");
File.Copy(file.FullName, destPath);
}
}
foreach (DirectoryInfo subDir in dir.GetDirectories())
{
if (subDir.Name != "Output") CollectFiles(subDir, output);
}
}
}
}
6. Hjson 配置文件
6.1. 基本介绍
说明:TML 1.4新版早已自动生成hjson文件,此教程Localizer.cs为早期教程的内容,现在无需编写,但不删除,仅供参考!
说明:TML 1.4新版早已自动生成hjson文件,此教程Localizer.cs为早期教程的内容,现在无需编写,但不删除,仅供参考!
众所周知:语言是人类进行沟通交流的表达方式。它是人与人之间的一种交流方式,人们彼此的交往离不开语言。尽管通过图片、动作、表情等可以传递人们的思想,但是语言是其中最重要的,也是最方便的媒介。然而世界各地的人们所用的语言各不相同,彼此间直接交谈是困难的,甚至是不可能的。即使是同一种语言,还有不同的方言,其差别程度也不相同。有的方言可以基本上相互理解,有的差别极大。
我们早期的模组开发者早已意识到多语言的重要性,@SweelLong为主要语言文件编写者,并且随着tModLoader的不断更迭,早期使用本地化模组,依靠代码实现自制语言格式的json文件读取……
TML 1.4的发布,TML-Team加入了新的本地化方案{*.hjson},并提供了一系列的工具支持,使得开发者可以轻松的实现多语言支持。本教程将介绍HJSON的语法和用法。
6.2. 文件类型
我们早期的模组开发者早已意识到多语言的重要性,@SweelLong为主要语言文件编写者,并且随着tModLoader的不断更迭,早期使用本地化模组,依靠代码实现自制语言格式的json文件读取……
TML 1.4的发布,TML-Team加入了新的本地化方案{*.hjson},并提供了一系列的工具支持,使得开发者可以轻松的实现多语言支持。本教程将介绍HJSON的语法和用法。
JSON 是我们平时使用非常频繁的数据格式,尤其在网络传输中非常受欢迎。大部分编程语言都支持这种格式。但是作为配置文件还是有些许不足,最主要的一点是缺乏注释(其他比如低信噪比其实还可以接受),所以在 JSON 的基础上衍生出了更方便的作为配置文件的格式 HJSON 。
HJSON的写法毕竟还是多的,甚至可以直接模仿JSON的写法:
Xxx:
{
Xx: "x"
Xxx:{
...
}
}
这里称:Xxx和xx为键名、x为键值。
调用HJSON值的方式类似调用命名空间:
现在给定HJSON文件:
Mods:
{
Terraria:
{
Name: "Terraria"
Description: "一个生存类模组"
}
tModLoader:
{
Name: "tModLoader"
Description: "一个模组加载器"
}
}
在C#中读取HJSON文件(键名的完全路径):
输出Terraria的描述:>>> Mods.Terraria.Description
输出结果:"一个生存类模组"
6.3. TML本地化方案介绍
TML本地化方案:
// You may find this .hjson file approach to translations easier for your mod.
// 你会发现.hjson文件的方法让模组翻译更容易。
// .hjson files contain translations for the language specified in the filename. (Make sure this file is UTF-8 encoded only.)
// .hjson的文件夹名是指定的(确保文件编码只能为UTF-8)
// The possible languages are: English ("en-US"), German ("de-DE"), Italian ("it-IT"), French ("fr-FR"), Spanish ("es-ES"), Russian ("ru-RU"), Chinese ("zh-Hans"), Portuguese ("pt-BR"), and Polish ("pl-PL")
// 可能的语言是(引号内为指定的文件名):英语("en-US"), 德语("de-DE"), 意大利语("it-IT"), 法语("fr-FR"), 西班牙语("es-ES"), 俄语("ru-RU"), 汉语("zh-Hans"), 葡萄牙语("pt-BR"), 波兰语("pl-PL")
// We have organized these files in a folder called Localization. A single file per language makes it extremely easy to to integrate and maintain translations.
// 我们将这些文件组织在一个名为本地化的文件夹中。每种语言只有一个文件,因此非常容易整理和维护翻译。
// Each translation entry in .hjson files contains a key and a value. The key is determined following the rules of JSON [https://www.w3schools.com/js/js_json_syntax.asp]
// 每个翻译条目.hjson文件都包含一个键名和一个键值。键是根据JSON的规则确定的[https://www.w3schools.com/js/js_json_syntax.asp]
// The Key automatically inherits "Mods.ModNameHere.", which is useful to know if you want to use substitutions (as seen in the Paper Airplane example) or use Language.GetTextValue or Network text.
// 键自动继承"Mods.模组名",如果您想使用代码设置语言或使用Language.GetTextValu或网络文本是非常有用的。
// The following are the currently autogenerated keys: ItemName, ItemTooltip, BuffName, BuffDescription, ProjectileName, NPCName, MapObject, and Prefix
// 这些键是自动继承的(开发组要求不使用自动键,可忽略):ItemName, ItemTooltip, BuffName, BuffDescription, ProjectileName, NPCName, MapObject, and Prefix
6.4. Localizer.cs
/// <summary>
/// Items/Weapons文件夹专用键
/// </summary>
/// <param name="keyName"></param>
/// <returns></returns>
internal static string WeaponsText(string keyName) => Language.GetTextValue("Mods.InterspaceMod.Weapons.{0}", keyName);
根据第二行,我们发现这个方法允许Weapons文件夹下的类调用语言文本:
查阅语言文件(如zh-Hans.hjson):如果要调用
Weapons:
{
InterspaceSword: "星际天河之刃"
}
直接调用:Language.GetTextValue("Mods.InterspaceMod.Weapons.InterspaceSword");
方法调用:WeaponsText("InterspaceSword");
对于Armors键里有多层,则可以这样写:
ArmorsText("InterspaceArmors.Head");
Language.GetTextValue("Mods.InterspaceMod.Armors.InterspaceArmors.Head");