├── .gitignore ├── Images ├── 20190226132523.png └── 20190226132619.png ├── LICENSE ├── Material ├── ProgramIcon.png ├── ProgramIcon.psd ├── Radmin.png ├── device-laptop-R.png ├── device-laptop-W.png └── device-laptop.psd ├── OtherSource └── WilsonGlobalSystemHooks_src.zip ├── README.md ├── RadminSavePassword.sln └── RadminSavePassword ├── App.config ├── Config ├── LoginType.cs ├── ServerInfo.cs └── SystemConfig.cs ├── EntryptDecrypt.cs ├── FodyWeavers.xml ├── FodyWeavers.xsd ├── Global.cs ├── Hook ├── CBTHook.cs ├── Hook.cs ├── KeyboardLLHook.cs ├── MouseLLHook.cs ├── RadminInput.cs ├── ServerInfoEventArgs.cs └── WindowsApi.cs ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Program.cs ├── ProgramIcon.ico ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── RadminSavePassword.csproj ├── Resources ├── btnOpen_Image.png ├── sign-ban.png ├── tag-alt.png └── tag.png ├── ServerInfoForm.Designer.cs ├── ServerInfoForm.cs ├── ServerInfoForm.resx └── costura32 └── GlobalCbtHook.dll /.gitignore: -------------------------------------------------------------------------------- 1 | RadminSavePassword/obj/ 2 | RadminSavePassword/bin/ 3 | *.DotSettings 4 | *.suo 5 | *.vs -------------------------------------------------------------------------------- /Images/20190226132523.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Images/20190226132523.png -------------------------------------------------------------------------------- /Images/20190226132619.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Images/20190226132619.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Material/ProgramIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Material/ProgramIcon.png -------------------------------------------------------------------------------- /Material/ProgramIcon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Material/ProgramIcon.psd -------------------------------------------------------------------------------- /Material/Radmin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Material/Radmin.png -------------------------------------------------------------------------------- /Material/device-laptop-R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Material/device-laptop-R.png -------------------------------------------------------------------------------- /Material/device-laptop-W.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Material/device-laptop-W.png -------------------------------------------------------------------------------- /Material/device-laptop.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/Material/device-laptop.psd -------------------------------------------------------------------------------- /OtherSource/WilsonGlobalSystemHooks_src.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/OtherSource/WilsonGlobalSystemHooks_src.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RadminSavePassword 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/rdbyia8eoogscfed?svg=true)](https://ci.appveyor.com/project/xjj0906/radminsavepassword) 4 | 5 | 程序会自动记录并管理 Radmin 的密码 6 | 7 | ## **适用于以下 Radmin** 8 | 9 | | 属性 | 值 | 10 | |------|:------:| 11 | | 版本 |3.4、3.5| 12 | | 语言 | 多国 | 13 | 14 | ## **如何使用:** 15 | 16 | * 运行 RadminSavePassword 程序 17 | * 打开 Radmin Viewer 的连接,如连接的名称为:192.168.151.76 18 | * 勾选`另存为缺省值`,点击`确认` 19 | 20 | ![20190226132523](/Images/20190226132523.png) 21 | 22 | * 程序则自动保存名称为 192.168.151.76 的用户名密码 23 | 24 | ![20190226132619](/Images/20190226132619.png) 25 | 26 | ## **实现原理:** 27 | 28 | - 程序在启动后,通过安装系统钩子(Hook),对 Windows 窗体创建销毁、鼠标、键盘进行监控,从而达到获取 Radmin 程序的登陆信息 29 | 30 | ## **关于钩子(Hook):** 31 | 32 | - 钩子(Hook),是 Windows 消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理 Window 消息或特定事件。 33 | - 钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。 34 | - 来源:[百度百科] 35 | 36 | > **注意:** 由于 .Net 程序安装 WH_SHELL 和 WH_CBT Hook 这两个Hook会失败,因此通过 C++ 的 DLL 间接地安装 Hook,然后再通知 .Net 的程序进行处理的手段 37 | > 38 | > 详情参阅: 39 | > [http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H](http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H) 40 | 41 | [百度百科]:http://baike.baidu.com/link?url=vvhHuJDnkVN4IaE319drtMogwGv4Jf-ra3Cik8IcMHvf8iqUsa2noXU42twUMYq9VZyfK1Aml_ApNXzx80C0Q_ 42 | -------------------------------------------------------------------------------- /RadminSavePassword.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RadminSavePassword", "RadminSavePassword\RadminSavePassword.csproj", "{E3EE68E8-55FA-471C-A8A1-CCE2E89D54B3}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {E3EE68E8-55FA-471C-A8A1-CCE2E89D54B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {E3EE68E8-55FA-471C-A8A1-CCE2E89D54B3}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {E3EE68E8-55FA-471C-A8A1-CCE2E89D54B3}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {E3EE68E8-55FA-471C-A8A1-CCE2E89D54B3}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /RadminSavePassword/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /RadminSavePassword/Config/LoginType.cs: -------------------------------------------------------------------------------- 1 | namespace RadminSavePassword 2 | { 3 | /// 4 | /// 登陆类型 5 | /// 6 | public enum LoginType 7 | { 8 | Radmin = 0, 9 | Windows = 1, 10 | } 11 | } -------------------------------------------------------------------------------- /RadminSavePassword/Config/ServerInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace RadminSavePassword 5 | { 6 | [Serializable] 7 | public class ServerInfo : ISerializable 8 | { 9 | private readonly EntryptDecrypt _entryptDecrypt = new EntryptDecrypt(); 10 | 11 | public LoginType LoginType { get; set; } 12 | 13 | public string Name { get; set; } 14 | 15 | public string UserName { get; set; } 16 | 17 | public string Password { get; set; } 18 | 19 | public string Domain { get; set; } 20 | 21 | public ServerInfo() 22 | { 23 | } 24 | 25 | protected ServerInfo(SerializationInfo info, StreamingContext context) 26 | { 27 | LoginType = (LoginType)info.GetInt32("LoginType"); 28 | Name = info.GetString("Name"); 29 | UserName = info.GetString("UserName"); 30 | 31 | string decryptPassword = _entryptDecrypt.Decrypt(info.GetString("Password")); 32 | Password = decryptPassword; 33 | 34 | Domain = info.GetString("Domain"); 35 | } 36 | 37 | public void GetObjectData(SerializationInfo info, StreamingContext context) 38 | { 39 | info.AddValue("LoginType", (int)LoginType); 40 | info.AddValue("Name", Name); 41 | info.AddValue("UserName", UserName); 42 | 43 | string entryptPassword = _entryptDecrypt.Encrypt(Password); 44 | info.AddValue("Password", entryptPassword); 45 | 46 | info.AddValue("Domain", Domain); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /RadminSavePassword/Config/SystemConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Reflection; 5 | using System.Runtime.Serialization.Formatters.Binary; 6 | using System.Windows.Forms; 7 | 8 | namespace RadminSavePassword 9 | { 10 | [Serializable] 11 | public class SystemConfig 12 | { 13 | // Don't use Application.ExecutablePath 14 | // see https://stackoverflow.com/questions/12945805/odd-c-sharp-path-issue 15 | private static readonly string ExecutablePath = Assembly.GetEntryAssembly().Location; 16 | 17 | private static string Key = "RadminSavePassword_" + Application.StartupPath.GetHashCode(); 18 | 19 | public bool IsAutoEnter { get; set; } 20 | 21 | public string RadminOpenPath { get; set; } 22 | 23 | public Dictionary ServerList { get; set; } 24 | 25 | public SystemConfig() 26 | { 27 | ServerList = new Dictionary(); 28 | } 29 | 30 | public static SystemConfig Load(string filePath) 31 | { 32 | using (Stream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 33 | { 34 | byte[] byteData = new byte[fStream.Length]; 35 | fStream.Read(byteData, 0, byteData.Length); 36 | fStream.Position = 0; 37 | 38 | BinaryFormatter binaryFormat = new BinaryFormatter(); 39 | SystemConfig config = (SystemConfig)binaryFormat.Deserialize(fStream); 40 | 41 | return config; 42 | } 43 | } 44 | 45 | public static void Save(SystemConfig config, string filePath) 46 | { 47 | using (Stream fStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) 48 | { 49 | BinaryFormatter binaryFormat = new BinaryFormatter(); 50 | binaryFormat.Serialize(fStream, config); 51 | 52 | fStream.Flush(); 53 | } 54 | } 55 | 56 | #region 自动启动 57 | /// 58 | /// 设置开机启动项 59 | /// 60 | /// 是否启动 61 | public static void SetAutoStart(bool started) 62 | { 63 | Microsoft.Win32.RegistryKey HKCU = Microsoft.Win32.Registry.CurrentUser; 64 | Microsoft.Win32.RegistryKey runKey = HKCU.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 65 | if (started) 66 | { 67 | try 68 | { 69 | var names = runKey.GetValueNames(); 70 | foreach (var name in names) 71 | { 72 | if (name.StartsWith("RadminSavePassword_")) 73 | runKey.DeleteValue(name); 74 | } 75 | runKey.SetValue(Key, $"{ExecutablePath} --min-mode"); 76 | } 77 | catch { } 78 | finally 79 | { 80 | HKCU.Close(); 81 | } 82 | } 83 | else 84 | { 85 | try 86 | { 87 | runKey.DeleteValue(Key); 88 | HKCU.Close(); 89 | } 90 | catch { } 91 | finally 92 | { 93 | HKCU.Close(); 94 | } 95 | } 96 | } 97 | 98 | /// 99 | /// 检查开机启动项是否有效 100 | /// 101 | /// 102 | public static bool CheckIsAutoStart() 103 | { 104 | Microsoft.Win32.RegistryKey HKCU = Microsoft.Win32.Registry.CurrentUser; 105 | Microsoft.Win32.RegistryKey runKey = HKCU.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 106 | 107 | try 108 | { 109 | string[] runList = runKey.GetValueNames(); 110 | foreach (string item in runList) 111 | { 112 | if (item.Equals(Key, StringComparison.OrdinalIgnoreCase)) 113 | return true; 114 | } 115 | return false; 116 | } 117 | finally 118 | { 119 | HKCU.Close(); 120 | } 121 | } 122 | #endregion 123 | } 124 | } -------------------------------------------------------------------------------- /RadminSavePassword/EntryptDecrypt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | 6 | namespace RadminSavePassword 7 | { 8 | public class EntryptDecrypt 9 | { 10 | const string Key = "~x1o5*7%";//8位key 11 | 12 | public string Encrypt(string pToEncrypt) 13 | { 14 | if (string.IsNullOrEmpty(pToEncrypt)) 15 | return string.Empty; 16 | try 17 | { 18 | byte[] rgbKey = Encoding.UTF8.GetBytes(Key); 19 | byte[] rgbIV = Encoding.UTF8.GetBytes(Key); 20 | byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt); 21 | DESCryptoServiceProvider dcsp = new DESCryptoServiceProvider(); 22 | using (MemoryStream mStream = new MemoryStream()) 23 | { 24 | using (CryptoStream cStream = new CryptoStream(mStream, dcsp.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write)) 25 | { 26 | cStream.Write(inputByteArray, 0, inputByteArray.Length); 27 | cStream.FlushFinalBlock(); 28 | return Convert.ToBase64String(mStream.ToArray()); 29 | } 30 | } 31 | } 32 | catch 33 | { 34 | return string.Empty; 35 | } 36 | } 37 | 38 | public string Decrypt(string pToDecrypt) 39 | { 40 | if (string.IsNullOrEmpty(pToDecrypt)) 41 | return string.Empty; 42 | try 43 | { 44 | byte[] rgbKey = Encoding.UTF8.GetBytes(Key); 45 | byte[] rgbIV = Encoding.UTF8.GetBytes(Key); 46 | byte[] inputByteArray = Convert.FromBase64String(pToDecrypt); 47 | DESCryptoServiceProvider dcsp = new DESCryptoServiceProvider(); 48 | using (MemoryStream mStream = new MemoryStream()) 49 | { 50 | using (CryptoStream cStream = new CryptoStream(mStream, dcsp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write)) 51 | { 52 | cStream.Write(inputByteArray, 0, inputByteArray.Length); 53 | cStream.FlushFinalBlock(); 54 | return Encoding.UTF8.GetString(mStream.ToArray()); 55 | } 56 | } 57 | } 58 | catch 59 | { 60 | return string.Empty; 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /RadminSavePassword/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /RadminSavePassword/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 23 | 24 | 25 | 26 | 27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 28 | 29 | 30 | 31 | 32 | The order of preloaded assemblies, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | 38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 39 | 40 | 41 | 42 | 43 | Controls if .pdbs for reference assemblies are also embedded. 44 | 45 | 46 | 47 | 48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 49 | 50 | 51 | 52 | 53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 54 | 55 | 56 | 57 | 58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 59 | 60 | 61 | 62 | 63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 64 | 65 | 66 | 67 | 68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 69 | 70 | 71 | 72 | 73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 74 | 75 | 76 | 77 | 78 | A list of unmanaged 32 bit assembly names to include, delimited with |. 79 | 80 | 81 | 82 | 83 | A list of unmanaged 64 bit assembly names to include, delimited with |. 84 | 85 | 86 | 87 | 88 | The order of preloaded assemblies, delimited with |. 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 97 | 98 | 99 | 100 | 101 | A comma-separated list of error codes that can be safely ignored in assembly verification. 102 | 103 | 104 | 105 | 106 | 'false' to turn off automatic generation of the XML Schema file. 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /RadminSavePassword/Global.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace RadminSavePassword 4 | { 5 | public static class Global 6 | { 7 | public static string ProgramText = "Radmin保存密码"; 8 | 9 | public static SystemConfig SystemConfig { get; set; } 10 | public static Dictionary UnSaveServerInfos { get; set; } 11 | 12 | static Global() 13 | { 14 | SystemConfig = new SystemConfig(); 15 | UnSaveServerInfos = new Dictionary(); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/CBTHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace RadminSavePassword.Hook 5 | { 6 | public class CBTHook : Hook 7 | { 8 | // Functions imported from our unmanaged DLL 9 | [DllImport("GlobalCbtHook.dll", CallingConvention = CallingConvention.Cdecl)] 10 | protected static extern bool InitializeCbtHook(int threadID, IntPtr DestWindow); 11 | [DllImport("GlobalCbtHook.dll", CallingConvention = CallingConvention.Cdecl)] 12 | protected static extern void UninitializeCbtHook(); 13 | 14 | // Values retreived with RegisterWindowMessage 15 | private int _MsgID_CBT_HookReplaced; 16 | private int _MsgID_CBT_Activate; 17 | private int _MsgID_CBT_CreateWnd; 18 | private int _MsgID_CBT_DestroyWnd; 19 | private int _MsgID_CBT_MinMax; 20 | private int _MsgID_CBT_MoveSize; 21 | private int _MsgID_CBT_SetFocus; 22 | private int _MsgID_CBT_SysCommand; 23 | 24 | public delegate void HookReplacedEventHandler(); 25 | public delegate void WindowEventHandler(IntPtr Handle); 26 | public delegate void SysCommandEventHandler(int SysCommand, int lParam); 27 | 28 | public event HookReplacedEventHandler HookReplaced; 29 | public event WindowEventHandler Activate; 30 | public event WindowEventHandler CreateWindow; 31 | public event WindowEventHandler DestroyWindow; 32 | public event WindowEventHandler MinMax; 33 | public event WindowEventHandler MoveSize; 34 | public event WindowEventHandler SetFocus; 35 | public event SysCommandEventHandler SysCommand; 36 | 37 | public CBTHook(IntPtr Handle) 38 | : base(Handle) 39 | { 40 | } 41 | 42 | protected override void OnStart() 43 | { 44 | // Retreive the message IDs that we'll look for in WndProc 45 | _MsgID_CBT_HookReplaced = RegisterWindowMessage("WILSON_HOOK_CBT_REPLACED"); 46 | _MsgID_CBT_Activate = RegisterWindowMessage("WILSON_HOOK_HCBT_ACTIVATE"); 47 | _MsgID_CBT_CreateWnd = RegisterWindowMessage("WILSON_HOOK_HCBT_CREATEWND"); 48 | _MsgID_CBT_DestroyWnd = RegisterWindowMessage("WILSON_HOOK_HCBT_DESTROYWND"); 49 | _MsgID_CBT_MinMax = RegisterWindowMessage("WILSON_HOOK_HCBT_MINMAX"); 50 | _MsgID_CBT_MoveSize = RegisterWindowMessage("WILSON_HOOK_HCBT_MOVESIZE"); 51 | _MsgID_CBT_SetFocus = RegisterWindowMessage("WILSON_HOOK_HCBT_SETFOCUS"); 52 | _MsgID_CBT_SysCommand = RegisterWindowMessage("WILSON_HOOK_HCBT_SYSCOMMAND"); 53 | 54 | // Start the hook 55 | InitializeCbtHook(0, _Handle); 56 | } 57 | 58 | protected override void OnStop() 59 | { 60 | UninitializeCbtHook(); 61 | } 62 | 63 | public override void ProcessWindowMessage(ref System.Windows.Forms.Message m) 64 | { 65 | if (m.Msg == _MsgID_CBT_HookReplaced) 66 | { 67 | if (HookReplaced != null) 68 | HookReplaced(); 69 | } 70 | else if (m.Msg == _MsgID_CBT_Activate) 71 | { 72 | if (Activate != null) 73 | Activate(m.WParam); 74 | } 75 | else if (m.Msg == _MsgID_CBT_CreateWnd) 76 | { 77 | if (CreateWindow != null) 78 | CreateWindow(m.WParam); 79 | } 80 | else if (m.Msg == _MsgID_CBT_DestroyWnd) 81 | { 82 | if (DestroyWindow != null) 83 | DestroyWindow(m.WParam); 84 | } 85 | else if (m.Msg == _MsgID_CBT_MinMax) 86 | { 87 | if (MinMax != null) 88 | MinMax(m.WParam); 89 | } 90 | else if (m.Msg == _MsgID_CBT_MoveSize) 91 | { 92 | if (MoveSize != null) 93 | MoveSize(m.WParam); 94 | } 95 | else if (m.Msg == _MsgID_CBT_SetFocus) 96 | { 97 | if (SetFocus != null) 98 | SetFocus(m.WParam); 99 | } 100 | else if (m.Msg == _MsgID_CBT_SysCommand) 101 | { 102 | if (SysCommand != null) 103 | SysCommand(m.WParam.ToInt32(), m.LParam.ToInt32()); 104 | } 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/Hook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace RadminSavePassword.Hook 5 | { 6 | public abstract class Hook 7 | { 8 | // API call needed to retreive the value of the messages to intercept from the unmanaged DLL 9 | [DllImport("user32.dll")] 10 | protected static extern int RegisterWindowMessage(string lpString); 11 | 12 | public delegate void HookReplacedEventHandler(); 13 | public delegate void WindowEventHandler(IntPtr Handle); 14 | public delegate void SysCommandEventHandler(int SysCommand, int lParam); 15 | public delegate void ActivateShellWindowEventHandler(); 16 | public delegate void TaskmanEventHandler(); 17 | public delegate void BasicHookEventHandler(IntPtr Handle1, IntPtr Handle2); 18 | public delegate void WndProcEventHandler(IntPtr Handle, IntPtr Message, IntPtr wParam, IntPtr lParam); 19 | 20 | protected bool _IsActive = false; 21 | protected IntPtr _Handle; 22 | 23 | public Hook(IntPtr Handle) 24 | { 25 | _Handle = Handle; 26 | } 27 | 28 | public void Start() 29 | { 30 | if (!_IsActive) 31 | { 32 | _IsActive = true; 33 | OnStart(); 34 | } 35 | } 36 | 37 | public void Stop() 38 | { 39 | if (_IsActive) 40 | { 41 | OnStop(); 42 | _IsActive = false; 43 | } 44 | } 45 | 46 | ~Hook() 47 | { 48 | Stop(); 49 | } 50 | 51 | public bool IsActive 52 | { 53 | get { return _IsActive; } 54 | } 55 | 56 | protected abstract void OnStart(); 57 | protected abstract void OnStop(); 58 | public abstract void ProcessWindowMessage(ref System.Windows.Forms.Message m); 59 | } 60 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/KeyboardLLHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Forms; 4 | 5 | namespace RadminSavePassword.Hook 6 | { 7 | public class KeyboardLLHook : Hook 8 | { 9 | [DllImport("GlobalCbtHook.dll", CallingConvention = CallingConvention.Cdecl)] 10 | private static extern void InitializeKeyboardLLHook(int threadID, IntPtr DestWindow); 11 | [DllImport("GlobalCbtHook.dll", CallingConvention = CallingConvention.Cdecl)] 12 | private static extern void UninitializeKeyboardLLHook(); 13 | 14 | // Values retreived with RegisterWindowMessage 15 | private int _MsgID_KeyboardLL; 16 | private int _MsgID_KeyboardLL_HookReplaced; 17 | 18 | public event HookReplacedEventHandler HookReplaced; 19 | public event KeyEventHandler KeyDown; 20 | public event KeyEventHandler KeyUp; 21 | public event KeyEventHandler KeyPress; 22 | 23 | public KeyboardLLHook(IntPtr Handle) 24 | : base(Handle) 25 | { 26 | } 27 | 28 | protected override void OnStart() 29 | { 30 | // Retreive the message IDs that we'll look for in WndProc 31 | _MsgID_KeyboardLL = RegisterWindowMessage("WILSON_HOOK_KEYBOARDLL"); 32 | _MsgID_KeyboardLL_HookReplaced = RegisterWindowMessage("WILSON_HOOK_KEYBOARDLL_REPLACED"); 33 | 34 | // Start the hook 35 | InitializeKeyboardLLHook(0, _Handle); 36 | } 37 | 38 | protected override void OnStop() 39 | { 40 | UninitializeKeyboardLLHook(); 41 | } 42 | 43 | public override void ProcessWindowMessage(ref System.Windows.Forms.Message m) 44 | { 45 | if (m.Msg == _MsgID_KeyboardLL) 46 | { 47 | KBDLLHOOKSTRUCT kbhs = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(m.LParam, typeof(KBDLLHOOKSTRUCT)); 48 | if (m.WParam == (IntPtr)WindowsApi.WM_KEYDOWN && KeyDown != null) 49 | KeyDown(this, new KeyEventArgs((Keys)kbhs.vkCode)); 50 | else 51 | { 52 | if (m.WParam == (IntPtr)WindowsApi.WM_KEYUP && KeyUp != null) 53 | KeyUp.Invoke(this, new KeyEventArgs((Keys)kbhs.vkCode)); 54 | if (m.WParam == (IntPtr)WindowsApi.WM_KEYUP && KeyPress != null) 55 | KeyPress(this, new KeyEventArgs((Keys)kbhs.vkCode)); 56 | } 57 | } 58 | else if (m.Msg == _MsgID_KeyboardLL_HookReplaced) 59 | { 60 | if (HookReplaced != null) 61 | HookReplaced(); 62 | } 63 | } 64 | 65 | [StructLayout(LayoutKind.Sequential)] 66 | public class KBDLLHOOKSTRUCT 67 | { 68 | /// 69 | /// 虚拟按键码(1--254) 70 | /// 71 | public int vkCode; 72 | /// 73 | /// 硬件按键扫描码 74 | /// 75 | public int scanCode; 76 | /// 77 | /// 键按下:128 抬起:0 78 | /// 79 | public int flags; 80 | /// 81 | /// 消息时间戳间 82 | /// 83 | public int time; 84 | /// 85 | /// 额外信息 86 | /// 87 | public int dwExtraInfo; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/MouseLLHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Forms; 4 | 5 | namespace RadminSavePassword.Hook 6 | { 7 | public class MouseLLHook : Hook 8 | { 9 | [DllImport("GlobalCbtHook.dll", CallingConvention = CallingConvention.Cdecl)] 10 | private static extern void InitializeMouseLLHook(int threadID, IntPtr DestWindow); 11 | [DllImport("GlobalCbtHook.dll", CallingConvention = CallingConvention.Cdecl)] 12 | private static extern void UninitializeMouseLLHook(); 13 | 14 | // Values retreived with RegisterWindowMessage 15 | private int _MsgID_MouseLL; 16 | private int _MsgID_MouseLL_HookReplaced; 17 | 18 | public event HookReplacedEventHandler HookReplaced; 19 | public event BasicHookEventHandler MouseLLEvent; 20 | public event MouseEventHandler MouseDown; 21 | public event MouseEventHandler MouseMove; 22 | public event MouseEventHandler MouseUp; 23 | 24 | private const int WM_MOUSEMOVE = 0x0200; 25 | private const int WM_LBUTTONDOWN = 0x0201; 26 | private const int WM_LBUTTONUP = 0x0202; 27 | private const int WM_LBUTTONDBLCLK = 0x0203; 28 | private const int WM_RBUTTONDOWN = 0x0204; 29 | private const int WM_RBUTTONUP = 0x0205; 30 | private const int WM_RBUTTONDBLCLK = 0x0206; 31 | private const int WM_MBUTTONDOWN = 0x0207; 32 | private const int WM_MBUTTONUP = 0x0208; 33 | private const int WM_MBUTTONDBLCLK = 0x0209; 34 | private const int WM_MOUSEWHEEL = 0x020A; 35 | 36 | struct MSLLHOOKSTRUCT 37 | { 38 | public System.Drawing.Point pt; 39 | public int mouseData; 40 | public int flags; 41 | public int time; 42 | public IntPtr dwExtraInfo; 43 | }; 44 | 45 | public MouseLLHook(IntPtr Handle) 46 | : base(Handle) 47 | { 48 | } 49 | 50 | protected override void OnStart() 51 | { 52 | // Retreive the message IDs that we'll look for in WndProc 53 | _MsgID_MouseLL = RegisterWindowMessage("WILSON_HOOK_MOUSELL"); 54 | _MsgID_MouseLL_HookReplaced = RegisterWindowMessage("WILSON_HOOK_MOUSELL_REPLACED"); 55 | 56 | // Start the hook 57 | InitializeMouseLLHook(0, _Handle); 58 | } 59 | 60 | protected override void OnStop() 61 | { 62 | UninitializeMouseLLHook(); 63 | } 64 | 65 | public override void ProcessWindowMessage(ref System.Windows.Forms.Message m) 66 | { 67 | if (m.Msg == _MsgID_MouseLL) 68 | { 69 | if (MouseLLEvent != null) 70 | MouseLLEvent(m.WParam, m.LParam); 71 | 72 | MSLLHOOKSTRUCT M = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(m.LParam, typeof(MSLLHOOKSTRUCT)); 73 | 74 | if (m.WParam.ToInt32() == WM_MOUSEMOVE) 75 | { 76 | if (MouseMove != null) 77 | MouseMove(this, new MouseEventArgs(MouseButtons.None, 0, M.pt.X, M.pt.Y, 0)); 78 | } 79 | else if (m.WParam.ToInt32() == WM_LBUTTONDOWN) 80 | { 81 | if (MouseDown != null) 82 | MouseDown(this, new MouseEventArgs(MouseButtons.Left, 0, M.pt.X, M.pt.Y, 0)); 83 | } 84 | else if (m.WParam.ToInt32() == WM_RBUTTONDOWN) 85 | { 86 | if (MouseDown != null) 87 | MouseDown(this, new MouseEventArgs(MouseButtons.Right, 0, M.pt.X, M.pt.Y, 0)); 88 | } 89 | else if (m.WParam.ToInt32() == WM_LBUTTONUP) 90 | { 91 | if (MouseUp != null) 92 | MouseUp(this, new MouseEventArgs(MouseButtons.Left, 0, M.pt.X, M.pt.Y, 0)); 93 | } 94 | else if (m.WParam.ToInt32() == WM_RBUTTONUP) 95 | { 96 | if (MouseUp != null) 97 | MouseUp(this, new MouseEventArgs(MouseButtons.Right, 0, M.pt.X, M.pt.Y, 0)); 98 | } 99 | } 100 | else if (m.Msg == _MsgID_MouseLL_HookReplaced) 101 | { 102 | if (HookReplaced != null) 103 | HookReplaced(); 104 | } 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/RadminInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Text.RegularExpressions; 4 | using System.Windows.Forms; 5 | 6 | namespace RadminSavePassword.Hook 7 | { 8 | public delegate void CatchServerInfoEventHandler(object sender, ServerInfoEventArgs args); 9 | 10 | public class RadminInput : NativeWindow 11 | { 12 | protected readonly Regex RadminFlagRegex = new Regex(@"(?<=Radmin.*?[::]\s*)[^\s].*"); 13 | protected readonly Regex WindowsFlagRegex = new Regex(@"(?<=Windows.*?[::]\s*)[^\s].*"); 14 | 15 | public bool IsStarted { get; protected set; } 16 | 17 | protected CBTHook CBTHook { get; private set; } 18 | protected MouseLLHook MouseLLHook { get; private set; } 19 | protected KeyboardLLHook KeyboardLLHook { get; private set; } 20 | 21 | protected IntPtr _parentHandle; 22 | 23 | protected ControlHandle _activeControlHandle = null; 24 | 25 | public event CatchServerInfoEventHandler CatchServerInfo; 26 | 27 | public RadminInput(IntPtr parentHandle) 28 | { 29 | _parentHandle = parentHandle; 30 | 31 | CBTHook = new CBTHook(_parentHandle); 32 | MouseLLHook = new MouseLLHook(_parentHandle); 33 | KeyboardLLHook = new KeyboardLLHook(_parentHandle); 34 | 35 | CBTHook.Activate += CBTHook_Activate; 36 | MouseLLHook.MouseUp += MouseLLHook_MouseUp; 37 | KeyboardLLHook.KeyDown += KeyboardLLHook_KeyDown; 38 | CBTHook.DestroyWindow += CBTHook_DestroyWindow; 39 | } 40 | 41 | void KeyboardLLHook_KeyDown(object sender, KeyEventArgs e) 42 | { 43 | 44 | if (_activeControlHandle != null && (e.KeyCode == Keys.Enter))//|| e.KeyCode == Keys.Space 45 | { 46 | ServerInfo serverInfo = PickUpServerInfo(_activeControlHandle); 47 | if (CatchServerInfo != null && serverInfo != null) 48 | CatchServerInfo(this, new ServerInfoEventArgs(serverInfo)); 49 | } 50 | } 51 | 52 | void MouseLLHook_MouseUp(object sender, MouseEventArgs e) 53 | { 54 | if (_activeControlHandle != null && e.Button == MouseButtons.Left) 55 | { 56 | WindowsApi.Point point = new WindowsApi.Point { X = (uint)e.X, Y = (uint)e.Y }; 57 | IntPtr handle = WindowsApi.WindowFromPoint(point); 58 | 59 | if (_activeControlHandle.OkButtonHandle == handle) 60 | { 61 | ServerInfo serverInfo = PickUpServerInfo(_activeControlHandle); 62 | if (CatchServerInfo != null && serverInfo != null) 63 | CatchServerInfo(this, new ServerInfoEventArgs(serverInfo)); 64 | } 65 | } 66 | } 67 | 68 | void CBTHook_DestroyWindow(IntPtr handle) 69 | { 70 | if (IsLoginWindows(handle)) 71 | { 72 | _activeControlHandle = null; 73 | } 74 | } 75 | 76 | protected void CBTHook_Activate(IntPtr handle) 77 | { 78 | if (IsLoginWindows(handle)) 79 | { 80 | string title = GetHandleText(handle); 81 | LoginType loginType = GetLoginType(title); 82 | string name = RemoveStringPreFlag(title); 83 | OnPaddingProcess(handle, name, loginType); 84 | } 85 | } 86 | 87 | protected override void WndProc(ref Message m) 88 | { 89 | // Check to see if we've received any Windows messages telling us about our hooks 90 | if (KeyboardLLHook != null) 91 | KeyboardLLHook.ProcessWindowMessage(ref m); 92 | if (MouseLLHook != null) 93 | MouseLLHook.ProcessWindowMessage(ref m); 94 | if (CBTHook != null) 95 | CBTHook.ProcessWindowMessage(ref m); 96 | 97 | base.WndProc(ref m); 98 | } 99 | 100 | public void Start() 101 | { 102 | if (!IsStarted) 103 | { 104 | AssignHandle(_parentHandle); 105 | 106 | CBTHook.Start(); 107 | MouseLLHook.Start(); 108 | KeyboardLLHook.Start(); 109 | 110 | IntPtr handle = IntPtr.Zero; 111 | string name = string.Empty; 112 | LoginType loginType = LoginType.Radmin; 113 | WindowsApi.EnumChildWindows(IntPtr.Zero, (hwnd, lParam) => 114 | { 115 | if (IsLoginWindows(hwnd)) 116 | { 117 | handle = hwnd; 118 | string title = GetHandleText(handle); 119 | loginType = GetLoginType(title); 120 | name = RemoveStringPreFlag(title); 121 | return false; 122 | } 123 | return true; 124 | }, IntPtr.Zero); 125 | 126 | if (handle != IntPtr.Zero) 127 | OnPaddingProcess(handle, name, loginType); 128 | 129 | IsStarted = true; 130 | } 131 | } 132 | 133 | public void Stop() 134 | { 135 | if (IsStarted) 136 | { 137 | CBTHook.Stop(); 138 | MouseLLHook.Stop(); 139 | KeyboardLLHook.Stop(); 140 | ReleaseHandle(); 141 | IsStarted = false; 142 | } 143 | } 144 | 145 | /// 146 | /// 填充主窗体信息 147 | /// 148 | /// 主窗体句柄 149 | /// 当前服务器名称 150 | /// 当前登陆类型 151 | protected virtual void OnPaddingProcess(IntPtr handle, string serverName, LoginType loginType) 152 | { 153 | ControlHandle controlHandle = GetControlHandle(handle); 154 | _activeControlHandle = controlHandle; 155 | 156 | if (!Global.SystemConfig.ServerList.ContainsKey(serverName)) return; 157 | 158 | ServerInfo serverInfo = Global.SystemConfig.ServerList[serverName]; 159 | if (serverInfo.LoginType != loginType) return; 160 | 161 | WindowsApi.SendMessage(controlHandle.UsernameHandle, WindowsApi.WM_SETTEXT, 1024, serverInfo.UserName); 162 | WindowsApi.SendMessage(controlHandle.PasswordHandle, WindowsApi.WM_SETTEXT, 1024, serverInfo.Password); 163 | 164 | if (controlHandle.LoginType == LoginType.Windows) 165 | WindowsApi.SendMessage(controlHandle.DomainHandle, WindowsApi.WM_SETTEXT, 1024, serverInfo.Domain); 166 | 167 | if (Global.SystemConfig.IsAutoEnter) 168 | { 169 | WindowsApi.PostMessage(controlHandle.OkButtonHandle, WindowsApi.WM_KEYDOWN, 0X0D, 0); 170 | } 171 | } 172 | 173 | /// 174 | /// 提取界面服务器信息 175 | /// 176 | /// 窗体控件句柄数据 177 | /// 178 | protected virtual ServerInfo PickUpServerInfo(ControlHandle controlHandle) 179 | { 180 | int defaultCheckValue = (int)WindowsApi.SendMessage(controlHandle.DefaultCheckHandle, WindowsApi.BM_GETCHECK, 0, 0); 181 | if (defaultCheckValue != WindowsApi.BST_CHECKED) return null; 182 | 183 | ServerInfo serverInfo = new ServerInfo(); 184 | serverInfo.Name = controlHandle.Title; 185 | serverInfo.LoginType = controlHandle.LoginType; 186 | 187 | StringBuilder stringBuilder = new StringBuilder(1024); 188 | WindowsApi.SendMessage(controlHandle.UsernameHandle, WindowsApi.WM_GETTEXT, 1024, stringBuilder); 189 | serverInfo.UserName = stringBuilder.ToString(); 190 | 191 | 192 | long dwStyle = WindowsApi.GetWindowLong(controlHandle.PasswordHandle, WindowsApi.GWL_STYLE); //获取密码框原来样式 193 | WindowsApi.SetWindowWord(controlHandle.PasswordHandle, WindowsApi.GWL_STYLE, 0); //取消所有样式 194 | WindowsApi.SetWindowLong(controlHandle.PasswordHandle, WindowsApi.GWL_STYLE, 195 | dwStyle & ~WindowsApi.ES_PASSWORD); //去掉密码属性 196 | 197 | stringBuilder.Remove(0, stringBuilder.Length); 198 | WindowsApi.SendMessage(controlHandle.PasswordHandle, WindowsApi.WM_GETTEXT, 1024, stringBuilder); 199 | //没有了ES_PASSWORD属性WM_GETTEXT可以成功 200 | 201 | WindowsApi.SetWindowLong(controlHandle.PasswordHandle, WindowsApi.GWL_STYLE, dwStyle); //还原密码框原来样式 202 | 203 | serverInfo.Password = stringBuilder.ToString(); 204 | if (serverInfo.LoginType == LoginType.Windows) 205 | { 206 | stringBuilder.Remove(0, stringBuilder.Length); 207 | WindowsApi.SendMessage(controlHandle.DomainHandle, WindowsApi.WM_GETTEXT, 1024, stringBuilder); 208 | serverInfo.Domain = stringBuilder.ToString(); 209 | } 210 | 211 | if (string.IsNullOrEmpty(serverInfo.Password)) 212 | return null; 213 | 214 | return serverInfo; 215 | } 216 | 217 | ~RadminInput() 218 | { 219 | Stop(); 220 | } 221 | 222 | /// 223 | /// 获取主窗体中子控件句柄 224 | /// 225 | /// 主窗体句柄 226 | /// 227 | protected ControlHandle GetControlHandle(IntPtr handle) 228 | { 229 | ControlHandle controlHandle = new ControlHandle(); 230 | controlHandle.ParentHandle = handle; 231 | 232 | string title = GetHandleText(handle); 233 | 234 | controlHandle.LoginType = GetLoginType(title); 235 | controlHandle.Title = RemoveStringPreFlag(title); 236 | 237 | bool existHostName = false; 238 | int tabIndex = 0; 239 | WindowsApi.EnumChildWindows(handle, (hwnd, lParam) => 240 | { 241 | #region 旧逻辑(已注释) 242 | 243 | //WindowsApi.Rect rect = new WindowsApi.Rect(); 244 | //WindowsApi.GetWindowRect(hwnd, out rect); 245 | //WindowsApi.Point point = new WindowsApi.Point(); 246 | //point.X = rect.Left; 247 | //point.Y = rect.Top; 248 | //WindowsApi.ScreenToClient(handle, ref point); 249 | //if (controlHandle.LoginType == LoginType.Radmin) 250 | //{ 251 | // if (point.X == 83 && point.Y == 20) //用户名 252 | // controlHandle.UsernameHandle = hwnd; 253 | // else if (point.X == 83 && point.Y == 55) //密码框 254 | // controlHandle.PasswordHandle = hwnd; 255 | // else if (point.X == 18 && point.Y == 88) //缺省值CheckBox 256 | // controlHandle.DefaultCheckHandle = hwnd; 257 | 258 | // //3.4版Radmin方式登陆的确认按钮Y坐标为111,3.5的为112 259 | // else if (point.X == 83 && (point.Y == 111 || point.Y == 112)) //确定按钮 260 | // controlHandle.OkButtonHandle = hwnd; 261 | // else if (point.X == 180 && (point.Y == 111 || point.Y == 112)) //取消按钮 262 | // controlHandle.CancelButtonHandle = hwnd; 263 | //} 264 | //else if (controlHandle.LoginType == LoginType.Windows) 265 | //{ 266 | // if (point.X == 83 && point.Y == 20) //用户名 267 | // controlHandle.UsernameHandle = hwnd; 268 | // else if (point.X == 83 && point.Y == 55) //密码框 269 | // controlHandle.PasswordHandle = hwnd; 270 | // else if (point.X == 83 && point.Y == 89) //域名 271 | // controlHandle.DomainHandle = hwnd; 272 | 273 | // //界面存在“主机名称”标签 274 | // else if (point.X == 18 && point.Y == 91) 275 | // existHostName = true; 276 | 277 | // if (existHostName) 278 | // { 279 | // if (point.X == 18 && point.Y == 153) 280 | // controlHandle.DefaultCheckHandle = hwnd; 281 | // else if (point.X == 83 && point.Y == 176) //确定按钮 282 | // controlHandle.OkButtonHandle = hwnd; 283 | // else if (point.X == 180 && point.Y == 176) //取消按钮 284 | // controlHandle.CancelButtonHandle = hwnd; 285 | // } 286 | // else 287 | // { 288 | // if (point.X == 18 && point.Y == 122) 289 | // controlHandle.DefaultCheckHandle = hwnd; 290 | // else if (point.X == 83 && point.Y == 145) //确定按钮 291 | // controlHandle.OkButtonHandle = hwnd; 292 | // else if (point.X == 180 && point.Y == 145) //取消按钮 293 | // controlHandle.CancelButtonHandle = hwnd; 294 | // } 295 | //} 296 | //else 297 | // throw new NotImplementedException("unknow ProgramFlag"); 298 | 299 | #endregion 300 | 301 | if (controlHandle.LoginType == LoginType.Radmin) 302 | { 303 | if (tabIndex == 0) //用户名 304 | controlHandle.UsernameHandle = hwnd; 305 | else if (tabIndex == 2) //密码框 306 | controlHandle.PasswordHandle = hwnd; 307 | else if (tabIndex == 4) //缺省值CheckBox 308 | controlHandle.DefaultCheckHandle = hwnd; 309 | 310 | //3.4版Radmin方式登陆的确认按钮Y坐标为111,3.5的为112 311 | else if (tabIndex == 5) //确定按钮 312 | controlHandle.OkButtonHandle = hwnd; 313 | else if (tabIndex == 6) //取消按钮 314 | controlHandle.CancelButtonHandle = hwnd; 315 | } 316 | else if (controlHandle.LoginType == LoginType.Windows) 317 | { 318 | if (tabIndex == 0) //用户名 319 | controlHandle.UsernameHandle = hwnd; 320 | else if (tabIndex == 2) //密码框 321 | controlHandle.PasswordHandle = hwnd; 322 | else if (tabIndex == 4) //域名 323 | controlHandle.DomainHandle = hwnd; 324 | 325 | // TODO:暂时没找到如何有此连接的主机 326 | ////界面存在“主机名称”标签 327 | //else if (point.X == 18 && point.Y == 91) 328 | // existHostName = true; 329 | 330 | //if (existHostName) 331 | //{ 332 | // if (point.X == 18 && point.Y == 153) 333 | // controlHandle.DefaultCheckHandle = hwnd; 334 | // else if (point.X == 83 && point.Y == 176) //确定按钮 335 | // controlHandle.OkButtonHandle = hwnd; 336 | // else if (point.X == 180 && point.Y == 176) //取消按钮 337 | // controlHandle.CancelButtonHandle = hwnd; 338 | //} 339 | //else 340 | { 341 | if (tabIndex == 6) 342 | controlHandle.DefaultCheckHandle = hwnd; 343 | else if (tabIndex == 7) //确定按钮 344 | controlHandle.OkButtonHandle = hwnd; 345 | else if (tabIndex == 8) //取消按钮 346 | controlHandle.CancelButtonHandle = hwnd; 347 | } 348 | } 349 | else 350 | throw new NotImplementedException("unknow ProgramFlag"); 351 | 352 | tabIndex++; 353 | 354 | return true; 355 | }, IntPtr.Zero); 356 | 357 | return controlHandle; 358 | } 359 | 360 | /// 361 | /// 获取窗体句柄的Text信息 362 | /// 363 | /// 窗体句柄 364 | /// 365 | protected string GetHandleText(IntPtr handle) 366 | { 367 | StringBuilder sb = new StringBuilder(256); 368 | WindowsApi.GetWindowText(handle, sb, sb.Capacity); 369 | return sb.ToString(); 370 | } 371 | 372 | /// 373 | /// 根据窗体标题判断登陆类型 374 | /// 375 | /// 窗体标题 376 | /// 377 | protected LoginType GetLoginType(string title) 378 | { 379 | LoginType loginType = LoginType.Radmin; 380 | 381 | if (RadminFlagRegex.IsMatch(title)) 382 | loginType = LoginType.Radmin; 383 | else if (WindowsFlagRegex.IsMatch(title)) 384 | loginType = LoginType.Windows; 385 | 386 | return loginType; 387 | } 388 | 389 | /// 390 | /// 移除字符串开头的用于标识Radmin程序窗体的前缀字符 391 | /// 392 | /// 待处理的字符串 393 | /// 394 | protected string RemoveStringPreFlag(string str) 395 | { 396 | Match radminMatch = RadminFlagRegex.Match(str); 397 | if (radminMatch.Success) 398 | return radminMatch.Value; 399 | 400 | Match windowsMatch = WindowsFlagRegex.Match(str); 401 | if (windowsMatch.Success) 402 | return windowsMatch.Value; 403 | 404 | return str; 405 | } 406 | 407 | /// 408 | /// 校验当前句柄对应的窗体是否为登陆窗体 409 | /// 410 | /// 窗体句柄 411 | /// 412 | protected bool IsLoginWindows(IntPtr handle) 413 | { 414 | StringBuilder sb = new StringBuilder(256); 415 | WindowsApi.GetWindowText(handle, sb, sb.Capacity); 416 | string title = sb.ToString(); 417 | 418 | return IsLoginWindows(title); 419 | } 420 | 421 | /// 422 | /// 校验当前句柄对应的窗体是否为登陆窗体 423 | /// 424 | /// 窗体标题 425 | /// 426 | protected bool IsLoginWindows(string title) 427 | { 428 | return (RadminFlagRegex.IsMatch(title) || WindowsFlagRegex.IsMatch(title)); 429 | } 430 | 431 | /// 432 | /// 窗体控件句柄数据 433 | /// 434 | protected class ControlHandle 435 | { 436 | /// 437 | /// 登陆类型 438 | /// 439 | public LoginType LoginType { get; set; } 440 | /// 441 | /// 窗体标题 442 | /// 443 | public string Title { get; set; } 444 | /// 445 | /// 父窗体句柄 446 | /// 447 | public IntPtr ParentHandle { get; set; } 448 | /// 449 | /// 用户名TextBox句柄 450 | /// 451 | public IntPtr UsernameHandle { get; set; } 452 | /// 453 | /// 密码TextBox句柄 454 | /// 455 | public IntPtr PasswordHandle { get; set; } 456 | /// 457 | /// 域名TextBox句柄 458 | /// 459 | public IntPtr DomainHandle { get; set; } 460 | /// 461 | /// 缺省值CheckBox句柄 462 | /// 463 | public IntPtr DefaultCheckHandle { get; set; } 464 | /// 465 | /// 确认Button句柄 466 | /// 467 | public IntPtr OkButtonHandle { get; set; } 468 | /// 469 | /// 取消Button句柄 470 | /// 471 | public IntPtr CancelButtonHandle { get; set; } 472 | } 473 | } 474 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/ServerInfoEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RadminSavePassword.Hook 4 | { 5 | public class ServerInfoEventArgs : EventArgs 6 | { 7 | public ServerInfo ServerInfo { get; private set; } 8 | 9 | public ServerInfoEventArgs(ServerInfo serverInfo) 10 | { 11 | ServerInfo = serverInfo; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /RadminSavePassword/Hook/WindowsApi.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Text; 4 | 5 | namespace RadminSavePassword.Hook 6 | { 7 | public static class WindowsApi 8 | { 9 | public struct Rect 10 | { 11 | public uint Left; 12 | public uint Top; 13 | public uint Right; 14 | public uint Bottom; 15 | } 16 | 17 | public struct Point 18 | { 19 | public uint X; 20 | public uint Y; 21 | } 22 | 23 | public const int WM_KEYDOWN = 0X100; 24 | public const int WM_KEYUP = 0X101; 25 | public const int WM_SYSCHAR = 0X106; 26 | public const int WM_SYSKEYUP = 0X105; 27 | public const int WM_SYSKEYDOWN = 0X104; 28 | public const int WM_CHAR = 0X102; 29 | 30 | public const int BM_GETCHECK = 0x00F0; 31 | public const int WM_GETTEXT = 0x000D; 32 | public const int WM_SETTEXT = 0x000C; 33 | 34 | public const int BST_UNCHECKED = 0x0000; 35 | public const int BST_CHECKED = 0x0001; 36 | 37 | public const int WH_KEYBOARD_LL = 13; 38 | public const int WH_MOUSE_LL = 14; 39 | public const int WH_MOUSE = 7; 40 | 41 | public const int GWL_STYLE = -16; 42 | 43 | public const long ES_PASSWORD = 0x0020L; 44 | 45 | public const int SW_SHOWNOMAL = 1; 46 | 47 | [DllImport("user32.dll")] 48 | public static extern long SendMessage(IntPtr childHandle, int msg, int lParam, string wParam); 49 | 50 | [DllImport("user32.dll")] 51 | public static extern long SendMessage(IntPtr childHandle, int msg, int lParam, int wParam); 52 | 53 | [DllImport("user32.dll")] 54 | public static extern long SendMessage(IntPtr childHandle, int msg, int lParam, StringBuilder wParam); 55 | 56 | [DllImport("user32.dll")] 57 | public static extern bool PostMessage(IntPtr hwnd, int msg, int wParam, uint lParam); 58 | 59 | [DllImport("user32.dll")] 60 | public static extern IntPtr EnumChildWindows(IntPtr hWndParent, CallBack lpfn, IntPtr lParam); 61 | 62 | [DllImport("user32")] 63 | public static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect); 64 | 65 | [DllImport("user32.dll")] 66 | public static extern bool ScreenToClient(IntPtr hWnd, ref Point lpPoint); 67 | 68 | [DllImport("user32.dll")] 69 | public static extern bool GetWindowText(IntPtr hWnd, StringBuilder lpString, int cch); 70 | 71 | [DllImport("user32.dll")] 72 | public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 73 | 74 | [DllImport("user32.dll")] 75 | public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 76 | 77 | [DllImport("user32.dll")] 78 | public static extern IntPtr SetWindowsHookEx(int idHook, HookCallBack lpfn, IntPtr hMod, int dwThreadId); 79 | 80 | [DllImport("user32.dll")] 81 | public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, int wParam, int lParam); 82 | 83 | [DllImport("kernel32.dll")] 84 | public static extern IntPtr GetModuleHandle(string name); 85 | 86 | [DllImport("user32.dll")] 87 | public static extern IntPtr WindowFromPoint(Point point); 88 | 89 | [DllImport("user32.dll")] 90 | public static extern int UnhookWindowsHookEx(IntPtr hhk); 91 | 92 | [DllImport("user32.dll")] 93 | public static extern IntPtr GetParent(IntPtr hWnd); 94 | 95 | [DllImport("user32.dll")] 96 | public static extern long GetWindowLong(IntPtr hWnd, int nlndex); 97 | 98 | [DllImport("user32.dll")] 99 | public static extern long SetWindowLong(IntPtr hWnd, int nlndex, long dwNewLong); 100 | 101 | [DllImport("user32.dll")] 102 | public static extern long SetWindowWord(IntPtr hWnd, int nlndex, long wNewWord); 103 | 104 | [DllImport("user32.dll")] 105 | public static extern IntPtr SetForegroundWindow(IntPtr hwnd); 106 | 107 | [DllImport("User32.dll")] 108 | public static extern bool ShowWindowAsync(IntPtr hWnd, int lParam); 109 | 110 | [DllImport("user32.dll")] 111 | public static extern IntPtr GetForegroundWindow(); 112 | 113 | public delegate bool CallBack(IntPtr hwnd, int lParam); 114 | 115 | public delegate int HookCallBack(int code, int wparam, int lparam); 116 | } 117 | } -------------------------------------------------------------------------------- /RadminSavePassword/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace RadminSavePassword 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 33 | this.imgListSmall = new System.Windows.Forms.ImageList(this.components); 34 | this.listView = new System.Windows.Forms.ListView(); 35 | this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 36 | this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 37 | this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 38 | this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 39 | this.cbAutoEnter = new System.Windows.Forms.CheckBox(); 40 | this.label1 = new System.Windows.Forms.Label(); 41 | this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); 42 | this.notifyMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 43 | this.启动BToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 44 | this.停止EToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 45 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); 46 | this.退出XToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 47 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 48 | this.btnStart = new System.Windows.Forms.Button(); 49 | this.cbAutoStart = new System.Windows.Forms.CheckBox(); 50 | this.btnOpen = new System.Windows.Forms.Button(); 51 | this.btnDelete = new System.Windows.Forms.Button(); 52 | this.btnEdit = new System.Windows.Forms.Button(); 53 | this.btnAdd = new System.Windows.Forms.Button(); 54 | this.btnStop = new System.Windows.Forms.Button(); 55 | this.lbVersion = new System.Windows.Forms.Label(); 56 | this.notifyMenu.SuspendLayout(); 57 | this.SuspendLayout(); 58 | // 59 | // imgListSmall 60 | // 61 | this.imgListSmall.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgListSmall.ImageStream"))); 62 | this.imgListSmall.TransparentColor = System.Drawing.Color.Transparent; 63 | this.imgListSmall.Images.SetKeyName(0, "sign-add.png"); 64 | this.imgListSmall.Images.SetKeyName(1, "sign-delete.png"); 65 | this.imgListSmall.Images.SetKeyName(2, "sign-info.png"); 66 | this.imgListSmall.Images.SetKeyName(3, "tag.png"); 67 | this.imgListSmall.Images.SetKeyName(4, "tag-alt.png"); 68 | this.imgListSmall.Images.SetKeyName(5, "device-laptop-R.png"); 69 | this.imgListSmall.Images.SetKeyName(6, "device-laptop-W.png"); 70 | // 71 | // listView 72 | // 73 | this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 74 | | System.Windows.Forms.AnchorStyles.Left) 75 | | System.Windows.Forms.AnchorStyles.Right))); 76 | this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 77 | this.columnHeader1, 78 | this.columnHeader2, 79 | this.columnHeader3, 80 | this.columnHeader4}); 81 | this.listView.FullRowSelect = true; 82 | this.listView.GridLines = true; 83 | this.listView.HideSelection = false; 84 | this.listView.Location = new System.Drawing.Point(12, 84); 85 | this.listView.MultiSelect = false; 86 | this.listView.Name = "listView"; 87 | this.listView.Size = new System.Drawing.Size(360, 342); 88 | this.listView.SmallImageList = this.imgListSmall; 89 | this.listView.TabIndex = 7; 90 | this.listView.UseCompatibleStateImageBehavior = false; 91 | this.listView.View = System.Windows.Forms.View.Details; 92 | // 93 | // columnHeader1 94 | // 95 | this.columnHeader1.Text = "名称"; 96 | this.columnHeader1.Width = 132; 97 | // 98 | // columnHeader2 99 | // 100 | this.columnHeader2.Text = "用户名"; 101 | this.columnHeader2.Width = 90; 102 | // 103 | // columnHeader3 104 | // 105 | this.columnHeader3.Text = "密码"; 106 | this.columnHeader3.Width = 43; 107 | // 108 | // columnHeader4 109 | // 110 | this.columnHeader4.Text = "域名"; 111 | this.columnHeader4.Width = 69; 112 | // 113 | // cbAutoEnter 114 | // 115 | this.cbAutoEnter.AutoSize = true; 116 | this.cbAutoEnter.Location = new System.Drawing.Point(174, 28); 117 | this.cbAutoEnter.Name = "cbAutoEnter"; 118 | this.cbAutoEnter.Size = new System.Drawing.Size(72, 16); 119 | this.cbAutoEnter.TabIndex = 2; 120 | this.cbAutoEnter.Text = "自动确定"; 121 | this.toolTip1.SetToolTip(this.cbAutoEnter, "Radmin界面中自动填充登陆信息后回车"); 122 | this.cbAutoEnter.UseVisualStyleBackColor = true; 123 | // 124 | // label1 125 | // 126 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 127 | | System.Windows.Forms.AnchorStyles.Right))); 128 | this.label1.AutoSize = true; 129 | this.label1.Location = new System.Drawing.Point(10, 429); 130 | this.label1.Name = "label1"; 131 | this.label1.Size = new System.Drawing.Size(197, 12); 132 | this.label1.TabIndex = 8; 133 | this.label1.Text = "注意:Radmin中的名称不能有重复项"; 134 | // 135 | // notifyIcon 136 | // 137 | this.notifyIcon.ContextMenuStrip = this.notifyMenu; 138 | this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); 139 | this.notifyIcon.Text = "Radmin保存密码"; 140 | this.notifyIcon.Visible = true; 141 | // 142 | // notifyMenu 143 | // 144 | this.notifyMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 145 | this.启动BToolStripMenuItem, 146 | this.停止EToolStripMenuItem, 147 | this.toolStripSeparator1, 148 | this.退出XToolStripMenuItem}); 149 | this.notifyMenu.Name = "notifyMenu"; 150 | this.notifyMenu.Size = new System.Drawing.Size(117, 76); 151 | // 152 | // 启动BToolStripMenuItem 153 | // 154 | this.启动BToolStripMenuItem.Image = global::RadminSavePassword.Properties.Resources.tag; 155 | this.启动BToolStripMenuItem.Name = "启动BToolStripMenuItem"; 156 | this.启动BToolStripMenuItem.Size = new System.Drawing.Size(116, 22); 157 | this.启动BToolStripMenuItem.Text = "启动(&B)"; 158 | // 159 | // 停止EToolStripMenuItem 160 | // 161 | this.停止EToolStripMenuItem.Image = global::RadminSavePassword.Properties.Resources.tag_alt; 162 | this.停止EToolStripMenuItem.Name = "停止EToolStripMenuItem"; 163 | this.停止EToolStripMenuItem.Size = new System.Drawing.Size(116, 22); 164 | this.停止EToolStripMenuItem.Text = "停止(&E)"; 165 | // 166 | // toolStripSeparator1 167 | // 168 | this.toolStripSeparator1.Name = "toolStripSeparator1"; 169 | this.toolStripSeparator1.Size = new System.Drawing.Size(113, 6); 170 | // 171 | // 退出XToolStripMenuItem 172 | // 173 | this.退出XToolStripMenuItem.Image = global::RadminSavePassword.Properties.Resources.sign_ban; 174 | this.退出XToolStripMenuItem.Name = "退出XToolStripMenuItem"; 175 | this.退出XToolStripMenuItem.Size = new System.Drawing.Size(116, 22); 176 | this.退出XToolStripMenuItem.Text = "退出(&X)"; 177 | // 178 | // toolTip1 179 | // 180 | this.toolTip1.AutoPopDelay = 5000; 181 | this.toolTip1.InitialDelay = 200; 182 | this.toolTip1.ReshowDelay = 100; 183 | // 184 | // btnStart 185 | // 186 | this.btnStart.ImageKey = "tag.png"; 187 | this.btnStart.ImageList = this.imgListSmall; 188 | this.btnStart.Location = new System.Drawing.Point(12, 12); 189 | this.btnStart.Name = "btnStart"; 190 | this.btnStart.Size = new System.Drawing.Size(75, 30); 191 | this.btnStart.TabIndex = 0; 192 | this.btnStart.Text = "启动"; 193 | this.btnStart.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; 194 | this.toolTip1.SetToolTip(this.btnStart, "启动后,当Radmin中勾选了\"另存为缺省值\"时,程序会自动记录用户名和密码"); 195 | this.btnStart.UseVisualStyleBackColor = true; 196 | // 197 | // cbAutoStart 198 | // 199 | this.cbAutoStart.AutoSize = true; 200 | this.cbAutoStart.Location = new System.Drawing.Point(174, 11); 201 | this.cbAutoStart.Name = "cbAutoStart"; 202 | this.cbAutoStart.Size = new System.Drawing.Size(72, 16); 203 | this.cbAutoStart.TabIndex = 9; 204 | this.cbAutoStart.Text = "开机启动"; 205 | this.toolTip1.SetToolTip(this.cbAutoStart, "Radmin界面中自动填充登陆信息后回车"); 206 | this.cbAutoStart.UseVisualStyleBackColor = true; 207 | // 208 | // btnOpen 209 | // 210 | this.btnOpen.Image = global::RadminSavePassword.Properties.Resources.btnOpen_Image; 211 | this.btnOpen.Location = new System.Drawing.Point(286, 12); 212 | this.btnOpen.Name = "btnOpen"; 213 | this.btnOpen.Size = new System.Drawing.Size(86, 66); 214 | this.btnOpen.TabIndex = 6; 215 | this.btnOpen.Text = "打开Radmin"; 216 | this.btnOpen.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; 217 | this.btnOpen.UseVisualStyleBackColor = true; 218 | // 219 | // btnDelete 220 | // 221 | this.btnDelete.ImageKey = "sign-delete.png"; 222 | this.btnDelete.ImageList = this.imgListSmall; 223 | this.btnDelete.Location = new System.Drawing.Point(174, 48); 224 | this.btnDelete.Name = "btnDelete"; 225 | this.btnDelete.Size = new System.Drawing.Size(75, 30); 226 | this.btnDelete.TabIndex = 5; 227 | this.btnDelete.Text = "删除"; 228 | this.btnDelete.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; 229 | this.btnDelete.UseVisualStyleBackColor = true; 230 | // 231 | // btnEdit 232 | // 233 | this.btnEdit.ImageKey = "sign-info.png"; 234 | this.btnEdit.ImageList = this.imgListSmall; 235 | this.btnEdit.Location = new System.Drawing.Point(93, 48); 236 | this.btnEdit.Name = "btnEdit"; 237 | this.btnEdit.Size = new System.Drawing.Size(75, 30); 238 | this.btnEdit.TabIndex = 4; 239 | this.btnEdit.Text = "编辑"; 240 | this.btnEdit.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; 241 | this.btnEdit.UseVisualStyleBackColor = true; 242 | // 243 | // btnAdd 244 | // 245 | this.btnAdd.ImageKey = "sign-add.png"; 246 | this.btnAdd.ImageList = this.imgListSmall; 247 | this.btnAdd.Location = new System.Drawing.Point(12, 48); 248 | this.btnAdd.Name = "btnAdd"; 249 | this.btnAdd.Size = new System.Drawing.Size(75, 30); 250 | this.btnAdd.TabIndex = 3; 251 | this.btnAdd.Text = "添加"; 252 | this.btnAdd.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; 253 | this.btnAdd.UseVisualStyleBackColor = true; 254 | // 255 | // btnStop 256 | // 257 | this.btnStop.ImageKey = "tag-alt.png"; 258 | this.btnStop.ImageList = this.imgListSmall; 259 | this.btnStop.Location = new System.Drawing.Point(93, 12); 260 | this.btnStop.Name = "btnStop"; 261 | this.btnStop.Size = new System.Drawing.Size(75, 30); 262 | this.btnStop.TabIndex = 1; 263 | this.btnStop.Text = "停止"; 264 | this.btnStop.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; 265 | this.btnStop.UseVisualStyleBackColor = true; 266 | // 267 | // lbVersion 268 | // 269 | this.lbVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 270 | | System.Windows.Forms.AnchorStyles.Right))); 271 | this.lbVersion.Location = new System.Drawing.Point(12, 441); 272 | this.lbVersion.Name = "lbVersion"; 273 | this.lbVersion.Size = new System.Drawing.Size(360, 12); 274 | this.lbVersion.TabIndex = 10; 275 | this.lbVersion.Text = "V1.0.0.0"; 276 | this.lbVersion.TextAlign = System.Drawing.ContentAlignment.TopRight; 277 | // 278 | // MainForm 279 | // 280 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 281 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 282 | this.ClientSize = new System.Drawing.Size(384, 462); 283 | this.Controls.Add(this.lbVersion); 284 | this.Controls.Add(this.cbAutoStart); 285 | this.Controls.Add(this.label1); 286 | this.Controls.Add(this.btnOpen); 287 | this.Controls.Add(this.cbAutoEnter); 288 | this.Controls.Add(this.btnDelete); 289 | this.Controls.Add(this.btnEdit); 290 | this.Controls.Add(this.btnAdd); 291 | this.Controls.Add(this.listView); 292 | this.Controls.Add(this.btnStop); 293 | this.Controls.Add(this.btnStart); 294 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 295 | this.MinimumSize = new System.Drawing.Size(400, 500); 296 | this.Name = "MainForm"; 297 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 298 | this.Text = "Radmin保存密码"; 299 | this.notifyMenu.ResumeLayout(false); 300 | this.ResumeLayout(false); 301 | this.PerformLayout(); 302 | 303 | } 304 | 305 | #endregion 306 | 307 | private System.Windows.Forms.Button btnStart; 308 | private System.Windows.Forms.Button btnStop; 309 | private System.Windows.Forms.ListView listView; 310 | private System.Windows.Forms.ColumnHeader columnHeader1; 311 | private System.Windows.Forms.ColumnHeader columnHeader2; 312 | private System.Windows.Forms.ColumnHeader columnHeader3; 313 | private System.Windows.Forms.ImageList imgListSmall; 314 | private System.Windows.Forms.Button btnAdd; 315 | private System.Windows.Forms.Button btnEdit; 316 | private System.Windows.Forms.Button btnDelete; 317 | private System.Windows.Forms.CheckBox cbAutoEnter; 318 | private System.Windows.Forms.Button btnOpen; 319 | private System.Windows.Forms.Label label1; 320 | private System.Windows.Forms.NotifyIcon notifyIcon; 321 | private System.Windows.Forms.ContextMenuStrip notifyMenu; 322 | private System.Windows.Forms.ToolStripMenuItem 退出XToolStripMenuItem; 323 | private System.Windows.Forms.ToolStripMenuItem 启动BToolStripMenuItem; 324 | private System.Windows.Forms.ToolStripMenuItem 停止EToolStripMenuItem; 325 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; 326 | private System.Windows.Forms.ToolTip toolTip1; 327 | private System.Windows.Forms.ColumnHeader columnHeader4; 328 | private System.Windows.Forms.CheckBox cbAutoStart; 329 | private System.Windows.Forms.Label lbVersion; 330 | } 331 | } 332 | 333 | -------------------------------------------------------------------------------- /RadminSavePassword/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Threading; 5 | using System.Windows.Forms; 6 | using Microsoft.Win32; 7 | using RadminSavePassword.Hook; 8 | 9 | namespace RadminSavePassword 10 | { 11 | public partial class MainForm : Form 12 | { 13 | private readonly RadminInput _radminInput; 14 | protected readonly string _rootPath; 15 | protected const string ConfigName = "config.dat"; 16 | private FormWindowState _lastWindowState; 17 | private bool _isAllowExit = false; 18 | 19 | public MainForm(bool isMinMode) 20 | { 21 | InitializeComponent(); 22 | _radminInput = new RadminInput(this.Handle); 23 | _rootPath = Application.StartupPath; 24 | 25 | if (isMinMode) 26 | WindowState = FormWindowState.Minimized; 27 | } 28 | 29 | protected override void OnLoad(EventArgs e) 30 | { 31 | base.OnLoad(e); 32 | 33 | Text = Global.ProgramText; 34 | lbVersion.Text = $@"V{Application.ProductVersion}"; 35 | 36 | LoadConfig(); 37 | 38 | btnStop.Enabled = false; 39 | 停止EToolStripMenuItem.Enabled = false; 40 | 41 | btnStart.Click += btnStart_Click; 42 | btnStop.Click += btnStop_Click; 43 | 44 | btnAdd.Click += btnAdd_Click; 45 | btnEdit.Click += btnEdit_Click; 46 | btnDelete.Click += btnDelete_Click; 47 | 48 | btnOpen.Click += btnOpen_Click; 49 | 50 | cbAutoEnter.CheckedChanged += cbAutoEnter_CheckedChanged; 51 | 52 | try 53 | { 54 | cbAutoStart.Checked = SystemConfig.CheckIsAutoStart(); 55 | } 56 | catch (Exception ex) 57 | { 58 | MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 59 | } 60 | cbAutoStart.CheckedChanged += CbAutoStart_CheckedChanged; 61 | 62 | listView.ItemActivate += listView_ItemActivate; 63 | 64 | notifyIcon.MouseClick += notifyIcon_MouseClick; 65 | 66 | 启动BToolStripMenuItem.Click += (sender, ex) => btnStart.PerformClick(); 67 | 停止EToolStripMenuItem.Click += (sender, ex) => btnStop.PerformClick(); 68 | 退出XToolStripMenuItem.Click += (sender, ex) => 69 | { 70 | _isAllowExit = true; 71 | Application.Exit(); 72 | }; 73 | 74 | _radminInput.CatchServerInfo += _radminInput_CatchServerInfo; 75 | 76 | btnStart.PerformClick(); 77 | } 78 | 79 | private void CbAutoStart_CheckedChanged(object sender, EventArgs e) 80 | { 81 | try 82 | { 83 | var cb = (CheckBox)sender; 84 | SystemConfig.SetAutoStart(cb.Checked); 85 | } 86 | catch (Exception ex) 87 | { 88 | MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 89 | } 90 | } 91 | 92 | protected override void OnFormClosing(FormClosingEventArgs e) 93 | { 94 | if (!_isAllowExit) 95 | { 96 | e.Cancel = true; 97 | WindowState = FormWindowState.Minimized; 98 | return; 99 | } 100 | 101 | base.OnFormClosing(e); 102 | } 103 | 104 | void _radminInput_CatchServerInfo(object sender, ServerInfoEventArgs args) 105 | { 106 | ListViewItem existItem = null; 107 | foreach (ListViewItem item in listView.Items) 108 | { 109 | ServerInfo si = (ServerInfo)item.Tag; 110 | if (si.Name == args.ServerInfo.Name) 111 | { 112 | existItem = item; 113 | break; 114 | } 115 | } 116 | if (existItem != null) 117 | { 118 | UpdateListViewItem(args.ServerInfo, existItem); 119 | } 120 | else 121 | { 122 | ListViewItem item = CreateListViewItem(args.ServerInfo); 123 | listView.Items.Add(item); 124 | } 125 | 126 | Global.SystemConfig.ServerList[args.ServerInfo.Name] = args.ServerInfo; 127 | 128 | SaveConfig(); 129 | } 130 | 131 | void notifyIcon_MouseClick(object sender, MouseEventArgs e) 132 | { 133 | if (e.Button != MouseButtons.Left) return; 134 | 135 | this.Visible = true; 136 | Thread.Sleep(20);//睡眠20毫秒,让显示动画平滑 137 | WindowState = _lastWindowState; 138 | this.Activate(); 139 | } 140 | 141 | void listView_ItemActivate(object sender, EventArgs e) 142 | { 143 | btnEdit.PerformClick(); 144 | } 145 | 146 | void cbAutoEnter_CheckedChanged(object sender, EventArgs e) 147 | { 148 | Global.SystemConfig.IsAutoEnter = cbAutoEnter.Checked; 149 | SaveConfig(); 150 | } 151 | 152 | void btnOpen_Click(object sender, EventArgs e) 153 | { 154 | if (string.IsNullOrEmpty(Global.SystemConfig.RadminOpenPath)) 155 | { 156 | RegistryKey regLM = Registry.LocalMachine; 157 | RegistryKey regUninstall = regLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"); 158 | if (regUninstall == null) return; 159 | 160 | string[] reguninstallSubKeyNames = regUninstall.GetSubKeyNames(); 161 | foreach (var name in reguninstallSubKeyNames) 162 | { 163 | RegistryKey key = regUninstall.OpenSubKey(name); 164 | if (key == null) continue; 165 | 166 | string displayName = (string)key.GetValue("DisplayName"); 167 | if (string.IsNullOrEmpty(displayName)) continue; 168 | 169 | if (displayName.StartsWith("Radmin Viewer")) 170 | { 171 | string installLocation = (string)key.GetValue("InstallLocation"); 172 | if (string.IsNullOrEmpty(installLocation)) continue; 173 | 174 | Global.SystemConfig.RadminOpenPath = Path.Combine(installLocation, "Radmin.exe"); 175 | SaveConfig(); 176 | break; 177 | } 178 | } 179 | } 180 | 181 | if (string.IsNullOrEmpty(Global.SystemConfig.RadminOpenPath) || !File.Exists(Global.SystemConfig.RadminOpenPath)) 182 | { 183 | MessageBox.Show("找不到Radmin的安装目录,请手工指定", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 184 | OpenFileDialog opDialog = new OpenFileDialog(); 185 | opDialog.CheckFileExists = true; 186 | opDialog.Filter = "程序文件(*.exe)|*.exe|所有文件(*.*)|*.*"; 187 | opDialog.FileName = "Radmin.exe"; 188 | if (opDialog.ShowDialog() == DialogResult.OK) 189 | { 190 | Global.SystemConfig.RadminOpenPath = opDialog.FileName; 191 | SaveConfig(); 192 | } 193 | else 194 | return; 195 | } 196 | ProcessStartInfo startInfo = new ProcessStartInfo(Global.SystemConfig.RadminOpenPath); 197 | startInfo.WorkingDirectory = Path.GetDirectoryName(Global.SystemConfig.RadminOpenPath); 198 | Process.Start(startInfo); 199 | } 200 | 201 | void btnStop_Click(object sender, EventArgs e) 202 | { 203 | _radminInput.Stop(); 204 | 205 | btnStart.Enabled = true; 206 | btnStop.Enabled = false; 207 | 启动BToolStripMenuItem.Enabled = true; 208 | 停止EToolStripMenuItem.Enabled = false; 209 | } 210 | 211 | void btnStart_Click(object sender, EventArgs e) 212 | { 213 | _radminInput.Start(); 214 | 215 | btnStart.Enabled = false; 216 | btnStop.Enabled = true; 217 | 启动BToolStripMenuItem.Enabled = false; 218 | 停止EToolStripMenuItem.Enabled = true; 219 | } 220 | 221 | void btnDelete_Click(object sender, EventArgs e) 222 | { 223 | if (listView.FocusedItem == null) return; 224 | 225 | if (MessageBox.Show("确认删除选中的记录?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != 226 | DialogResult.OK) 227 | return; 228 | 229 | ListViewItem focusedItem = listView.FocusedItem; 230 | ServerInfo serverInfo = (ServerInfo)focusedItem.Tag; 231 | listView.Items.Remove(focusedItem); 232 | 233 | Global.SystemConfig.ServerList.Remove(serverInfo.Name); 234 | 235 | SaveConfig(); 236 | } 237 | 238 | void btnEdit_Click(object sender, EventArgs e) 239 | { 240 | if (listView.FocusedItem == null) return; 241 | 242 | ListViewItem focusedItem = listView.FocusedItem; 243 | ServerInfo serverInfo = (ServerInfo)focusedItem.Tag; 244 | 245 | ServerInfoForm form = new ServerInfoForm(serverInfo); 246 | if (form.ShowDialog() != DialogResult.OK) return; 247 | 248 | UpdateListViewItem(form.ServerInfo, focusedItem); 249 | 250 | Global.SystemConfig.ServerList[form.ServerInfo.Name] = form.ServerInfo; 251 | 252 | SaveConfig(); 253 | } 254 | 255 | void btnAdd_Click(object sender, EventArgs e) 256 | { 257 | ServerInfoForm form = new ServerInfoForm(); 258 | if (form.ShowDialog() != DialogResult.OK) return; 259 | 260 | ListViewItem item = CreateListViewItem(form.ServerInfo); 261 | listView.Items.Add(item); 262 | 263 | Global.SystemConfig.ServerList[form.ServerInfo.Name] = form.ServerInfo; 264 | 265 | SaveConfig(); 266 | } 267 | 268 | private ListViewItem CreateListViewItem(ServerInfo serverInfo) 269 | { 270 | ListViewItem item = new ListViewItem(); 271 | for (int i = 0; i < listView.Columns.Count - 1; i++) 272 | item.SubItems.Add(string.Empty); 273 | 274 | UpdateListViewItem(serverInfo, item); 275 | return item; 276 | } 277 | 278 | private void UpdateListViewItem(ServerInfo serverInfo, ListViewItem item) 279 | { 280 | item.ImageKey = serverInfo.LoginType == LoginType.Radmin ? "device-laptop-R.png" : "device-laptop-W.png"; 281 | item.Text = serverInfo.Name; 282 | item.SubItems[1].Text = serverInfo.UserName; 283 | item.SubItems[2].Text = serverInfo.Password.Length == 0 ? "(无)" : "*****"; 284 | item.SubItems[3].Text = serverInfo.Domain; 285 | item.Tag = serverInfo; 286 | } 287 | 288 | protected void LoadConfig() 289 | { 290 | if (File.Exists(Path.Combine(_rootPath, ConfigName))) 291 | Global.SystemConfig = SystemConfig.Load(Path.Combine(_rootPath, ConfigName)); 292 | 293 | listView.Items.Clear(); 294 | foreach (var pair in Global.SystemConfig.ServerList) 295 | { 296 | listView.Items.Add(CreateListViewItem(pair.Value)); 297 | } 298 | 299 | cbAutoEnter.Checked = Global.SystemConfig.IsAutoEnter; 300 | } 301 | 302 | protected void SaveConfig() 303 | { 304 | SystemConfig.Save(Global.SystemConfig, Path.Combine(_rootPath, ConfigName)); 305 | } 306 | 307 | protected override void OnSizeChanged(EventArgs e) 308 | { 309 | base.OnSizeChanged(e); 310 | 311 | if (WindowState == FormWindowState.Maximized || WindowState == FormWindowState.Normal) 312 | { 313 | _lastWindowState = WindowState; 314 | } 315 | 316 | if (WindowState == FormWindowState.Minimized) 317 | { 318 | this.Visible = false; 319 | } 320 | } 321 | 322 | ~MainForm() 323 | { 324 | _radminInput.Stop(); 325 | } 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /RadminSavePassword/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Windows.Forms; 4 | using RadminSavePassword.Hook; 5 | 6 | namespace RadminSavePassword 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// 应用程序的主入口点。 12 | /// 13 | [STAThread] 14 | static void Main(string[] args) 15 | { 16 | bool isMinMode = args != null && args.Length > 0 && args[0] == "--min-mode"; 17 | 18 | bool canCreateNew; 19 | Mutex mutexLock = new Mutex(true, Application.ProductName, out canCreateNew); 20 | if (canCreateNew) 21 | { 22 | Application.ThreadException += Application_ThreadException; 23 | Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 24 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 25 | Application.EnableVisualStyles(); 26 | Application.SetCompatibleTextRenderingDefault(false); 27 | Application.Run(new MainForm(isMinMode)); 28 | 29 | mutexLock.ReleaseMutex();//退出锁定.然后再退出程序. 30 | } 31 | else 32 | { 33 | IntPtr windowHandle = RuningWindow();//获取本程序的运行实例. 34 | HandleRunningWindow(windowHandle);//激活该程序,并显示在最前端. 35 | } 36 | } 37 | 38 | static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 39 | { 40 | MessageBox.Show(string.Format("未处理的异常:{0}", e.Exception.Message), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); 41 | } 42 | 43 | static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 44 | { 45 | Exception ex = e.ExceptionObject as Exception; 46 | MessageBox.Show(string.Format("未处理的异常:{0}", ex.Message), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); 47 | } 48 | 49 | /// 50 | /// 将指定的窗口 显示到最前端. 51 | /// 52 | /// 窗口句柄 53 | private static void HandleRunningWindow(IntPtr handle) 54 | { 55 | WindowsApi.ShowWindowAsync(handle, WindowsApi.SW_SHOWNOMAL);//显示 56 | WindowsApi.SetForegroundWindow(handle);//当到最前端 57 | } 58 | 59 | /// 60 | /// 获取运行实例. 61 | /// 62 | /// 63 | private static IntPtr RuningWindow() 64 | { 65 | return WindowsApi.FindWindow(null, Global.ProgramText); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /RadminSavePassword/ProgramIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/RadminSavePassword/ProgramIcon.ico -------------------------------------------------------------------------------- /RadminSavePassword/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("RadminSavePassword")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("RadminSavePassword")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("0700c1a2-d157-4674-8726-a79953a6f3eb")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /RadminSavePassword/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace RadminSavePassword.Properties { 12 | using System; 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", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RadminSavePassword.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 使用此强类型资源类,为所有资源查找 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap btnOpen_Image { 67 | get { 68 | object obj = ResourceManager.GetObject("btnOpen_Image", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 75 | /// 76 | internal static System.Drawing.Bitmap sign_ban { 77 | get { 78 | object obj = ResourceManager.GetObject("sign_ban", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 85 | /// 86 | internal static System.Drawing.Bitmap tag { 87 | get { 88 | object obj = ResourceManager.GetObject("tag", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 95 | /// 96 | internal static System.Drawing.Bitmap tag_alt { 97 | get { 98 | object obj = ResourceManager.GetObject("tag_alt", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /RadminSavePassword/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 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\sign-ban.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\tag.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\tag-alt.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\btnOpen_Image.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | -------------------------------------------------------------------------------- /RadminSavePassword/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace RadminSavePassword.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RadminSavePassword/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RadminSavePassword/RadminSavePassword.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E3EE68E8-55FA-471C-A8A1-CCE2E89D54B3} 8 | WinExe 9 | Properties 10 | RadminSavePassword 11 | RadminSavePassword 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | x86 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | x86 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | ProgramIcon.ico 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Form 57 | 58 | 59 | ServerInfoForm.cs 60 | 61 | 62 | Form 63 | 64 | 65 | MainForm.cs 66 | 67 | 68 | 69 | 70 | 71 | 72 | MainForm.cs 73 | 74 | 75 | ServerInfoForm.cs 76 | 77 | 78 | ResXFileCodeGenerator 79 | Resources.Designer.cs 80 | Designer 81 | 82 | 83 | True 84 | Resources.resx 85 | True 86 | 87 | 88 | Designer 89 | 90 | 91 | SettingsSingleFileGenerator 92 | Settings.Designer.cs 93 | 94 | 95 | True 96 | Settings.settings 97 | True 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Designer 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 3.3.1 117 | 118 | 119 | 120 | 127 | -------------------------------------------------------------------------------- /RadminSavePassword/Resources/btnOpen_Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/RadminSavePassword/Resources/btnOpen_Image.png -------------------------------------------------------------------------------- /RadminSavePassword/Resources/sign-ban.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/RadminSavePassword/Resources/sign-ban.png -------------------------------------------------------------------------------- /RadminSavePassword/Resources/tag-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/RadminSavePassword/Resources/tag-alt.png -------------------------------------------------------------------------------- /RadminSavePassword/Resources/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/RadminSavePassword/Resources/tag.png -------------------------------------------------------------------------------- /RadminSavePassword/ServerInfoForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace RadminSavePassword 2 | { 3 | partial class ServerInfoForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.label1 = new System.Windows.Forms.Label(); 32 | this.txtName = new System.Windows.Forms.TextBox(); 33 | this.txtUsername = new System.Windows.Forms.TextBox(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.txtPassword = new System.Windows.Forms.TextBox(); 36 | this.label3 = new System.Windows.Forms.Label(); 37 | this.btnOk = new System.Windows.Forms.Button(); 38 | this.btnCancel = new System.Windows.Forms.Button(); 39 | this.txtDomain = new System.Windows.Forms.TextBox(); 40 | this.lbDomain = new System.Windows.Forms.Label(); 41 | this.rbRadmin = new System.Windows.Forms.RadioButton(); 42 | this.rbWindows = new System.Windows.Forms.RadioButton(); 43 | this.label5 = new System.Windows.Forms.Label(); 44 | this.SuspendLayout(); 45 | // 46 | // label1 47 | // 48 | this.label1.AutoSize = true; 49 | this.label1.Location = new System.Drawing.Point(26, 37); 50 | this.label1.Name = "label1"; 51 | this.label1.Size = new System.Drawing.Size(29, 12); 52 | this.label1.TabIndex = 3; 53 | this.label1.Text = "名称"; 54 | // 55 | // txtName 56 | // 57 | this.txtName.Location = new System.Drawing.Point(61, 34); 58 | this.txtName.Name = "txtName"; 59 | this.txtName.Size = new System.Drawing.Size(211, 21); 60 | this.txtName.TabIndex = 4; 61 | // 62 | // txtUsername 63 | // 64 | this.txtUsername.Location = new System.Drawing.Point(61, 61); 65 | this.txtUsername.Name = "txtUsername"; 66 | this.txtUsername.Size = new System.Drawing.Size(211, 21); 67 | this.txtUsername.TabIndex = 6; 68 | // 69 | // label2 70 | // 71 | this.label2.AutoSize = true; 72 | this.label2.Location = new System.Drawing.Point(14, 64); 73 | this.label2.Name = "label2"; 74 | this.label2.Size = new System.Drawing.Size(41, 12); 75 | this.label2.TabIndex = 5; 76 | this.label2.Text = "用户名"; 77 | // 78 | // txtPassword 79 | // 80 | this.txtPassword.Location = new System.Drawing.Point(61, 88); 81 | this.txtPassword.Name = "txtPassword"; 82 | this.txtPassword.PasswordChar = '*'; 83 | this.txtPassword.Size = new System.Drawing.Size(211, 21); 84 | this.txtPassword.TabIndex = 8; 85 | // 86 | // label3 87 | // 88 | this.label3.AutoSize = true; 89 | this.label3.Location = new System.Drawing.Point(26, 91); 90 | this.label3.Name = "label3"; 91 | this.label3.Size = new System.Drawing.Size(29, 12); 92 | this.label3.TabIndex = 7; 93 | this.label3.Text = "密码"; 94 | // 95 | // btnOk 96 | // 97 | this.btnOk.Location = new System.Drawing.Point(64, 142); 98 | this.btnOk.Name = "btnOk"; 99 | this.btnOk.Size = new System.Drawing.Size(75, 23); 100 | this.btnOk.TabIndex = 11; 101 | this.btnOk.Text = "确定"; 102 | this.btnOk.UseVisualStyleBackColor = true; 103 | // 104 | // btnCancel 105 | // 106 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 107 | this.btnCancel.Location = new System.Drawing.Point(145, 142); 108 | this.btnCancel.Name = "btnCancel"; 109 | this.btnCancel.Size = new System.Drawing.Size(75, 23); 110 | this.btnCancel.TabIndex = 12; 111 | this.btnCancel.Text = "取消"; 112 | this.btnCancel.UseVisualStyleBackColor = true; 113 | // 114 | // txtDomain 115 | // 116 | this.txtDomain.Location = new System.Drawing.Point(61, 115); 117 | this.txtDomain.Name = "txtDomain"; 118 | this.txtDomain.Size = new System.Drawing.Size(211, 21); 119 | this.txtDomain.TabIndex = 10; 120 | // 121 | // lbDomain 122 | // 123 | this.lbDomain.AutoSize = true; 124 | this.lbDomain.Location = new System.Drawing.Point(26, 118); 125 | this.lbDomain.Name = "lbDomain"; 126 | this.lbDomain.Size = new System.Drawing.Size(29, 12); 127 | this.lbDomain.TabIndex = 9; 128 | this.lbDomain.Text = "域名"; 129 | // 130 | // rbRadmin 131 | // 132 | this.rbRadmin.AutoSize = true; 133 | this.rbRadmin.Location = new System.Drawing.Point(61, 12); 134 | this.rbRadmin.Name = "rbRadmin"; 135 | this.rbRadmin.Size = new System.Drawing.Size(59, 16); 136 | this.rbRadmin.TabIndex = 1; 137 | this.rbRadmin.TabStop = true; 138 | this.rbRadmin.Text = "Radmin"; 139 | this.rbRadmin.UseVisualStyleBackColor = true; 140 | // 141 | // rbWindows 142 | // 143 | this.rbWindows.AutoSize = true; 144 | this.rbWindows.Location = new System.Drawing.Point(126, 12); 145 | this.rbWindows.Name = "rbWindows"; 146 | this.rbWindows.Size = new System.Drawing.Size(65, 16); 147 | this.rbWindows.TabIndex = 2; 148 | this.rbWindows.TabStop = true; 149 | this.rbWindows.Text = "Windows"; 150 | this.rbWindows.UseVisualStyleBackColor = true; 151 | // 152 | // label5 153 | // 154 | this.label5.AutoSize = true; 155 | this.label5.Location = new System.Drawing.Point(14, 14); 156 | this.label5.Name = "label5"; 157 | this.label5.Size = new System.Drawing.Size(41, 12); 158 | this.label5.TabIndex = 0; 159 | this.label5.Text = "安全性"; 160 | // 161 | // ServerInfoForm 162 | // 163 | this.AcceptButton = this.btnOk; 164 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 165 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 166 | this.CancelButton = this.btnCancel; 167 | this.ClientSize = new System.Drawing.Size(284, 175); 168 | this.Controls.Add(this.label5); 169 | this.Controls.Add(this.rbWindows); 170 | this.Controls.Add(this.rbRadmin); 171 | this.Controls.Add(this.txtDomain); 172 | this.Controls.Add(this.lbDomain); 173 | this.Controls.Add(this.btnCancel); 174 | this.Controls.Add(this.btnOk); 175 | this.Controls.Add(this.txtPassword); 176 | this.Controls.Add(this.label3); 177 | this.Controls.Add(this.txtUsername); 178 | this.Controls.Add(this.label2); 179 | this.Controls.Add(this.txtName); 180 | this.Controls.Add(this.label1); 181 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 182 | this.MaximizeBox = false; 183 | this.MinimizeBox = false; 184 | this.Name = "ServerInfoForm"; 185 | this.ShowIcon = false; 186 | this.ShowInTaskbar = false; 187 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 188 | this.Text = "服务器信息"; 189 | this.ResumeLayout(false); 190 | this.PerformLayout(); 191 | 192 | } 193 | 194 | #endregion 195 | 196 | private System.Windows.Forms.Label label1; 197 | private System.Windows.Forms.TextBox txtName; 198 | private System.Windows.Forms.TextBox txtUsername; 199 | private System.Windows.Forms.Label label2; 200 | private System.Windows.Forms.TextBox txtPassword; 201 | private System.Windows.Forms.Label label3; 202 | private System.Windows.Forms.Button btnOk; 203 | private System.Windows.Forms.Button btnCancel; 204 | private System.Windows.Forms.TextBox txtDomain; 205 | private System.Windows.Forms.Label lbDomain; 206 | private System.Windows.Forms.RadioButton rbRadmin; 207 | private System.Windows.Forms.RadioButton rbWindows; 208 | private System.Windows.Forms.Label label5; 209 | } 210 | } -------------------------------------------------------------------------------- /RadminSavePassword/ServerInfoForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | 9 | namespace RadminSavePassword 10 | { 11 | public partial class ServerInfoForm : Form 12 | { 13 | public LoginType _lastLoginType; 14 | public ServerInfo _sourceServerInfo; 15 | 16 | public ServerInfo ServerInfo { get; private set; } 17 | 18 | public ServerInfoForm() 19 | : this(null) 20 | { 21 | 22 | } 23 | 24 | public ServerInfoForm(ServerInfo serverInfo) 25 | { 26 | InitializeComponent(); 27 | 28 | ServerInfo = new ServerInfo(); 29 | _sourceServerInfo = serverInfo; 30 | 31 | rbRadmin.Tag = LoginType.Radmin; 32 | rbWindows.Tag = LoginType.Windows; 33 | _lastLoginType = LoginType.Windows; 34 | } 35 | 36 | protected override void OnLoad(EventArgs e) 37 | { 38 | base.OnLoad(e); 39 | 40 | btnOk.Click += btnOk_Click; 41 | btnCancel.Click += btnCancel_Click; 42 | rbRadmin.CheckedChanged += rb_CheckedChanged; 43 | rbWindows.CheckedChanged += rb_CheckedChanged; 44 | 45 | UpdateUIControlData(_sourceServerInfo); 46 | } 47 | 48 | void rb_CheckedChanged(object sender, EventArgs e) 49 | { 50 | RadioButton rb = (RadioButton)sender; 51 | if (!rb.Checked) return; 52 | 53 | LoginType loginType = (LoginType)rb.Tag; 54 | UpdateUIControlLayout(loginType); 55 | } 56 | 57 | void btnCancel_Click(object sender, EventArgs e) 58 | { 59 | ServerInfo = null; 60 | UpdateUIControlData(ServerInfo); 61 | } 62 | 63 | void btnOk_Click(object sender, EventArgs e) 64 | { 65 | if (string.IsNullOrEmpty(txtName.Text)) 66 | { 67 | MessageBox.Show("名称不能为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 68 | return; 69 | } 70 | 71 | if (string.IsNullOrEmpty(txtUsername.Text)) 72 | { 73 | MessageBox.Show("用户名不能为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 74 | return; 75 | } 76 | 77 | if ((Global.SystemConfig.ServerList.ContainsKey(txtName.Text) && Global.SystemConfig.ServerList[txtName.Text] != _sourceServerInfo)) 78 | { 79 | MessageBox.Show("该服务器名称已存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); 80 | return; 81 | } 82 | 83 | SaveUIDataToObj(ServerInfo); 84 | DialogResult = DialogResult.OK; 85 | } 86 | 87 | protected virtual void UpdateUIControlLayout(LoginType loginType) 88 | { 89 | if (_lastLoginType == loginType) return; 90 | 91 | int size = 26; 92 | int change = loginType == LoginType.Windows ? 1 : -1; 93 | bool visible = loginType == LoginType.Windows; 94 | 95 | lbDomain.Visible = txtDomain.Visible = visible; 96 | lbDomain.Location = new Point(lbDomain.Location.X, lbDomain.Location.Y + (size * change)); 97 | txtDomain.Location = new Point(txtDomain.Location.X, txtDomain.Location.Y + (size * change)); 98 | btnOk.Location = new Point(btnOk.Location.X, btnOk.Location.Y + (size * change)); 99 | btnCancel.Location = new Point(btnCancel.Location.X, btnCancel.Location.Y + (size * change)); 100 | Size = new Size(Size.Width, Size.Height + (size * change)); 101 | _lastLoginType = loginType; 102 | } 103 | 104 | protected virtual void UpdateUIControlData(ServerInfo serverInfo) 105 | { 106 | if (serverInfo != null) 107 | { 108 | switch (serverInfo.LoginType) 109 | { 110 | case LoginType.Radmin: 111 | rbRadmin.Checked = true; 112 | break; 113 | case LoginType.Windows: 114 | rbWindows.Checked = true; 115 | break; 116 | default: 117 | throw new NotImplementedException(); 118 | } 119 | txtName.Text = serverInfo.Name; 120 | txtUsername.Text = serverInfo.UserName; 121 | txtPassword.Text = serverInfo.Password; 122 | txtDomain.Text = serverInfo.Domain; 123 | } 124 | else 125 | { 126 | rbRadmin.Checked = true; 127 | txtName.Text = string.Empty; 128 | txtUsername.Text = string.Empty; 129 | txtPassword.Text = string.Empty; 130 | txtDomain.Text = string.Empty; 131 | } 132 | } 133 | 134 | protected virtual void SaveUIDataToObj(ServerInfo serverInfo) 135 | { 136 | if (serverInfo == null) return; 137 | 138 | serverInfo.Name = txtName.Text; 139 | serverInfo.UserName = txtUsername.Text; 140 | serverInfo.Password = txtPassword.Text; 141 | if (rbRadmin.Checked) 142 | serverInfo.LoginType = (LoginType)rbRadmin.Tag; 143 | else if (rbWindows.Checked) 144 | serverInfo.LoginType = (LoginType)rbWindows.Tag; 145 | else 146 | throw new NotImplementedException(); 147 | 148 | if (serverInfo.LoginType == LoginType.Windows) 149 | serverInfo.Domain = txtDomain.Text; 150 | else 151 | serverInfo.Domain = string.Empty; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /RadminSavePassword/ServerInfoForm.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 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /RadminSavePassword/costura32/GlobalCbtHook.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjj0906/RadminSavePassword/6d4eec45ac09f56ed44c81410cc6fe6cf6398040/RadminSavePassword/costura32/GlobalCbtHook.dll --------------------------------------------------------------------------------