├── .gitattributes ├── .vs └── Translator │ ├── FileContentIndex │ ├── 00abf8cd-b14d-4081-8da3-9507a41cb2b1.vsidx │ ├── 08c89261-1cc1-4d12-b63e-51add9051839.vsidx │ ├── 2ea01327-5d2f-4b1f-8559-73cca111278c.vsidx │ ├── 8f8ec6ff-73d4-489b-87c3-35c632fa1afb.vsidx │ └── read.lock │ └── v17 │ ├── .suo │ └── TestStore │ └── 0 │ ├── 000.testlog │ └── testlog.manifest ├── Readme.md ├── Translator.sln └── Translator ├── App.config ├── App.xaml ├── App.xaml.cs ├── BackgroundWindow.xaml ├── BackgroundWindow.xaml.cs ├── Introduction.png ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── SettingPages ├── DontClick_Selected_Page.xaml ├── DontClick_Selected_Page.xaml.cs ├── General_Selected_Page.xaml ├── General_Selected_Page.xaml.cs └── TranslatorPages │ ├── Baidu_Selected_Page.xaml │ ├── Baidu_Selected_Page.xaml.cs │ ├── ChatGPT_Selected_Page.xaml │ ├── ChatGPT_Selected_Page.xaml.cs │ ├── Deepl_Selected_Page.xaml │ └── Deepl_Selected_Page.xaml.cs ├── Settings.cs ├── SettingsWindow.xaml ├── SettingsWindow.xaml.cs ├── Translator.csproj ├── TranslatorApi ├── Common.cs ├── Impl │ ├── BaiduTranslator.cs │ ├── ChatgptTranslator.cs │ └── DeeplTranslator.cs └── Translator.cs └── myico.ico /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.vs/Translator/FileContentIndex/00abf8cd-b14d-4081-8da3-9507a41cb2b1.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/FileContentIndex/00abf8cd-b14d-4081-8da3-9507a41cb2b1.vsidx -------------------------------------------------------------------------------- /.vs/Translator/FileContentIndex/08c89261-1cc1-4d12-b63e-51add9051839.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/FileContentIndex/08c89261-1cc1-4d12-b63e-51add9051839.vsidx -------------------------------------------------------------------------------- /.vs/Translator/FileContentIndex/2ea01327-5d2f-4b1f-8559-73cca111278c.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/FileContentIndex/2ea01327-5d2f-4b1f-8559-73cca111278c.vsidx -------------------------------------------------------------------------------- /.vs/Translator/FileContentIndex/8f8ec6ff-73d4-489b-87c3-35c632fa1afb.vsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/FileContentIndex/8f8ec6ff-73d4-489b-87c3-35c632fa1afb.vsidx -------------------------------------------------------------------------------- /.vs/Translator/FileContentIndex/read.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/FileContentIndex/read.lock -------------------------------------------------------------------------------- /.vs/Translator/v17/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/v17/.suo -------------------------------------------------------------------------------- /.vs/Translator/v17/TestStore/0/000.testlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/v17/TestStore/0/000.testlog -------------------------------------------------------------------------------- /.vs/Translator/v17/TestStore/0/testlog.manifest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/.vs/Translator/v17/TestStore/0/testlog.manifest -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Readme 2 | 3 | ## 注意 4 | 5 | **4月份左右openai对api的调用做出进一步限制,普通用户每分钟的请求次数降为了3次,已经不能满足实时翻译的基本请求。尽管十分可惜,本项目将不再维护。** 6 | 7 | ## 背景 8 | 9 | ​ [BV1uN411c7PQ](https://www.bilibili.com/video/BV1uN411c7PQ)中展示出ChatGPT的翻译能力引人注目,基于此构建了一款简单的翻译器。 10 | 11 | ## 安装 12 | 13 | [Release Translator · Tofweod/Translator (github.com)](https://github.com/Tofweod/Translator/releases) 以及演示视频[BV1EM411W7Dk](https://www.bilibili.com/video/BV1EM411W7Dk) 14 | 15 | ## 使用 16 | 17 | 解压安装包,打开Translator.exe,选中翻译文本并复制(Ctrl+C)即可进行翻译。 18 | 19 | 本软件支持ChatGPT翻译、百度翻译,以及中日英三语之间的互译 20 | 21 | 注:本软件的翻译属于**在线翻译**,**需要联网使用**。 22 | 23 | ​ **在使用翻译器前应确保自己已注册对应的翻译API** 24 | 25 | ​ exe文件目录下的Config文件内有部分扩展设置,可按需自行修改 26 | 27 | 相关教程 28 | 29 | ​ [一文教你快速注册OpenAi(ChatGPT),国内也可以! - 腾讯云开发者社区-腾讯云 (tencent.com)](https://cloud.tencent.com/developer/article/2190154)-在注册成功后可以在个人页面申请一个API Key 30 | 31 | [推荐一款好用的免费翻译API——百度翻译 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/81945858) 32 | 33 | ## 框架 34 | 35 | ​ 本项目基于.Net4.7.2框架 36 | 37 | ## 使用到的其他开源项目 38 | 39 | [HandyOrg](https://handyorg.github.io/) 40 | 41 | ## 参考文献 42 | 43 | [C#技巧:用C#监视剪贴板活动 ](https://www.cnblogs.com/DotNetEarthworm/archive/2008/12/19/1358461.html) 44 | 45 | [c# - Asynchronously wait for Task to complete with timeout](https://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout) 46 | 47 | ## 待实现 48 | 49 | ​ 本软件的字体设置以及穿透设置是**未实现**的。 50 | -------------------------------------------------------------------------------- /Translator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.33424.131 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Translator", "Translator\Translator.csproj", "{581423A1-CAF2-4F9A-AA74-ECE8171C317F}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{CAE2F026-6883-46B1-BD43-61737C782DDC}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {581423A1-CAF2-4F9A-AA74-ECE8171C317F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {581423A1-CAF2-4F9A-AA74-ECE8171C317F}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {581423A1-CAF2-4F9A-AA74-ECE8171C317F}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {581423A1-CAF2-4F9A-AA74-ECE8171C317F}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {CAE2F026-6883-46B1-BD43-61737C782DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {CAE2F026-6883-46B1-BD43-61737C782DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {CAE2F026-6883-46B1-BD43-61737C782DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {CAE2F026-6883-46B1-BD43-61737C782DDC}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {8A931F33-CA52-42B5-AA6E-28692CA901CA} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Translator/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Translator/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Translator/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace Translator 10 | { 11 | /// 12 | /// App.xaml 的交互逻辑 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Translator/BackgroundWindow.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Translator/BackgroundWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Shapes; 15 | 16 | namespace Translator 17 | { 18 | /// 19 | /// BackgroundSettings.xaml 的交互逻辑 20 | /// 21 | public partial class BackgroundWindow : Window 22 | 23 | { 24 | public BackgroundWindow() 25 | { 26 | InitializeComponent(); 27 | } 28 | 29 | private void BackgroundColor_Changed(object sender, RoutedEventArgs e) 30 | { 31 | var mainWindow = (MainWindow)Application.Current.MainWindow; 32 | mainWindow.Background = ColorPicker.SelectedBrush; 33 | Settings.BackgroundColor = ColorPicker.SelectedBrush.ToString(); 34 | } 35 | 36 | ~BackgroundWindow() 37 | { 38 | Configuration config = Settings.GetAppConfig(); 39 | config.AppSettings.Settings["BackgroundColor"].Value = Settings.BackgroundColor; 40 | Settings.SaveAppConfig(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Translator/Introduction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/Translator/Introduction.png -------------------------------------------------------------------------------- /Translator/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Translator/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection.Emit; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Data; 11 | using System.Windows.Documents; 12 | using System.Windows.Input; 13 | using System.Windows.Media; 14 | using System.Windows.Media.Imaging; 15 | using System.Windows.Navigation; 16 | using System.Windows.Shapes; 17 | using System.Windows.Interop; 18 | using Translator.TranslatorApi; 19 | using System.Configuration; 20 | using System.Threading; 21 | using System.Timers; 22 | 23 | namespace Translator 24 | { 25 | 26 | public partial class MainWindow : Window 27 | { 28 | 29 | public System.Windows.Threading.DispatcherTimer timer;//定时器 30 | 31 | IntPtr hwnd; // 窗口句柄 32 | 33 | ITranslator translator; 34 | string src_lang; 35 | string dst_lang; 36 | 37 | bool valid; 38 | bool peneration = false; 39 | 40 | int outTime; 41 | int timeoutCount; 42 | 43 | 44 | public MainWindow() 45 | { 46 | InitializeComponent(); 47 | // 颜色、字体设置 48 | this.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(Settings.BackgroundColor)); 49 | // 默认翻译选项 50 | translator = Common.GetTranslatorDict()[Settings.TranslatorName]; 51 | src_lang = Settings.Src_Lang; 52 | dst_lang = Settings.Dst_Lang; 53 | valid = Settings.Valid; 54 | outTime = Settings.TranslateTimeout; 55 | timeoutCount = 0; 56 | 57 | 58 | 59 | // 设置句柄、定时器 60 | hwnd = new WindowInteropHelper(this).Handle; 61 | timer = new System.Windows.Threading.DispatcherTimer(); 62 | timer.Interval = TimeSpan.FromMilliseconds(10); 63 | timer.Tick += timer_Tick; 64 | timer.Start(); 65 | 66 | } 67 | 68 | 69 | 70 | #region 置顶函数 71 | [DllImport("user32.dll")] 72 | private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, uint flags); 73 | #endregion 74 | 75 | #region 消息钩子预定义参数 76 | private const int WM_DRAWCLIPBOARD = 0x308; 77 | 78 | private const int WM_CHANGECBCHAIN = 0x30D; 79 | 80 | private IntPtr mNextClipBoardViewerHWnd; 81 | 82 | [DllImport("user32.dll", CharSet = CharSet.Auto)] 83 | static public extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); 84 | 85 | [DllImport("user32.dll", CharSet = CharSet.Auto)] 86 | static public extern bool ChangeClipboardChain(IntPtr HWnd, IntPtr HWndNext); 87 | 88 | [DllImport("user32.dll", CharSet = CharSet.Auto)] 89 | static public extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); 90 | #endregion 91 | 92 | #region 消息钩子函数 93 | protected override void OnSourceInitialized(EventArgs e) 94 | { 95 | base.OnSourceInitialized(e); 96 | HwndSource source = PresentationSource.FromVisual(this) as HwndSource; 97 | //挂消息钩子 98 | mNextClipBoardViewerHWnd = SetClipboardViewer(source.Handle); 99 | source.AddHook(WndProc); 100 | } 101 | 102 | 103 | 104 | 105 | IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 106 | { 107 | switch (msg) 108 | { 109 | case WM_DRAWCLIPBOARD: 110 | { 111 | SendMessage(mNextClipBoardViewerHWnd, msg, wParam.ToInt32(), lParam.ToInt32()); 112 | //文本内容检测 113 | if (System.Windows.Clipboard.ContainsText()) 114 | { 115 | //System.Windows.Clipboard.GetText()此处有Bug 116 | //String ct = System.Windows.Clipboard.GetText(); 117 | String ct = Clipboard.GetText(); 118 | source_lang.Text = "\t" + ct; 119 | UpdateDestLangAsync(ct,src_lang,dst_lang); 120 | } 121 | } 122 | break; 123 | case WM_CHANGECBCHAIN: 124 | { 125 | if (wParam == (IntPtr)mNextClipBoardViewerHWnd) 126 | { 127 | mNextClipBoardViewerHWnd = lParam; 128 | } 129 | else 130 | { 131 | SendMessage(mNextClipBoardViewerHWnd, msg, wParam.ToInt32(), lParam.ToInt32()); 132 | } 133 | } 134 | break; 135 | default: 136 | break; 137 | } 138 | return IntPtr.Zero; 139 | } 140 | #endregion 141 | 142 | 143 | #region 引入穿透函数 144 | private const int WS_EX_TRANSPARENT = 0x20; 145 | 146 | private const int GWL_EXSTYLE = -20; 147 | 148 | [DllImport("user32", EntryPoint = "SetWindowLong")] 149 | private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong); 150 | 151 | [DllImport("user32", EntryPoint = "GetWindowLong")] 152 | private static extern uint GetWindowLong(IntPtr hwnd, int nIndex); 153 | #endregion 154 | 155 | 156 | 157 | private void MainWindow_Closing(object sender, EventArgs e) 158 | { 159 | HwndSource source = PresentationSource.FromVisual(this) as HwndSource; 160 | //移除消息钩子 161 | ChangeClipboardChain(source.Handle, mNextClipBoardViewerHWnd); 162 | source.RemoveHook(WndProc); 163 | timer.Stop(); 164 | } 165 | 166 | private void Exit_Button_Click(object sender, RoutedEventArgs e) 167 | { 168 | MainWindow_Closing(sender, e); 169 | Environment.Exit(0); 170 | } 171 | 172 | private void timer_Tick(object sender, EventArgs e) 173 | { 174 | if (this.WindowState != WindowState.Minimized) 175 | { 176 | SetWindowPos(hwnd, -1, 0, 0, 0, 0, 0x0001 | 0x0002); 177 | } 178 | 179 | } 180 | 181 | 182 | private async void UpdateDestLangAsync(string text, string src, string dst) 183 | { 184 | if (valid) 185 | { 186 | dest_lang.Text = "\t"+await TimeoutAfter(translator.TranslateAsync(text, src, dst),Settings.TranslateTimeout); 187 | } 188 | else 189 | { 190 | dest_lang.Text = "\t已禁止翻译"; 191 | } 192 | } 193 | 194 | // 超时设置 195 | public async Task TimeoutAfter(Task task,int timeout) 196 | { 197 | 198 | using (var timeoutCancellationTokenSource = new CancellationTokenSource()) 199 | { 200 | 201 | var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token)); 202 | if (completedTask == task) 203 | { 204 | timeoutCount = 0; 205 | timeoutCancellationTokenSource.Cancel(); 206 | return await task; // Very important in order to propagate exceptions 207 | } 208 | else 209 | { 210 | timeoutCount++; 211 | return "翻译请求超时-times:"+timeoutCount; 212 | } 213 | } 214 | } 215 | 216 | private void Drag(object sender, MouseEventArgs e) 217 | { 218 | if (e.LeftButton == MouseButtonState.Pressed) 219 | { 220 | DragMove(); 221 | } 222 | } 223 | 224 | private void Window_StateChanged(object sender, EventArgs e) 225 | { 226 | if (WindowState != WindowState.Minimized) 227 | { 228 | WindowState = WindowState.Minimized; 229 | } 230 | } 231 | 232 | private void Valid_Button_Click(object sender, RoutedEventArgs e) 233 | { 234 | if (valid) 235 | { 236 | valid = false; 237 | Valid.FontWeight = FontWeights.Normal; 238 | } 239 | else 240 | { 241 | valid = true; 242 | Valid.FontWeight = FontWeights.Bold; 243 | } 244 | } 245 | 246 | private void Settings_Button_Click(object sender, RoutedEventArgs e) 247 | { 248 | var settingsWindow = new SettingsWindow 249 | { 250 | Owner = this 251 | }; 252 | settingsWindow.Show(); 253 | } 254 | 255 | private void Font_Button_Click(object sender, RoutedEventArgs e) 256 | { 257 | 258 | } 259 | 260 | private void Background_Button_Click(object sender, RoutedEventArgs e) 261 | { 262 | var backgroundWindow = new BackgroundWindow 263 | { 264 | Owner = this 265 | }; 266 | backgroundWindow.Show(); 267 | } 268 | 269 | 270 | public void SetTranslator(ITranslator t) 271 | { 272 | translator = t; 273 | } 274 | 275 | public void SetSrcLang(string s) 276 | { 277 | src_lang = s; 278 | } 279 | 280 | public void SetDstLang(string s) 281 | { 282 | dst_lang = s; 283 | } 284 | 285 | public void SetTimeOut(int t) 286 | { 287 | outTime = t; 288 | } 289 | 290 | private void Penetration_Button_Click(object sender, RoutedEventArgs e) 291 | { 292 | if (peneration) 293 | { 294 | Background.Opacity = 0; 295 | } 296 | else 297 | { 298 | Background.Opacity = 1; 299 | } 300 | //IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(Body)).Handle; 301 | //SetWindowLong(hwnd, GWL_EXSTYLE, 302 | // GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT); 303 | } 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /Translator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // 有关程序集的一般信息由以下 8 | // 控制。更改这些特性值可修改 9 | // 与程序集关联的信息。 10 | [assembly: AssemblyTitle("Translator")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("Translator")] 15 | [assembly: AssemblyCopyright("Copyright © 2023")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // 将 ComVisible 设置为 false 会使此程序集中的类型 20 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 21 | //请将此类型的 ComVisible 特性设置为 true。 22 | [assembly: ComVisible(false)] 23 | 24 | //若要开始生成可本地化的应用程序,请设置 25 | //.csproj 文件中的 CultureYouAreCodingWith 26 | //例如,如果您在源文件中使用的是美国英语, 27 | //使用的是美国英语,请将 设置为 en-US。 然后取消 28 | //对以下 NeutralResourceLanguage 特性的注释。 更新 29 | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //主题特定资源词典所处位置 36 | //(未在页面中找到资源时使用, 37 | //或应用程序资源字典中找到时使用) 38 | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 39 | //(未在页面中找到资源时使用, 40 | //、应用程序或任何主题专用资源字典中找到时使用) 41 | )] 42 | 43 | 44 | // 程序集的版本信息由下列四个值组成: 45 | // 46 | // 主版本 47 | // 次版本 48 | // 生成号 49 | // 修订号 50 | // 51 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 52 | //通过使用 "*",如下所示: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /Translator/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本: 4.0.30319.42000 5 | // 6 | // 对此文件的更改可能导致不正确的行为,如果 7 | // 重新生成代码,则所做更改将丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Translator.Properties 12 | { 13 | 14 | 15 | /// 16 | /// 强类型资源类,用于查找本地化字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// 返回此类使用的缓存 ResourceManager 实例。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Translator.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 重写当前线程的 CurrentUICulture 属性,对 56 | /// 使用此强类型资源类的所有资源查找执行重写。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Translator/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Translator/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Translator.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Translator/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Translator/SettingPages/DontClick_Selected_Page.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Translator/SettingPages/DontClick_Selected_Page.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace Translator.SettingPages 17 | { 18 | /// 19 | /// Introduction.xaml 的交互逻辑 20 | /// 21 | public partial class DontClick_Selected_Page : Page 22 | { 23 | public DontClick_Selected_Page() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Translator/SettingPages/General_Selected_Page.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Translator/SettingPages/General_Selected_Page.xaml.cs: -------------------------------------------------------------------------------- 1 | using HandyControl.Tools.Extension; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Data; 11 | using System.Windows.Documents; 12 | using System.Windows.Input; 13 | using System.Windows.Media; 14 | using System.Windows.Media.Imaging; 15 | using System.Windows.Navigation; 16 | using System.Windows.Shapes; 17 | using Translator.TranslatorApi; 18 | 19 | namespace Translator.SettingPages 20 | { 21 | /// 22 | /// Lang_Selected_Page.xaml 的交互逻辑 23 | /// 24 | public partial class General_Selected_Page : Page 25 | { 26 | 27 | private List LangList; 28 | 29 | public General_Selected_Page() 30 | { 31 | InitializeComponent(); 32 | LangList = Common.GetLangDict().Keys.ToList(); 33 | SrcLangCombox.ItemsSource = LangList; 34 | DstLangCombox.ItemsSource = LangList; 35 | TranslatorCombox.ItemsSource = Common.GetTranslatorDict().Keys.ToList(); 36 | 37 | 38 | TranslatorCombox.SelectedIndex = Common.GetTranslatorIndex(Settings.TranslatorName); 39 | TranslateTimeout.Text = Settings.TranslateTimeout.ToString(); 40 | SrcLangCombox.SelectedIndex = Common.GetLangIndex(Settings.Src_Lang); 41 | DstLangCombox.SelectedIndex = Common.GetLangIndex(Settings.Dst_Lang); 42 | } 43 | 44 | private void General_Click(object sender, RoutedEventArgs e) 45 | { 46 | Configuration config = Settings.GetAppConfig(); 47 | var mainWindow = (MainWindow)Application.Current.MainWindow; 48 | string TranslatorName = (string)TranslatorCombox.SelectedValue; 49 | if (!string.IsNullOrEmpty(TranslatorName)) 50 | { 51 | Settings.TranslatorName = TranslatorName; 52 | mainWindow.SetTranslator(Common.GetTranslatorDict()[Settings.TranslatorName]); 53 | // 写入config中 54 | config.AppSettings.Settings["Translator"].Value = TranslatorName; 55 | } 56 | string translateTimeout = TranslateTimeout.Text; 57 | if (!string.IsNullOrEmpty(translateTimeout)) 58 | { 59 | int timeout; 60 | try 61 | { 62 | timeout = int.Parse(translateTimeout); 63 | } 64 | catch 65 | { 66 | MessageBox.Show("输入数字格式有误"); 67 | return; 68 | } 69 | Settings.TranslateTimeout = timeout; 70 | mainWindow.SetTimeOut(timeout); 71 | config.AppSettings.Settings["TranslateTimeout"].Value = timeout.ToString(); 72 | } 73 | string src = (string)SrcLangCombox.SelectedValue; 74 | string dst = (string)DstLangCombox.SelectedValue; 75 | if (src == dst) // 可能为null 76 | { 77 | MessageBox.Show("源语言与目标语言相同"); 78 | return; 79 | } 80 | if (!string.IsNullOrEmpty(src)) 81 | { 82 | Settings.Src_Lang = Common.GetLangDict()[src]; 83 | mainWindow.SetSrcLang(Common.GetLangDict()[src]); 84 | config.AppSettings.Settings["Src_Lang"].Value = Common.GetLangDict()[src]; 85 | } 86 | if(!string.IsNullOrEmpty(dst)) 87 | { 88 | Settings.Dst_Lang = Common.GetLangDict()[dst]; 89 | mainWindow.SetDstLang(Common.GetLangDict()[dst]); 90 | config.AppSettings.Settings["Dst_Lang"].Value = Common.GetLangDict()[dst]; 91 | } 92 | MessageBox.Show("设置成功"); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Translator/SettingPages/TranslatorPages/Baidu_Selected_Page.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Translator/SettingPages/TranslatorPages/Baidu_Selected_Page.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Navigation; 15 | using System.Windows.Shapes; 16 | using Translator.TranslatorApi; 17 | 18 | namespace Translator.SettingPages.TranslatorPages 19 | { 20 | /// 21 | /// Baidu_Selected_Page.xaml 的交互逻辑 22 | /// 23 | public partial class Baidu_Selected_Page : Page 24 | { 25 | public Baidu_Selected_Page() 26 | { 27 | InitializeComponent(); 28 | 29 | appID.Text = Settings.BaiduAppId; 30 | key.Text = Settings.BaiduKey; 31 | } 32 | 33 | private void AppID_TextChanged(object sender, TextChangedEventArgs e) 34 | { 35 | Configuration config = Settings.GetAppConfig(); 36 | if (string.IsNullOrEmpty(Settings.BaiduAppId)) 37 | { 38 | config.AppSettings.Settings.Add("BaiduAppId", appID.Text); 39 | } 40 | else 41 | { 42 | config.AppSettings.Settings["BaiduAppId"].Value = appID.Text; 43 | } 44 | Settings.BaiduAppId = appID.Text; 45 | UpdateChanges(); 46 | } 47 | 48 | private void Key_TextChanged(object sender, TextChangedEventArgs e) 49 | { 50 | Configuration config = Settings.GetAppConfig(); 51 | if (string.IsNullOrEmpty(Settings.BaiduKey)) 52 | { 53 | config.AppSettings.Settings.Add("BaiduKey", key.Text); 54 | } 55 | else 56 | { 57 | config.AppSettings.Settings["BaiduKey"].Value = key.Text; 58 | } 59 | Settings.BaiduKey = key.Text; 60 | UpdateChanges(); 61 | } 62 | 63 | private void UpdateChanges() 64 | { 65 | Common.GetTranslatorDict()["百度翻译"].CheckUpdate(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Translator/SettingPages/TranslatorPages/ChatGPT_Selected_Page.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Translator/SettingPages/TranslatorPages/ChatGPT_Selected_Page.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Navigation; 15 | using System.Windows.Shapes; 16 | using Translator.TranslatorApi; 17 | 18 | namespace Translator.SettingPages.TranslatorPages 19 | { 20 | /// 21 | /// ChatGPT_Selected_Page.xaml 的交互逻辑 22 | /// 23 | public partial class ChatGPT_Selected_Page : Page 24 | { 25 | public ChatGPT_Selected_Page() 26 | { 27 | InitializeComponent(); 28 | 29 | key.Text = Settings.ChatgptKey; 30 | } 31 | 32 | private void Key_TextChanged(object sender, TextChangedEventArgs e) 33 | { 34 | Configuration config = Settings.GetAppConfig(); 35 | if (string.IsNullOrEmpty(Settings.ChatgptKey)) 36 | { 37 | config.AppSettings.Settings.Add("ChatgptKey", key.Text); 38 | } 39 | else 40 | { 41 | config.AppSettings.Settings["ChatgptKey"].Value = key.Text; 42 | } 43 | Settings.ChatgptKey = key.Text; 44 | UpdateChanges(); 45 | } 46 | 47 | private void UpdateChanges() 48 | { 49 | Common.GetTranslatorDict()["ChatGPT"].CheckUpdate(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Translator/SettingPages/TranslatorPages/Deepl_Selected_Page.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 为什么没有实现DeepL相关API? 15 | 16 | 17 |     Deepl的翻译效果无疑是十分优秀的,但是出于一下原因目前暂时不打算实现其接口。 18 |      - DeepL虽然添加了Api的术语表,但是在中文与其他语言之间并没有相应术语表。 19 |      - DeepL的api接口并不免费,每个月费用约为30元。且由于不支持中国银行卡,充值过程不友好。 20 |      - DeepL本身推出了一款免费的翻译软件DeepL,其使用体验以及稳定性无疑更佳。 21 |     综上,未来可能实现相应接口。 22 | 23 | 24 | Sorry! 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Translator/SettingPages/TranslatorPages/Deepl_Selected_Page.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace Translator.SettingPages.TranslatorPages 17 | { 18 | /// 19 | /// Deepl_Selected_Page.xaml 的交互逻辑 20 | /// 21 | public partial class Deepl_Selected_Page : Page 22 | { 23 | public Deepl_Selected_Page() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Translator/Settings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Configuration; 8 | using System.Windows; 9 | 10 | namespace Translator 11 | { 12 | internal static class Settings 13 | { 14 | public static int TranslateTimeout { get; set; } = int.Parse(ConfigurationManager.AppSettings["TranslateTimeout"]); 15 | 16 | public static string BaiduGlossary { get; set; } = ConfigurationManager.AppSettings["BaiduGlossary"]; 17 | 18 | public static string BackgroundColor { get; set; } = ConfigurationManager.AppSettings["BackgroundColor"]; 19 | 20 | public static string TranslatorName { get; set; } = ConfigurationManager.AppSettings["Translator"]; 21 | 22 | public static string Src_Lang { get; set; } = ConfigurationManager.AppSettings["Src_Lang"]; 23 | 24 | public static string Dst_Lang { get;set; } = ConfigurationManager.AppSettings["Dst_Lang"]; 25 | 26 | public static bool Valid { get; set; } = true; 27 | 28 | public static string BaiduAppId { get; set; } = ConfigurationManager.AppSettings["BaiduAppId"]; 29 | 30 | public static string BaiduKey { get; set; } = ConfigurationManager.AppSettings["BaiduKey"]; 31 | 32 | public static string ChatgptKey { get; set; } = ConfigurationManager.AppSettings["ChatgptKey"]; 33 | 34 | private static Configuration AppConfig = null; 35 | 36 | public static Configuration GetAppConfig() 37 | { 38 | if(AppConfig == null) 39 | { 40 | try 41 | { 42 | AppConfig = ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None); 43 | } 44 | catch (ConfigurationErrorsException cee) 45 | { 46 | MessageBox.Show(cee.Message); 47 | Environment.Exit(1); 48 | } 49 | } 50 | return AppConfig; 51 | } 52 | 53 | public static void SaveAppConfig() 54 | { 55 | if(AppConfig != null) 56 | { 57 | // 保存并刷新 58 | AppConfig.Save(System.Configuration.ConfigurationSaveMode.Modified); 59 | System.Configuration.ConfigurationManager.RefreshSection("appSettings"); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Translator/SettingsWindow.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Translator/SettingsWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Shapes; 15 | using Translator.SettingPages.TranslatorPages; 16 | 17 | namespace Translator 18 | { 19 | /// 20 | /// Settings.xaml 的交互逻辑 21 | /// 22 | public partial class SettingsWindow : Window 23 | { 24 | public SettingsWindow() 25 | { 26 | InitializeComponent(); 27 | } 28 | 29 | private void General_Selected(object sender, RoutedEventArgs e) 30 | { 31 | this.SettingFrame.Navigate(new Uri("pack://application:,,,/SettingPages/General_Selected_Page.xaml")); 32 | } 33 | 34 | private void ChatGPT_Selected(object sender, RoutedEventArgs e) 35 | { 36 | this.SettingFrame.Navigate(new Uri("pack://application:,,,/SettingPages/TranslatorPages/ChatGPT_Selected_Page.xaml")); 37 | } 38 | 39 | private void Baidu_Selected(object sender, RoutedEventArgs e) 40 | { 41 | this.SettingFrame.Navigate(new Uri("pack://application:,,,/SettingPages/TranslatorPages/Baidu_Selected_Page.xaml")); 42 | } 43 | 44 | private void Deepl_Selected(object sender, RoutedEventArgs e) 45 | { 46 | this.SettingFrame.Navigate(new Uri("pack://application:,,,/SettingPages/TranslatorPages/Deepl_Selected_Page.xaml")); 47 | } 48 | 49 | private void DontClick_Selected(object sender, RoutedEventArgs e) 50 | { 51 | this.SettingFrame.Navigate(new Uri("pack://application:,,,/SettingPages/DontClick_Selected_Page.xaml")); 52 | } 53 | 54 | ~SettingsWindow() 55 | { 56 | Settings.SaveAppConfig(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Translator/Translator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {581423A1-CAF2-4F9A-AA74-ECE8171C317F} 8 | WinExe 9 | Translator 10 | Translator_v2.2 11 | v4.7.2 12 | 512 13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 4 15 | true 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | myico.ico 39 | 40 | 41 | 42 | ..\..\..\Downloads\HandyControl-v3.4.0-Release\net472\HandyControl.dll 43 | 44 | 45 | ..\..\..\Downloads\Json130r3\Bin\net45\Newtonsoft.Json.dll 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 4.0 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | MSBuild:Compile 66 | Designer 67 | 68 | 69 | BackgroundWindow.xaml 70 | 71 | 72 | DontClick_Selected_Page.xaml 73 | 74 | 75 | General_Selected_Page.xaml 76 | 77 | 78 | Baidu_Selected_Page.xaml 79 | 80 | 81 | ChatGPT_Selected_Page.xaml 82 | 83 | 84 | Deepl_Selected_Page.xaml 85 | 86 | 87 | 88 | SettingsWindow.xaml 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Designer 97 | MSBuild:Compile 98 | 99 | 100 | MSBuild:Compile 101 | Designer 102 | 103 | 104 | App.xaml 105 | Code 106 | 107 | 108 | MainWindow.xaml 109 | Code 110 | 111 | 112 | Designer 113 | MSBuild:Compile 114 | 115 | 116 | Designer 117 | MSBuild:Compile 118 | 119 | 120 | Designer 121 | MSBuild:Compile 122 | 123 | 124 | Designer 125 | MSBuild:Compile 126 | 127 | 128 | Designer 129 | MSBuild:Compile 130 | 131 | 132 | Designer 133 | MSBuild:Compile 134 | 135 | 136 | 137 | 138 | Code 139 | 140 | 141 | True 142 | True 143 | Resources.resx 144 | 145 | 146 | True 147 | Settings.settings 148 | True 149 | 150 | 151 | ResXFileCodeGenerator 152 | Resources.Designer.cs 153 | 154 | 155 | SettingsSingleFileGenerator 156 | Settings.Designer.cs 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Translator/TranslatorApi/Common.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Translator.TranslatorApi.Impl; 8 | 9 | namespace Translator.TranslatorApi 10 | { 11 | internal static class Common 12 | { 13 | private static Dictionary langDict = new Dictionary() { 14 | {"中文","zh" }, 15 | {"英文","en" }, 16 | {"日文","jp" } 17 | }; 18 | 19 | private static Dictionary translatorDict = new Dictionary() 20 | { 21 | {"ChatGPT",new ChatgptTranslator() }, 22 | {"百度翻译",new BaiduTranslator() } 23 | }; 24 | 25 | public static Dictionary GetLangDict() { return langDict; } 26 | 27 | public static Dictionary GetTranslatorDict() { return translatorDict; } 28 | 29 | public static int GetTranslatorIndex(string s) 30 | { 31 | for(int i = 0;i < translatorDict.Count; ++i) 32 | { 33 | if(translatorDict.ElementAt(i).Key == s) 34 | { 35 | return i; 36 | } 37 | } 38 | return -1; 39 | } 40 | 41 | public static int GetLangIndex(string s) 42 | { 43 | for (int i = 0; i < langDict.Count; ++i) 44 | { 45 | if (langDict.ElementAt(i).Value == s) 46 | { 47 | return i; 48 | } 49 | } 50 | return -1; 51 | } 52 | 53 | public static string MD5IN32(string s) 54 | { 55 | MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); 56 | byte[] data = md5.ComputeHash(Encoding.Default.GetBytes(s)); 57 | StringBuilder sBuilder = new StringBuilder(); 58 | for (int i = 0; i < data.Length; i++) 59 | { 60 | sBuilder.Append(data[i].ToString("x2"));//转化为小写的16进制 61 | } 62 | return sBuilder.ToString(); 63 | 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Translator/TranslatorApi/Impl/BaiduTranslator.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net.Http; 6 | using System.Security.Cryptography; 7 | using System.Security.Cryptography.X509Certificates; 8 | using System.Security.Policy; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using Translator.TranslatorApi; 12 | 13 | namespace Translator.TranslatorApi.Impl 14 | { 15 | public class BaiduTranslator : ITranslator 16 | { 17 | // 使用百度通用翻译api 18 | const string url = "https://fanyi-api.baidu.com/api/trans/vip/translate?"; 19 | 20 | string AppId = Settings.BaiduAppId; 21 | string Key = Settings.BaiduKey; 22 | 23 | // 默认翻译选项 24 | string Action = Settings.BaiduGlossary; 25 | 26 | public void CheckUpdate() 27 | { 28 | AppId = Settings.BaiduAppId; 29 | Key = Settings.BaiduKey; 30 | } 31 | 32 | public async Task TranslateAsync(string text, string src, string dst) 33 | { 34 | StringBuilder sb = new StringBuilder(); 35 | var client = new HttpClient(); 36 | client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Content-Type", "application/x-www-form-urlencoded"); 37 | UInt32 salt = Salt(); 38 | sb.Append(url); 39 | // text做url处理 40 | sb.Append("q="+Uri.EscapeDataString(text)); 41 | sb.Append("&from=" + src); 42 | sb.Append("&to=" + dst); 43 | sb.Append("&appid=" + AppId); 44 | sb.Append("&salt=" + salt); 45 | sb.Append("&sign=" + Sign(text,salt)); 46 | sb.Append("&action=" + Action); 47 | HttpResponseMessage response; 48 | try 49 | { 50 | response = await client.PostAsync(sb.ToString(),null); 51 | } 52 | catch (HttpRequestException e) 53 | { 54 | return e.Message; 55 | } 56 | var getStr = response.Content.ReadAsStringAsync().Result; 57 | // 获取正常json 58 | try 59 | { 60 | var res = (Result)JsonConvert.DeserializeObject(getStr); 61 | return res.trans_Result[0].Dst; 62 | } 63 | catch 64 | { 65 | try 66 | { 67 | // 错误json 68 | var err_res = (Error)JsonConvert.DeserializeObject(getStr); 69 | return err_res.Error_msg; 70 | } 71 | catch 72 | { 73 | return "Unknown Error"; 74 | } 75 | } 76 | } 77 | 78 | 79 | public void SetAppId(string s) 80 | { 81 | AppId = s; 82 | } 83 | 84 | public void SetKey(string s) 85 | { 86 | Key = s; 87 | } 88 | private string Sign(string text,UInt32 salt) 89 | { 90 | return Common.MD5IN32(AppId + text + salt + Key); 91 | } 92 | 93 | 94 | // 生成10位随机salt 95 | private static UInt32 Salt() 96 | { 97 | 98 | byte[] randomBytes = new byte[4]; 99 | RNGCryptoServiceProvider rngServiceProvider = new RNGCryptoServiceProvider(); 100 | rngServiceProvider.GetNonZeroBytes(randomBytes); 101 | return BitConverter.ToUInt32(randomBytes, 0); 102 | } 103 | 104 | 105 | // 辅助嵌套类 106 | class Result 107 | { 108 | internal class Trans_Result 109 | { 110 | public string Src { get; set; } 111 | public string Dst { get; set; } 112 | } 113 | public string From { get; set; } 114 | public string To { get; set; } 115 | public Trans_Result[] trans_Result { get; set;} 116 | } 117 | 118 | class Error 119 | { 120 | public string Error_code { get; set; } 121 | public string Error_msg { get; set; } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Translator/TranslatorApi/Impl/ChatgptTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO.Packaging; 4 | using System.Linq; 5 | using System.Net.Http; 6 | using System.Security.Cryptography; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using HandyControl.Expression.Shapes; 10 | using Newtonsoft.Json; 11 | using static System.Net.Mime.MediaTypeNames; 12 | 13 | namespace Translator.TranslatorApi.Impl 14 | { 15 | public class ChatgptTranslator : ITranslator 16 | { 17 | string apiKey = Settings.ChatgptKey; 18 | const string url = "https://api.openai.com/v1/chat/completions"; 19 | 20 | public void CheckUpdate() 21 | { 22 | apiKey = Settings.ChatgptKey; 23 | } 24 | 25 | public async Task TranslateAsync(string text, string src, string dst) 26 | { 27 | return await DoTranslation(text,src,dst); 28 | } 29 | 30 | public void SetApiKey(string s) 31 | { 32 | apiKey = s; 33 | } 34 | 35 | 36 | private async Task DoTranslation(string text,string src,string dst) 37 | { 38 | var client = new HttpClient(); 39 | 40 | var data = new 41 | { 42 | model = "gpt-3.5-turbo", 43 | messages = new Message[] {new Message{role="system",content="Please translate "+src+" into "+dst}, // 此处role和content对应api中参数,不可修改 44 | new Message { role = "user", content = text } } 45 | }; 46 | var requestBody = JsonConvert.SerializeObject(data); 47 | client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey); 48 | var content = new StringContent(requestBody, System.Text.Encoding.UTF8, "application/json"); 49 | HttpResponseMessage response; 50 | try 51 | { 52 | response = await client.PostAsync(url, content); 53 | } 54 | catch (HttpRequestException e) 55 | { 56 | return e.Message; 57 | } 58 | var getStr = response.Content.ReadAsStringAsync().Result; 59 | 60 | 61 | try 62 | { 63 | var res = (Result)JsonConvert.DeserializeObject(getStr); 64 | return res.Choices[0].Message.content.Trim(); 65 | } 66 | catch 67 | { 68 | try 69 | { 70 | // 使用Error_Message类捕获错误json,并输出错误信息 71 | var err_res = (Error_Message)JsonConvert.DeserializeObject(getStr); 72 | return err_res.error.Message; 73 | } 74 | catch 75 | { 76 | return "Unknown Error"; 77 | } 78 | } 79 | } 80 | 81 | public async void TestChatgpt(string s) 82 | { 83 | var client = new HttpClient(); 84 | var data = new 85 | { 86 | model = "gpt-3.5-turbo", 87 | messages = new Message[] {new Message{role="user",content=s}, // 此处role和content对应api中参数,不可修改 88 | } 89 | }; 90 | var requestBody = JsonConvert.SerializeObject(data); 91 | client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey); 92 | var content = new StringContent(requestBody, System.Text.Encoding.UTF8, "application/json"); 93 | var response = await client.PostAsync(url, content); 94 | Console.WriteLine(response.Content.ReadAsStringAsync().Result); 95 | } 96 | 97 | 98 | //辅助嵌套类 99 | 100 | private class Message 101 | { 102 | public string role { get; set; } 103 | public string content { get; set; } 104 | 105 | } 106 | 107 | private class Result 108 | { 109 | internal class Usage 110 | { 111 | public int Prompt_tokens { get; set; } 112 | public int Completion_tokens { get; set; } 113 | public int Total_tokens { get; set; } 114 | } 115 | internal class Choice 116 | { 117 | public Message Message { get; set; } 118 | public string Finish_reason { get; set; } 119 | public int Index { get; set; } 120 | } 121 | public string Id { get; set; } 122 | public string Object { get; set; } 123 | public long Created { get; set; } 124 | public string Model { get; set; } 125 | public Usage usage { get; set; } 126 | public Choice[] Choices { get; set; } 127 | 128 | } 129 | 130 | 131 | private class Error_Message 132 | { 133 | internal class Error 134 | { 135 | public string Message { get; set; } 136 | public string Type { get; set; } 137 | public string Param { get; set; } 138 | public string Code { get; set; } 139 | } 140 | public Error error { get; set; } 141 | } 142 | } 143 | } 144 | 145 | -------------------------------------------------------------------------------- /Translator/TranslatorApi/Impl/DeeplTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Translator.TranslatorApi.Impl 9 | { 10 | /// 11 | /// 由于WPF使用的.net框架版本最高为4.7.2,Deepl官方提供的.net类库所支持框架版本为5.0,因此使用不了 12 | /// 同时,Deepl并不支持中文的术语库,也无法使用中国信用卡申请api 13 | /// 所幸Deepl推出了免费的应用程序,可完成与本程序相同的功能 14 | /// 综上,此接口暂时不考虑实现 15 | /// 16 | public class DeeplTranslator : ITranslator 17 | { 18 | public Task TranslateAsync(string text, string src, string dst) 19 | { 20 | // todo 21 | return null; 22 | } 23 | 24 | public void CheckUpdate() { } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Translator/TranslatorApi/Translator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Translator.TranslatorApi 8 | { 9 | public interface ITranslator 10 | { 11 | Task TranslateAsync(string text,string src,string dst); 12 | 13 | void CheckUpdate(); 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /Translator/myico.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tofweod/Translator/2aadde8f462344b3f8d4d0516bcdb182c61890c5/Translator/myico.ico --------------------------------------------------------------------------------