Skip to content

Commit

Permalink
TextHook:以U16编码写入CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
imba-tjd authored and AndromedaMelody committed May 30, 2023
1 parent 99b0565 commit 7373fec
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 33 deletions.
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<Platforms>AnyCPU</Platforms>
<LangVersion>11.0</LangVersion>
<Version>2.12.2.0</Version>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('netframework'))">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private void ConfirmButton_Click(object sender, RoutedEventArgs e)
Common.textHooker = new TextHookHandle(SameNameGameProcessList);
}

if(!Common.textHooker.Init(!(bool)x64GameCheckBox.IsChecked))
if (!Common.textHooker.Init((bool)x64GameCheckBox.IsChecked ? Common.appSettings.Textractor_Path64 : Common.appSettings.Textractor_Path32))
{
HandyControl.Controls.MessageBox.Show(Application.Current.Resources["MainWindow_TextractorError_Hint"].ToString());
return;
Expand Down
6 changes: 6 additions & 0 deletions MisakaTranslator-WPF/IAppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ string ForegroundHex

[Option(Alias = "Mecab.dicPath", DefaultValue = "")]
string Mecab_dicPath { get; set; }

[Option(Alias = "Textractor.Path32", DefaultValue = "")]
string Textractor_Path32 { get; set; }

[Option(Alias = "Textractor.Path64", DefaultValue = "")]
string Textractor_Path64 { get; set; }
}

public interface IRepeatRepairSettings
Expand Down
2 changes: 1 addition & 1 deletion MisakaTranslator-WPF/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private async Task StartTranslateByGid(int gid) {

Common.textHooker = pidList.Count == 1 ? new TextHookHandle(pidList[0].Id) : new TextHookHandle(pidList);

if(!Common.textHooker.Init(!gameInfoList[gid].Isx64))
if (!Common.textHooker.Init(gameInfoList[gid].Isx64 ? Common.appSettings.Textractor_Path64 : Common.appSettings.Textractor_Path32))
{
HandyControl.Controls.MessageBox.Show(Application.Current.Resources["MainWindow_TextractorError_Hint"].ToString());
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public MecabDictPage()

private void ChoosePathBtn_Click(object sender, RoutedEventArgs e)
{

FolderBrowserDialog dialog = new();
if (dialog.ShowDialog() == DialogResult.OK)
{
Expand Down
32 changes: 26 additions & 6 deletions MisakaTranslator-WPF/SettingsPages/HookSettingsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,32 @@
<hc:ScrollViewer HorizontalScrollBarVisibility="Disabled">
<StackPanel Background="White">
<TextBlock Text="{StaticResource HookSettingsPage_Introduce}" FontSize="16" Margin="10" TextWrapping="WrapWithOverflow"/>
<StackPanel Margin="20,10,10,10" Height="348">
<TextBlock Text="{StaticResource HookSettingsPage_AutoHook_Introduce}" Margin="0,20,0,0" TextWrapping="WrapWithOverflow"/>
<CheckBox Name="AutoHookCheckBox" Content="{StaticResource HookSettingsPage_AutoHook}" Margin="0,20,0,0" hc:InfoElement.Title="{StaticResource HookSettingsPage_AutoHook}" hc:Poptip.HitMode="None" hc:Poptip.IsOpen="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}" hc:Poptip.Content="{StaticResource HookSettingsPage_AutoHookHint}" hc:Poptip.Placement="Right" Click="AutoHookCheckBox_Click" HorizontalAlignment="Left"/>
<TextBlock Text="{StaticResource HookSettingsPage_AutoDetach_Introduce}" Margin="0,20,0,0" TextWrapping="WrapWithOverflow"/>
<CheckBox Name="AutoDetachCheckBox" Content="{StaticResource HookSettingsPage_AutoDetach}" Margin="0,20,0,0" Canvas.Left="10" Canvas.Top="105" Click="AutoDetachCheckBox_Click" HorizontalAlignment="Left"/>
<Button Content="{StaticResource HookSettingsPage_BtnExtractHistory}" Margin="0,20,0,0" Click="Button_Click" HorizontalAlignment="Left"/>
<StackPanel Margin="20,10,10,10" Height="348" >
<Grid Margin="0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="x86:" Grid.Column="0" VerticalAlignment="Center" />
<TextBox hc:InfoElement.TitlePlacement="Top" hc:InfoElement.Title="{StaticResource MecabDictPage_DBPath}" Name="Path32Box" IsReadOnly="True" Margin="10,0" Grid.Column="1" TextWrapping="WrapWithOverflow" />
<Button Content="{StaticResource JbeijingTransSettingsPage_ChoosePath}" Width="128" Grid.Column="2" Click="ChoosePath32Btn_Click" />
</Grid>
<Grid Margin="0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="x64:" Grid.Column="0" VerticalAlignment="Center" />
<TextBox hc:InfoElement.TitlePlacement="Top" hc:InfoElement.Title="{StaticResource MecabDictPage_DBPath}" Name="Path64Box" IsReadOnly="True" Margin="10,0" Grid.Column="1" TextWrapping="WrapWithOverflow" />
<Button Content="{StaticResource JbeijingTransSettingsPage_ChoosePath}" Width="128" Grid.Column="2" Click="ChoosePath64Btn_Click" />
</Grid>
<TextBlock Text="{StaticResource HookSettingsPage_AutoHook_Introduce}" Margin="0,10" TextWrapping="WrapWithOverflow"/>
<CheckBox Name="AutoHookCheckBox" Content="{StaticResource HookSettingsPage_AutoHook}" Margin="0,10" hc:InfoElement.Title="{StaticResource HookSettingsPage_AutoHook}" hc:Poptip.HitMode="None" hc:Poptip.IsOpen="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}" hc:Poptip.Content="{StaticResource HookSettingsPage_AutoHookHint}" hc:Poptip.Placement="Right" Click="AutoHookCheckBox_Click" HorizontalAlignment="Left"/>
<TextBlock Text="{StaticResource HookSettingsPage_AutoDetach_Introduce}" Margin="0,10" TextWrapping="WrapWithOverflow"/>
<CheckBox Name="AutoDetachCheckBox" Content="{StaticResource HookSettingsPage_AutoDetach}" Margin="0,10" Canvas.Left="10" Canvas.Top="105" Click="AutoDetachCheckBox_Click" HorizontalAlignment="Left"/>
<Button Content="{StaticResource HookSettingsPage_BtnExtractHistory}" Margin="0,10" Click="Button_Click" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</hc:ScrollViewer>
Expand Down
85 changes: 85 additions & 0 deletions MisakaTranslator-WPF/SettingsPages/HookSettingsPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;

Expand All @@ -15,6 +16,9 @@ public HookSettingsPage()

AutoHookCheckBox.IsChecked = Convert.ToBoolean(Common.appSettings.AutoHook);
AutoDetachCheckBox.IsChecked = Convert.ToBoolean(Common.appSettings.AutoDetach);

Path32Box.Text = Common.appSettings.Textractor_Path32;
Path64Box.Text = Common.appSettings.Textractor_Path64;
}

private void AutoHookCheckBox_Click(object sender, RoutedEventArgs e)
Expand All @@ -39,5 +43,86 @@ private void Button_Click(object sender, RoutedEventArgs e)
}
}

private void ChoosePath32Btn_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog dialog = new();
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
CheckCLI(dialog.SelectedPath, true);
}
}

private void ChoosePath64Btn_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog dialog = new();
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
CheckCLI(dialog.SelectedPath, false);
}
}

private void CheckCLI(string path, bool isX86)
{
if (File.Exists($@"{path}\TextractorCLI.exe"))
{
if (path.Contains("x86"))
{
Path32Box.Text = $@"{path}\TextractorCLI.exe";
Common.appSettings.Textractor_Path32 = Path32Box.Text;
if (File.Exists($@"{path.Replace("x86", "x64")}\TextractorCLI.exe"))
{
Path64Box.Text = $@"{path.Replace("x86", "x64")}\TextractorCLI.exe";
Common.appSettings.Textractor_Path64 = Path64Box.Text;
}
}
else if (path.Contains("x64"))
{
Path64Box.Text = $@"{path}\TextractorCLI.exe";
Common.appSettings.Textractor_Path64 = Path64Box.Text;
if (File.Exists($@"{path.Replace("x64", "x86")}\TextractorCLI.exe"))
{
Path32Box.Text = $@"{path.Replace("x64", "x86")}\TextractorCLI.exe";
Common.appSettings.Textractor_Path32 = Path32Box.Text;
}
}
else
{
if (isX86)
{
Path32Box.Text = $@"{path}\TextractorCLI.exe";
Common.appSettings.Textractor_Path32 = Path32Box.Text;
}
else
{
Path64Box.Text = $@"{path}\TextractorCLI.exe";
Common.appSettings.Textractor_Path64 = Path64Box.Text;
}
}
}
else if (File.Exists($@"{path}\x86\TextractorCLI.exe"))
{
Path32Box.Text = $@"{path}\x86\TextractorCLI.exe";
Common.appSettings.Textractor_Path32 = Path32Box.Text;
if (File.Exists($@"{path}\x64\TextractorCLI.exe"))
{
Path64Box.Text = $@"{path}\x64\TextractorCLI.exe";
Common.appSettings.Textractor_Path64 = Path64Box.Text;
}
}
else if (File.Exists($@"{path}\x64\TextractorCLI.exe"))
{
Path64Box.Text = $@"{path}\x64\TextractorCLI.exe";
Common.appSettings.Textractor_Path64 = Path64Box.Text;
if (File.Exists($@"{path}\x86\TextractorCLI.exe"))
{
Path32Box.Text = $@"{path}\x86\TextractorCLI.exe";
Common.appSettings.Textractor_Path32 = Path32Box.Text;
}
}
else
{
MessageBox.Show("找不到TextractorCLI.exe\nCan't find TextractorCLI.exe", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
2 changes: 1 addition & 1 deletion MisakaTranslator-WPF/lang/en-US.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
<sys:String x:Key="TesseractCliSettingsPage_Args">TesseractCli Parameters</sys:String>
<sys:String x:Key="TesseractCliSettingsPage_Select">Select</sys:String>

<sys:String x:Key="HookSettingsPage_Introduce">This is the text hook method (Textractor) setting. Textractor was recoded and runs along with the Translator. There is no need to change its path.</sys:String>
<sys:String x:Key="HookSettingsPage_Introduce">This is Textractor setting. You need to choose the path of its folder after installing or extracting it.</sys:String>
<sys:String x:Key="HookSettingsPage_AutoHook">Enable smart hook</sys:String>
<sys:String x:Key="HookSettingsPage_AutoHook_Introduce">Once enabled, Translator hooks the process that uses the biggest memory among multiple processes with the same name.</sys:String>
<sys:String x:Key="HookSettingsPage_AutoHookHint">Note: This approach is slightly more efficient, but may not find the text.</sys:String>
Expand Down
2 changes: 1 addition & 1 deletion MisakaTranslator-WPF/lang/zh-CN.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
<sys:String x:Key="TesseractCliSettingsPage_Args">自定义参数</sys:String>
<sys:String x:Key="TesseractCliSettingsPage_Select">选择</sys:String>

<sys:String x:Key="HookSettingsPage_Introduce">在这里进行文本Hook注入方式(Textractor)的相关设置;Textractor模块已经根据需要重写过并随本程序一起运行,您不需要更改它的位置</sys:String>
<sys:String x:Key="HookSettingsPage_Introduce">在这里进行Textractor的相关设置;您需要选择安装或解压后的文件夹位置</sys:String>
<sys:String x:Key="HookSettingsPage_AutoHook">开启智能注入</sys:String>
<sys:String x:Key="HookSettingsPage_AutoHook_Introduce">开启智能注入后,遇到某些游戏存在多个同名进程的情况下,将自动选择占用内存最大的进程注入</sys:String>
<sys:String x:Key="HookSettingsPage_AutoHookHint">注意:这种方式可以略微提高效率,但可能导致无法寻找到文本</sys:String>
Expand Down
2 changes: 2 additions & 0 deletions TextHookLibrary/NativeMethods.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// function
Windows.Win32.System.Console.AllocConsole
Windows.Win32.System.Console.FreeConsole
Windows.Win32.System.DataExchange.ChangeClipboardChain
Windows.Win32.System.DataExchange.SetClipboardViewer
61 changes: 39 additions & 22 deletions TextHookLibrary/TextHookHandle.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Win32;

namespace TextHookLibrary {
/// <summary>
Expand Down Expand Up @@ -132,36 +134,51 @@ public TextHookHandle() {
/// 初始化Textractor,建立CLI与本软件间的通信
/// </summary>
/// <returns>成功返回真,失败返回假</returns>
public bool Init(bool x86 = true) {
string Path = Environment.CurrentDirectory + @"\lib\TextHook\" + (x86 ? "x86" : "x64");//打开对应的Textractor
string CurrentPath = Environment.CurrentDirectory;
try {
Environment.CurrentDirectory = Path;//更改当前工作目录保证TextractorCLI正常运行
}
#pragma warning disable 168
catch (System.IO.DirectoryNotFoundException ex) {
#pragma warning restore 168
public bool Init(string path)
{
if(!File.Exists(path))
{
return false;
}

ProcessTextractor = new Process();
ProcessTextractor.StartInfo.FileName = "TextractorCLI.exe";
ProcessTextractor.StartInfo.CreateNoWindow = true;
ProcessTextractor.StartInfo.UseShellExecute = false;
ProcessTextractor.StartInfo.StandardOutputEncoding = Encoding.Unicode;
ProcessTextractor.StartInfo.RedirectStandardInput = true;
ProcessTextractor.StartInfo.RedirectStandardOutput = true;
ProcessTextractor = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = path,
CreateNoWindow = true,
UseShellExecute = false,
#if NETCOREAPP
StandardInputEncoding = new UnicodeEncoding(false, false),
#endif
StandardOutputEncoding = Encoding.Unicode,
RedirectStandardInput = true,
RedirectStandardOutput = true,
WorkingDirectory = Path.GetDirectoryName(path)
},
};

ProcessTextractor.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
try {
try
{
#if NETFRAMEWORK
// .NET Framework根据Console.InputEncoding编码在Start()中创建输入流
Console.InputEncoding = new UnicodeEncoding(false, false);
#endif
bool res = ProcessTextractor.Start();
#if NETFRAMEWORK
// Console.InputEncoding修改为非UTF16编码需要创建控制台
PInvoke.AllocConsole();
Console.InputEncoding = Encoding.Default;
PInvoke.FreeConsole();
#endif
ProcessTextractor.BeginOutputReadLine();
Environment.CurrentDirectory = CurrentPath;//打开后即可恢复原目录
return res;
}
#pragma warning disable 168
catch (System.ComponentModel.Win32Exception ex) {
#pragma warning restore 168
Environment.CurrentDirectory = CurrentPath;//恢复原目录
catch (System.ComponentModel.Win32Exception)
{
ProcessTextractor.Dispose();
ProcessTextractor = null;
return false;
}
}
Expand Down

0 comments on commit 7373fec

Please sign in to comment.