├── .gitignore
├── LICENSE
├── README.md
├── Wlx2Explorer.sln
└── Wlx2Explorer
├── Extensions
└── EnumExtensions.cs
├── Forms
├── AboutForm.Designer.cs
├── AboutForm.cs
├── AboutForm.resx
├── ListerForm.Designer.cs
├── ListerForm.cs
├── ListerForm.resx
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── MessageBoxForm.Designer.cs
├── MessageBoxForm.cs
├── MessageBoxForm.resx
├── PluginSettingsForm.Designer.cs
├── PluginSettingsForm.cs
├── PluginSettingsForm.resx
├── ProgramSettingsForm.Designer.cs
├── ProgramSettingsForm.cs
├── ProgramSettingsForm.resx
├── SearchForm.Designer.cs
├── SearchForm.cs
└── SearchForm.resx
├── Hooks
├── KeyboardHook.cs
├── VirtualKey.cs
└── VirtualKeyModifier.cs
├── Images
├── Down.png
├── Start.png
├── Stop.png
├── Up.png
├── Wlx2Explorer.ico
└── Wlx2Explorer.png
├── InitializationFile.cs
├── Libs
├── UnRAR.dll
└── UnRAR64.dll
├── Native
├── Interfaces
│ ├── IServiceProvider.cs
│ └── IShellBrowser.cs
├── NativeConstants.cs
├── NativeMethods.cs
└── NativeTypes.cs
├── Plugin.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── Settings
├── PluginInfo.cs
└── ProgramSettings.cs
├── StartUpManager.cs
├── ToggleParser.cs
├── Utils
├── AssemblyUtils.cs
└── WindowUtils.cs
├── Win32WindowWrapper.cs
├── Wlx2Explorer.csproj
├── Wlx2Explorer.ico
├── Wlx2Explorer.ini
└── Wlx2Explorer.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 |
3 | # Logs
4 | logs
5 | *.log
6 |
7 | ## Ignore Visual Studio temporary files, build results, and
8 | ## files generated by popular Visual Studio add-ons.
9 |
10 | # User-specific files
11 | *.suo
12 | *.user
13 | *.sln.docstates
14 |
15 | # Build results
16 |
17 | [Dd]ebug/
18 | [Rr]elease/
19 | x64/
20 | build/
21 | [Bb]in/
22 | [Oo]bj/
23 |
24 | #NuGet
25 | packages/
26 |
27 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
28 | !packages/*/build/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | *_i.c
35 | *_p.c
36 | *.ilk
37 | *.meta
38 | *.obj
39 | *.pch
40 | *.pdb
41 | *.pgc
42 | *.pgd
43 | *.rsp
44 | *.sbr
45 | *.tlb
46 | *.tli
47 | *.tlh
48 | *.tmp
49 | *.tmp_proj
50 | *.log
51 | *.vspscc
52 | *.vssscc
53 | .builds
54 | *.pidb
55 | *.log
56 | *.scc
57 |
58 | # Visual C++ cache files
59 | ipch/
60 | *.aps
61 | *.ncb
62 | *.opensdf
63 | *.sdf
64 | *.cachefile
65 |
66 | # Visual Studio profiler
67 | *.psess
68 | *.vsp
69 | *.vspx
70 |
71 | # Guidance Automation Toolkit
72 | *.gpState
73 |
74 | # ReSharper is a .NET coding add-in
75 | _ReSharper*/
76 | *.[Rr]e[Ss]harper
77 |
78 | # TeamCity is a build add-in
79 | _TeamCity*
80 |
81 | # DotCover is a Code Coverage Tool
82 | *.dotCover
83 |
84 | # NCrunch
85 | *.ncrunch*
86 | .*crunch*.local.xml
87 |
88 | # Installshield output folder
89 | [Ee]xpress/
90 |
91 | # DocProject is a documentation generator add-in
92 | DocProject/buildhelp/
93 | DocProject/Help/*.HxT
94 | DocProject/Help/*.HxC
95 | DocProject/Help/*.hhc
96 | DocProject/Help/*.hhk
97 | DocProject/Help/*.hhp
98 | DocProject/Help/Html2
99 | DocProject/Help/html
100 |
101 | # Click-Once directory
102 | publish/
103 |
104 | # Publish Web Output
105 | *.Publish.xml
106 |
107 | # NuGet Packages Directory
108 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
109 | #packages/
110 |
111 | # Windows Azure Build Output
112 | csx
113 | *.build.csdef
114 |
115 | # Windows Store app package directory
116 | AppPackages/
117 |
118 | # Others
119 | sql/
120 | *.Cache
121 | ClientBin/
122 | [Ss]tyle[Cc]op.*
123 | ~$*
124 | *~
125 | *.dbmdl
126 | *.[Pp]ublish.xml
127 | *.pfx
128 | *.publishsettings
129 |
130 | # RIA/Silverlight projects
131 | Generated_Code/
132 |
133 | # Backup & report files from converting an old project file to a newer
134 | # Visual Studio version. Backup files are not needed, because we have git ;-)
135 | _UpgradeReport_Files/
136 | Backup*/
137 | UpgradeLog*.XML
138 | UpgradeLog*.htm
139 |
140 | # SQL Server files
141 | App_Data/*.mdf
142 | App_Data/*.ldf
143 |
144 |
145 | #LightSwitch generated files
146 | GeneratedArtifacts/
147 | _Pvt_Extensions/
148 | ModelManifest.xml
149 |
150 | # =========================
151 | # Windows detritus
152 | # =========================
153 |
154 | # Windows image file caches
155 | Thumbs.db
156 | ehthumbs.db
157 |
158 | # Folder config file
159 | Desktop.ini
160 |
161 | # Recycle Bin used on file shares
162 | $RECYCLE.BIN/
163 |
164 | # Mac desktop service store files
165 | .DS_Store
166 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Alexander Illarionov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 | # Wlx2Explorer
6 |
7 |
8 |
9 | Wlx2Explorer is an application which allows you to use Total Commander lister plugins from File Explorer or Desktop.
10 |
11 | * Open File Explorer, select the necessary file and press the hot keys (Ctrl + Q), then you can use the plugin.
12 | * Or simply select the necessary file on your Desktop and press the hot keys (Ctrl + Q).
13 |
14 | Screenshot
15 | ------------------
16 |
17 | 
18 | 
19 |
20 | Command Line Interface
21 | --------------------
22 |
23 | ```bash
24 | -h --help The help
25 | -f --file Path to file
26 | -s --suppressmsg Suppress messages
27 |
28 | Example:
29 | Wlx2Explorer.exe -s --file "C:\Temp\Image.jpeg"
30 | ```
31 |
32 | Requirements
33 | ------------------
34 |
35 | * OS Windows XP SP3 and later.
36 | * .NET Framework 4.0
37 |
38 | Files
39 | ------------------
40 |
41 | * Wlx2Explorer.exe - The main executable module.
42 | * Wlx2Explorer.xml - The application settings file.
43 | * Wlx2Explorer.ini - The plugins settings file.
--------------------------------------------------------------------------------
/Wlx2Explorer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29318.209
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wlx2Explorer", "Wlx2Explorer\Wlx2Explorer.csproj", "{82A3A166-142C-4C62-8D57-6CF8678402AA}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Debug|x64.ActiveCfg = Debug|x64
17 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Debug|x64.Build.0 = Debug|x64
18 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Debug|x86.ActiveCfg = Debug|x86
19 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Debug|x86.Build.0 = Debug|x86
20 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Release|x64.ActiveCfg = Release|x64
21 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Release|x64.Build.0 = Release|x64
22 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Release|x86.ActiveCfg = Release|x86
23 | {82A3A166-142C-4C62-8D57-6CF8678402AA}.Release|x86.Build.0 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | VisualSVNWorkingCopyRoot = .
30 | SolutionGuid = {BF0AC8CD-EEA6-4627-9260-407C1EA7A175}
31 | EndGlobalSection
32 | EndGlobal
33 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Extensions/EnumExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.ComponentModel;
4 |
5 | namespace Wlx2Explorer.Extensions
6 | {
7 | static class EnumExtensions
8 | {
9 | public static string GetDescription(this Enum value) =>
10 | value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false).OfType()?.FirstOrDefault()?.Description ?? string.Empty;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/AboutForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Forms
2 | {
3 | partial class AboutForm
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 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
32 | this.lblProductName = new System.Windows.Forms.Label();
33 | this.lblCopyright = new System.Windows.Forms.Label();
34 | this.linkUrl = new System.Windows.Forms.LinkLabel();
35 | this.btnOk = new System.Windows.Forms.Button();
36 | this.pbImage = new System.Windows.Forms.PictureBox();
37 | this.lblProductTitle = new System.Windows.Forms.Label();
38 | ((System.ComponentModel.ISupportInitialize)(this.pbImage)).BeginInit();
39 | this.SuspendLayout();
40 | //
41 | // lblProductName
42 | //
43 | this.lblProductName.AutoSize = true;
44 | this.lblProductName.Location = new System.Drawing.Point(58, 21);
45 | this.lblProductName.Name = "lblProductName";
46 | this.lblProductName.Size = new System.Drawing.Size(75, 13);
47 | this.lblProductName.TabIndex = 0;
48 | this.lblProductName.Text = "Product Name";
49 | //
50 | // lblCopyright
51 | //
52 | this.lblCopyright.AutoSize = true;
53 | this.lblCopyright.Location = new System.Drawing.Point(58, 72);
54 | this.lblCopyright.Name = "lblCopyright";
55 | this.lblCopyright.Size = new System.Drawing.Size(51, 13);
56 | this.lblCopyright.TabIndex = 1;
57 | this.lblCopyright.Text = "Copyright";
58 | //
59 | // linkUrl
60 | //
61 | this.linkUrl.AutoSize = true;
62 | this.linkUrl.Location = new System.Drawing.Point(58, 95);
63 | this.linkUrl.Name = "linkUrl";
64 | this.linkUrl.Size = new System.Drawing.Size(29, 13);
65 | this.linkUrl.TabIndex = 2;
66 | this.linkUrl.TabStop = true;
67 | this.linkUrl.Text = "URL";
68 | this.linkUrl.Click += new System.EventHandler(this.LinkClick);
69 | //
70 | // btnOk
71 | //
72 | this.btnOk.Location = new System.Drawing.Point(352, 16);
73 | this.btnOk.Name = "btnOk";
74 | this.btnOk.Size = new System.Drawing.Size(75, 23);
75 | this.btnOk.TabIndex = 3;
76 | this.btnOk.Text = "Ok";
77 | this.btnOk.UseVisualStyleBackColor = true;
78 | this.btnOk.Click += new System.EventHandler(this.CloseClick);
79 | //
80 | // pbImage
81 | //
82 | this.pbImage.Image = ((System.Drawing.Image)(resources.GetObject("pbImage.Image")));
83 | this.pbImage.InitialImage = null;
84 | this.pbImage.Location = new System.Drawing.Point(4, 21);
85 | this.pbImage.Name = "pbImage";
86 | this.pbImage.Size = new System.Drawing.Size(48, 48);
87 | this.pbImage.TabIndex = 4;
88 | this.pbImage.TabStop = false;
89 | //
90 | // lblProductTitle
91 | //
92 | this.lblProductTitle.AutoSize = true;
93 | this.lblProductTitle.Location = new System.Drawing.Point(58, 47);
94 | this.lblProductTitle.Name = "lblProductTitle";
95 | this.lblProductTitle.Size = new System.Drawing.Size(67, 13);
96 | this.lblProductTitle.TabIndex = 5;
97 | this.lblProductTitle.Text = "Product Title";
98 | //
99 | // AboutForm
100 | //
101 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
102 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
103 | this.ClientSize = new System.Drawing.Size(439, 132);
104 | this.Controls.Add(this.lblProductTitle);
105 | this.Controls.Add(this.pbImage);
106 | this.Controls.Add(this.btnOk);
107 | this.Controls.Add(this.linkUrl);
108 | this.Controls.Add(this.lblCopyright);
109 | this.Controls.Add(this.lblProductName);
110 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
111 | this.KeyPreview = true;
112 | this.MaximizeBox = false;
113 | this.MinimizeBox = false;
114 | this.Name = "AboutForm";
115 | this.ShowInTaskbar = false;
116 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
117 | this.Text = "About";
118 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormKeyDown);
119 | ((System.ComponentModel.ISupportInitialize)(this.pbImage)).EndInit();
120 | this.ResumeLayout(false);
121 | this.PerformLayout();
122 |
123 | }
124 |
125 | #endregion
126 |
127 | private System.Windows.Forms.Label lblProductName;
128 | private System.Windows.Forms.Label lblCopyright;
129 | private System.Windows.Forms.LinkLabel linkUrl;
130 | private System.Windows.Forms.Button btnOk;
131 | private System.Windows.Forms.PictureBox pbImage;
132 | private System.Windows.Forms.Label lblProductTitle;
133 | }
134 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/AboutForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Windows.Forms;
4 | using Wlx2Explorer.Utils;
5 |
6 | namespace Wlx2Explorer.Forms
7 | {
8 | partial class AboutForm : Form
9 | {
10 | private const string URL = "https://github.com/AlexanderPro/Wlx2Explorer";
11 |
12 | public AboutForm()
13 | {
14 | InitializeComponent();
15 | Text = $"About {AssemblyUtils.AssemblyProductName}";
16 | lblProductName.Text = $"{AssemblyUtils.AssemblyProductName} v{AssemblyUtils.AssemblyProductVersion}";
17 | lblProductTitle.Text = AssemblyUtils.AssemblyTitle;
18 | lblCopyright.Text = $"Copyright © 2014 - {DateTime.Now.Year}";
19 | linkUrl.Text = URL;
20 | }
21 |
22 | private void CloseClick(object sender, EventArgs e)
23 | {
24 | Close();
25 | }
26 |
27 | private void LinkClick(object sender, EventArgs e)
28 | {
29 | Process.Start(URL);
30 | }
31 |
32 | private void FormKeyDown(object sender, KeyEventArgs e)
33 | {
34 | CloseClick(sender, e);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/AboutForm.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 |
123 | iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAC
124 | 4gAAAuIBSbr4BAAAAAd0SU1FB90KCwwyJVCrQ6MAAA24SURBVGhD1ZoJVFTXHcZt0yTdkoiapumWpkua
125 | tqlJmnhijDZteurSNm2OMS5VE3erxQUVQZYZ9gDDKqsSF1zQoKAQFRQiKIMBhWEZlpFlWGYGhmEWZgZm
126 | gYGv//sYlhG0GEna3nN+RzMn+L7fvd+9773RKRMZZm2hQidPj1Q3HZ1XUrLpYfvH/z/D1Hmhz6LLh7Ix
127 | Bfr2i5Ye1SURfRZvUp16G6q4b9v/t//doW892G/RZcDWUwRpRSxaKsPQ2RCD7vbTsGiu2Kzay5Je3aUT
128 | ZtWZVUZlwnfsP/a/M7qa9vcb25MA63UMWMsgq02GuDAAreJwTsTQmoAexQGYVafQq7sCq/aK3KrNyrB0
129 | pjlbOo/83P7H/PeGThrZb2iLBSxZJHEN6K2AVn4RN3K8UHVjrIipjWTaD8KiOkkyl0kqR9urzf7Uqkn3
130 | 7mlLegVIfcj+R385QyeN6DcoogFzpoOEuasIwmw+inN5qC0Ogrw6AurGsSJDWDqOk1A2WyWTVZddbFVn
131 | hJmVR9+CLOIb9kt9MWNE4PwoiXySKIfNXANRgQAFl/ZBdM0X9aXBaKuNhEYae1eREaFkEspiK8T2UXWv
132 | JiPJ3P7R7+2XnbzhKDAkcckuUYGBvmbczPXD9Yv7cPNTHlerpnIBlLejoG2Kg1GWeE+RYZRHuT3ULUvO
133 | Ad6bvJqNFRi9EgVAnwSymmRczdwLYZYHJ1FZ6M+thqwqHKr6/dC3xqNbnshJ3FvkAHq1V9BW4uFqv/yD
134 | j/EFMuwSNFm9IhiUOZwAq1JxrjdK8324k6quJJjb5Mrb0dxq3L1W9N9tiUQCzB0noCz3z7df/sHH+AJ2
135 | CW4VimDS5A0LFNHpVJLHR4XQj9vcjWWh3EqMlaDA9uAmCm5qi4dJEUdVOoaOsoDr9ss/+Li3ANsLQphU
136 | WXcVaBCFcDe/dkkUd9zqW+Oo5ywsCz0S3KSIJWJIKhnKMr8vScB8kSTyYGzPQO65ewu01UZAVRcFXXMM
137 | bexY9MhZ6JHgJvl++iwapvYjJOD7JQmYPsGAOReGtnTs3uuPna48XDw7WiAQDbSZWypCoagJQ0ddBHRN
138 | 0TC2srAs9EjwHnkUemRRJHBocgW0jeF3ESBMGRgwXYZRcQbhYeHg8XzwL+c9eH/9Xhw7xEdtETuNgtBc
139 | EQxFdSg6boeRQCSMLVFUIxaaoNA9skgigsPUloR2EX/yBDR3EzClY6DnHAlkwaBIRUJCAgSCMHh5+WCb
140 | swtWrlyHpat2IUTgTzUKIoEQdEgE0ErDYWiJRHcrCz0UPBw9rWH0WRh62g5Cfos3eQLq8QS48Gcx0J1G
141 | v16AQZaCuLh4xMbGISREAA8PHtZt3I0fvJGE3//dBytW74KrRwDEN0KgbRTA0BxOYVlo9isLLiBC0d0S
142 | SidUIlpvek2eQOedAiaadS58KnEG/d2ZdLKcpOChnEB0dAyCAkOw3YWHJ15NwROzUvHdN1KwYf1WrFzj
143 | hk0eH6NUSBu5hYUmKHR3S4idYKpVPJqLJlOgIWyUwDkSYLNO4Y2n0W/8mDgPfUsyPD29IQgNw34SCA+P
144 | grtn8LDAtNfOcgKr1rhixrwcOL3xKd7efB652XSHptDdzR/CyBFEArFo/MxzEgXqRwlw4c/QzJ8mgRQK
145 | fwr9hjTamEep9zvh7e2D0NBwREZEg+8Xfk8Bp7lX8cz8HDSLBVxwY3MgjE0BtB9i0HDD/QsQGO79x4Ph
146 | DSeIk8QZEjiMD95fh507doPP86U6hcHXP2pEYPb4Ak5z87DF8zQX3NjkT/hRraJRX7B38gRUdoHh3nOz
147 | TuH1x4jjsOlToZMm4d3Fy7F2zUa4uOwBn+8Hb/7ICkwngc2bto0rMP13edDU+cMg9SV8SCASkmuukyhQ
148 | RwJ0k+F6T9XhZp2F7zoKG8dpaBo/wu8WbMGSJSuxfv1m7HJxxR63AAeBnTv3jivA6LztB0Mjn+DRnghH
149 | bd7uyRPoqBP0G+i8Hu694TiFT4ZNd5g4QqTQM04SHpsZg6dnhWH2fDd8sMYZW533Yeosu8DraXB388Ka
150 | jfvGF5D4UHhvwov2QhiqPt1VQJf+ymCCBxzK2yGDAkO91yeTAAv+EWzaQ8QJaBoOwunlWDz2YgIef+kg
151 | ZsxKwqyFoVjyQSDeXBKPp+elwtODj01b+eML1PKgb/AkPEggFOU5LkK6NPsOir3YfJVgMp9PSFkbTAIR
152 | o6rDwrPgBzn6tMnQNSYg82IetnqexzNvHsHjvz2Mx185Bidagd8sPISl68Kxz90b/9zmN66AqtYL+vp9
153 | hDsJBEOUvZ0JsHflrxOPEkzmawQTuj+R9toP+/V0x2Qblus9Fz4JNk0i+jgOQ1sfC6FQiOLiYhTfLIEg
154 | MR+z30sb3gNTX0vHs388g7eWJo0vUONB4d3QVbcXhqYglFzaVkiXfoxgX5x9i7hThq3KxEYbJxDGVYfr
155 | PRf+APrU8ejrJNQHoK4RQHj6NCcgEokgFoshkUhwPrsSy12uYsacc5g6OxNTX78IpzlXxgh0VLtTeFdi
156 | D51EgSi+4PwZXdqJmEo8QQzJMJjMxN+ZFTWBJCAY1XuqjTqBwseiTxWDXlUsVNVBEAYHo3j7doji4iCu
157 | rOQEpFIpZDIZKmta4RUlwk8XUvhxBfai6/ZuYhcJBOBGxpYiujT7lm8GMZ2YRgzJfJOY+AooqgI4geHe
158 | s9qo4yj8fvR2RKFXGQllpd9whUSpqRDv2QNJQACktBJMQKlUQqPRoFPTheSMFry59qajQNUeCu8CnWQn
159 | 9I1+KEjfXEyX/h7xXeIpgsk8SbBVYVWa+D5QVPmRQOhI77nqxJAAhe+IQG+7APJSrxGBoQrR76X+/pB5
160 | e0N54wYnYDAYYLFYYLPZkHhGNiIg3kXhdxDb6STygSjXS+HmPId9R/QD4vsEk3maYKvBNvPEh3xIYLj3
161 | rDrRFD6SZj+MBEIgyd0DobMzimNiICotHd4DXIWam6E8fBgaHg+G9HRYzGZO4MJ11SgBmv3abXacobtN
162 | G7opzngybtkuivAM8SPihwRbkUeIia+ArNKHBEJG9Z5Vh4UPp/ChMMsDkfvJocEVOHkSIhcXiGnmJbQS
163 | Q3tgqEKGwkJYqFq2lBRHgUqa/dp/QVvD2Iqe9tP0YnMMhZk7blOEnxE/IZ4lfkywOjGJiY3WCn6/nh55
164 | ud5TdQZ7z8ILYG0Lhlnmj5wLxx0rVFAACZ8PqacnZPT5sMBQhWgVRgsoK7ZxwbU1W6Ct/id6DeXo71Xj
165 | 5oUVBorwPPEcwb7pZrAVuQ+Bcn5/F91cBnvPqkO9V7LwIbAqgmBu9cWV3eshjI4ec4xK6+shO3gQSi8v
166 | aM6ehUGvH94DjgI08xRcW72Z2ASroYwTKM5czgReIH5N/JL4BcGqNPF90FLOI4EPx/Te2vYhCQTA1OKD
167 | y5/QChw5MniM+vhAfPOmwzHKrUBeHgx+frAkJtIDYJejQPkWaCi4pmojsWFY4LPzy5jAS8SLxEyCSbAj
168 | deL3AVkFEwhy6D2rjlURCKvcDz0tPGRnHhup0NWrENOMS9zdIc3Pd9wDrEJyOWxpaQ4C7WWbueCaqvXQ
169 | iNfBqhdxAoXnlhopwit2XiZYndjdeOJDLva2dTUHOPSeVccq94dF5oOeZm9kRfmOPUarqyGlm5rMwwNK
170 | ujfceYw6CtDsU3CNeC3U4jUkUEoCnRCmLWECs+0wCXas3t9fNCrEPjYdJ2CvDhc+gML7wtLKQ0+TJy79
171 | ZAaEzz2HYjrzRUVFjscoW4GcHGhoUxvi42EhkTECog1ccHXlB8T7gwJWEjj7bjdFmEe8QbxKPE5M/C7M
172 | xq3L20MMtIkHqzPYe4uMutzKh6XFC93Sfbj47HTQ4yPo9gnR1KkQb9gACdVnzDHa2AhLRARsyckOAm2l
173 | 67jg6srVUFesgklbgj6zCtfPLGYCfyCYBOv//dVnaBRmOq/Q1PnahnrPqmNp9Ya52RPdDW64MFqAEBOS
174 | hx6CdNEiyKjvY47RO1agrZRmn4KrK1ais+IfEN+6hltFNSTwDhOYT7xJsJvY/d2FRw9hxsZftIjcdEPV
175 | sbR4ksA+EnBF+LK/qXOe+9WAgwAhJWSE8oUXoNm/HwaVanyBkve54J3lK4jlyM7IRuqpIlxP/RsTWEiw
176 | PcAe4h5s5Oev+XrNte0VrDosvLnJDd31u/HOn55nt/wF2+e8k3LltT9Yqh55BHUUvImQEx2EljBOmwaL
177 | qytsTU0OAopbq7jgneXL0Fm2FB8lnENQ4GVc+/htJrCAYHfjid+8/tMozdp4qLtxL8xSVxjrXLDirzM3
178 | 0sfsrGY3nV9umrt4ec785a0t33mKC68h9EQPYSX6qV51a3aPEqDZp+CdZe9BVbYEBZ8E4HDcIeSe+DPN
179 | wZQ5BJv9z/dKebfxWebatWrxDpta7IzVi198iz5iT4vs0Zc99rKnRqcFLyz4ft6yHTmdM1+1mSl4L2Ej
180 | Bgjl3EUUfvCRWn5rORdcJXqXWIyrpxapyi79Oe9A0Dw2MV/cP2coSFs7U5i+unj+i0+x1z52QrBlHmL0
181 | e+xDOev8eco//t0w8OijgF3gqZd9MW1OBv7yp+fXB7u/dOR41Oxbcb6v5Xzz4Sm/pZ9hb17s5yd35u9j
182 | sAvfyZSsrdFzGxZvaqxbuLr3yVlxmP56Op78tS+bZfbayJ5zGA++Yb/w8UrJw07z8pY7zc0vnLLo0uc4
183 | 36dM+TcRZl/hRmSf3QAAAABJRU5ErkJggg==
184 |
185 |
186 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/ListerForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Forms
2 | {
3 | partial class ListerForm
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 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ListerForm));
32 | this.pnlLister = new System.Windows.Forms.Panel();
33 | this.SuspendLayout();
34 | //
35 | // pnlLister
36 | //
37 | this.pnlLister.BackColor = System.Drawing.SystemColors.Control;
38 | this.pnlLister.Dock = System.Windows.Forms.DockStyle.Fill;
39 | this.pnlLister.Location = new System.Drawing.Point(0, 0);
40 | this.pnlLister.Name = "pnlLister";
41 | this.pnlLister.Size = new System.Drawing.Size(715, 603);
42 | this.pnlLister.TabIndex = 0;
43 | //
44 | // ListerForm
45 | //
46 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
47 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
48 | this.AutoSize = true;
49 | this.ClientSize = new System.Drawing.Size(715, 603);
50 | this.Controls.Add(this.pnlLister);
51 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
52 | this.Name = "ListerForm";
53 | this.Opacity = 0D;
54 | this.ShowInTaskbar = false;
55 | this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
56 | this.Text = "Lister";
57 | this.ResumeLayout(false);
58 |
59 | }
60 |
61 | #endregion
62 |
63 | private System.Windows.Forms.Panel pnlLister;
64 | }
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/ListerForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Windows.Forms;
6 | using System.Runtime.ExceptionServices;
7 | using System.IO;
8 | using System.Drawing.Printing;
9 | using Wlx2Explorer.Utils;
10 | using Wlx2Explorer.Settings;
11 | using Wlx2Explorer.Native;
12 | using Wlx2Explorer.Hooks;
13 |
14 | namespace Wlx2Explorer.Forms
15 | {
16 | partial class ListerForm : Form, IMessageFilter
17 | {
18 | private IntPtr _pluginHandle;
19 | private Plugin _plugin;
20 | private string _fileName;
21 | private ProgramSettings _settings;
22 |
23 | public ListerForm(ProgramSettings settings, IList plugins, string fileName)
24 | {
25 | InitializeComponent();
26 |
27 | bool pluginLoaded = TryToLoadPlugin(settings, plugins, fileName, out _pluginHandle, out _plugin);
28 | if (!pluginLoaded)
29 | {
30 | Close();
31 | return;
32 | }
33 |
34 | _settings = settings;
35 | _fileName = fileName;
36 | Text = "Lister - " + fileName;
37 | Width = settings.ListerFormWidth;
38 | Height = settings.ListerFormHeight;
39 | Opacity = 1.0;
40 | ShowInTaskbar = true;
41 | CenterToScreen();
42 | WindowState = settings.ListerFormMaximized ? FormWindowState.Maximized : WindowState;
43 | Application.AddMessageFilter(this);
44 | }
45 |
46 | [HandleProcessCorruptedStateExceptions]
47 | private bool TryToLoadPlugin(ProgramSettings settings, IList plugins, string fileName, out IntPtr pluginHandle, out Plugin plugin)
48 | {
49 | pluginHandle = IntPtr.Zero;
50 | plugin = null;
51 | foreach (var sourcePlugin in plugins)
52 | {
53 | try
54 | {
55 | PluginInfo pluginInfo = settings.Plugins.FirstOrDefault(x => string.Compare(x.Path, sourcePlugin.ModuleName) == 0);
56 | string extension = Path.GetExtension(fileName).TrimStart('.');
57 | if (pluginInfo.Extensions.Count == 0 || pluginInfo.Extensions.Contains(extension.ToLower()) || pluginInfo.Extensions.Contains(extension.ToUpper()))
58 | {
59 | pluginHandle = sourcePlugin.ListLoad(pnlLister.Handle, fileName);
60 | }
61 | }
62 | catch
63 | {
64 | }
65 |
66 | if (pluginHandle != IntPtr.Zero)
67 | {
68 | plugin = sourcePlugin;
69 | break;
70 | }
71 | }
72 | return pluginHandle != IntPtr.Zero;
73 | }
74 |
75 | protected override void OnLoad(EventArgs e)
76 | {
77 | base.OnLoad(e);
78 |
79 | pnlLister.Focus();
80 | NativeMethods.SetFocus(_pluginHandle);
81 | }
82 |
83 | [HandleProcessCorruptedStateExceptions]
84 | protected override void OnClosing(CancelEventArgs e)
85 | {
86 | base.OnClosing(e);
87 |
88 | try
89 | {
90 | if (_plugin.ListCloseWindowExist)
91 | {
92 | _plugin.ListCloseWindow(_pluginHandle);
93 | }
94 | else
95 | {
96 | NativeMethods.DestroyWindow(_pluginHandle);
97 | }
98 | Application.RemoveMessageFilter(this);
99 | }
100 | catch
101 | {
102 | }
103 | }
104 |
105 | protected override void OnResize(EventArgs e)
106 | {
107 | base.OnResize(e);
108 |
109 | if (_pluginHandle == IntPtr.Zero) return;
110 | NativeMethods.SetWindowPos(_pluginHandle, new IntPtr(0), 0, 0, pnlLister.Width, pnlLister.Height, 0);
111 | }
112 |
113 | bool IMessageFilter.PreFilterMessage(ref Message m)
114 | {
115 | if (m.Msg == NativeConstants.WM_KEYDOWN && WindowUtils.IsChildWindow(m.HWnd, Handle))
116 | {
117 | if (m.WParam.ToInt32() == _settings.SearchDialogKey3)
118 | {
119 | var key1 = true;
120 | var key2 = true;
121 |
122 | if ((VirtualKeyModifier)_settings.SearchDialogKey1 != VirtualKeyModifier.None)
123 | {
124 | int key1State = NativeMethods.GetAsyncKeyState(_settings.SearchDialogKey1) & 0x8000;
125 | key1 = Convert.ToBoolean(key1State);
126 | }
127 |
128 | if ((VirtualKeyModifier)_settings.SearchDialogKey2 != VirtualKeyModifier.None)
129 | {
130 | int key2State = NativeMethods.GetAsyncKeyState(_settings.SearchDialogKey2) & 0x8000;
131 | key2 = Convert.ToBoolean(key2State);
132 | }
133 |
134 | if (key1 && key2)
135 | {
136 | if (!_plugin.ListSearchDialogExist && !_plugin.ListSearchTextExist)
137 | {
138 | MessageBox.Show("This plugin does not support text search!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
139 | }
140 | else
141 | if (_plugin.ListSearchDialogExist)
142 | {
143 | _plugin.ListSearchDialog(_pluginHandle, 0);
144 | }
145 | else
146 | {
147 | var searchDlg = new SearchForm();
148 | var result = searchDlg.ShowDialog(this);
149 | if (result == DialogResult.OK)
150 | {
151 | var flags = 0;
152 | flags |= SearchForm.SearchFromBeginning ? NativeConstants.LCS_FINDFIRST : 0;
153 | flags |= SearchForm.SearchCaseSensitive ? NativeConstants.LCS_MATCHCASE : 0;
154 | flags |= SearchForm.SearchWholeWordsOnly ? NativeConstants.LCS_WHOLEWORDS : 0;
155 | flags |= SearchForm.SearchBackwards ? NativeConstants.LCS_BACKWARDS : 0;
156 | _plugin.ListSearchText(_pluginHandle, SearchForm.SearchingText, flags);
157 | }
158 | }
159 | }
160 | }
161 |
162 | if (m.WParam.ToInt32() == _settings.PrintDialogKey3)
163 | {
164 | var key1 = true;
165 | var key2 = true;
166 |
167 | if ((VirtualKeyModifier)_settings.PrintDialogKey1 != VirtualKeyModifier.None)
168 | {
169 | int key1State = NativeMethods.GetAsyncKeyState(_settings.PrintDialogKey1) & 0x8000;
170 | key1 = Convert.ToBoolean(key1State);
171 | }
172 |
173 | if ((VirtualKeyModifier)_settings.PrintDialogKey2 != VirtualKeyModifier.None)
174 | {
175 | int key2State = NativeMethods.GetAsyncKeyState(_settings.PrintDialogKey2) & 0x8000;
176 | key2 = Convert.ToBoolean(key2State);
177 | }
178 |
179 | if (key1 && key2)
180 | {
181 | if (!_plugin.ListPrintExist)
182 | {
183 | MessageBox.Show("This plugin does not support printing!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
184 | }
185 | else
186 | {
187 | Rect rectangle = null;
188 | PrinterSettings printerSettings = new PrinterSettings();
189 | _plugin.ListPrint(_pluginHandle, _fileName, printerSettings.PrinterName, 0, ref rectangle);
190 | }
191 | }
192 | }
193 |
194 | if (m.WParam.ToInt32() == (int)VirtualKey.VK_F3)
195 | {
196 | if (_plugin.ListSearchTextExist && !string.IsNullOrEmpty(SearchForm.SearchingText))
197 | {
198 | var flags = 0;
199 | flags |= SearchForm.SearchFromBeginning ? NativeConstants.LCS_FINDFIRST : 0;
200 | flags |= SearchForm.SearchCaseSensitive ? NativeConstants.LCS_MATCHCASE : 0;
201 | flags |= SearchForm.SearchWholeWordsOnly ? NativeConstants.LCS_WHOLEWORDS : 0;
202 | flags |= SearchForm.SearchBackwards ? NativeConstants.LCS_BACKWARDS : 0;
203 | _plugin.ListSearchText(_pluginHandle, SearchForm.SearchingText, flags);
204 | }
205 | }
206 |
207 | if (m.WParam.ToInt32() == (int)VirtualKey.VK_ESCAPE)
208 | {
209 | Close();
210 | }
211 | }
212 |
213 | return false;
214 | }
215 | }
216 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Forms
2 | {
3 | partial class MainForm
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.components = new System.ComponentModel.Container();
32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
33 | this.miStartStop = new System.Windows.Forms.ToolStripMenuItem();
34 | this.miSettings = new System.Windows.Forms.ToolStripMenuItem();
35 | this.miAbout = new System.Windows.Forms.ToolStripMenuItem();
36 | this.miSeparator = new System.Windows.Forms.ToolStripSeparator();
37 | this.miExit = new System.Windows.Forms.ToolStripMenuItem();
38 | this.iconSystemTray = new System.Windows.Forms.NotifyIcon(this.components);
39 | this.menuSystemTray = new System.Windows.Forms.ContextMenuStrip(this.components);
40 | this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
41 | this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
42 | this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
43 | this.menuSystemTray.SuspendLayout();
44 | this.SuspendLayout();
45 | //
46 | // miStartStop
47 | //
48 | this.miStartStop.Image = global::Wlx2Explorer.Properties.Resources.Start;
49 | this.miStartStop.Name = "miStartStop";
50 | this.miStartStop.Size = new System.Drawing.Size(125, 22);
51 | this.miStartStop.Text = "Stop";
52 | this.miStartStop.Click += new System.EventHandler(this.MenuItemStartStopClick);
53 | //
54 | // miSettings
55 | //
56 | this.miSettings.Name = "miSettings";
57 | this.miSettings.Size = new System.Drawing.Size(125, 22);
58 | this.miSettings.Text = "Settings...";
59 | this.miSettings.Click += new System.EventHandler(this.MenuItemSettingsClick);
60 | //
61 | // miAbout
62 | //
63 | this.miAbout.Name = "miAbout";
64 | this.miAbout.Size = new System.Drawing.Size(125, 22);
65 | this.miAbout.Text = "About";
66 | this.miAbout.Click += new System.EventHandler(this.MenuItemAboutClick);
67 | //
68 | // miSeparator
69 | //
70 | this.miSeparator.Name = "miSeparator";
71 | this.miSeparator.Size = new System.Drawing.Size(122, 6);
72 | //
73 | // miExit
74 | //
75 | this.miExit.Name = "miExit";
76 | this.miExit.Size = new System.Drawing.Size(125, 22);
77 | this.miExit.Text = "Exit";
78 | this.miExit.Click += new System.EventHandler(this.MenuItemExitClick);
79 | //
80 | // iconSystemTray
81 | //
82 | this.iconSystemTray.ContextMenuStrip = this.menuSystemTray;
83 | this.iconSystemTray.Icon = ((System.Drawing.Icon)(resources.GetObject("iconSystemTray.Icon")));
84 | this.iconSystemTray.Visible = true;
85 | //
86 | // menuSystemTray
87 | //
88 | this.menuSystemTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
89 | this.miStartStop,
90 | this.miSettings,
91 | this.miAbout,
92 | this.miSeparator,
93 | this.miExit});
94 | this.menuSystemTray.Name = "menuSystemTray";
95 | this.menuSystemTray.Size = new System.Drawing.Size(126, 98);
96 | //
97 | // toolStripMenuItem1
98 | //
99 | this.toolStripMenuItem1.Name = "toolStripMenuItem1";
100 | this.toolStripMenuItem1.Size = new System.Drawing.Size(32, 19);
101 | //
102 | // toolStripMenuItem2
103 | //
104 | this.toolStripMenuItem2.Name = "toolStripMenuItem2";
105 | this.toolStripMenuItem2.Size = new System.Drawing.Size(32, 19);
106 | //
107 | // toolStripMenuItem3
108 | //
109 | this.toolStripMenuItem3.Name = "toolStripMenuItem3";
110 | this.toolStripMenuItem3.Size = new System.Drawing.Size(32, 19);
111 | //
112 | // MainForm
113 | //
114 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
115 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
116 | this.ClientSize = new System.Drawing.Size(364, 147);
117 | this.Name = "MainForm";
118 | this.Opacity = 0D;
119 | this.ShowInTaskbar = false;
120 | this.Text = "Wlx2Explorer";
121 | this.menuSystemTray.ResumeLayout(false);
122 | this.ResumeLayout(false);
123 |
124 | }
125 |
126 | #endregion
127 |
128 | private System.Windows.Forms.NotifyIcon iconSystemTray;
129 | private System.Windows.Forms.ToolStripMenuItem miStartStop;
130 | private System.Windows.Forms.ToolStripMenuItem miSettings;
131 | private System.Windows.Forms.ToolStripMenuItem miAbout;
132 | private System.Windows.Forms.ToolStripSeparator miSeparator;
133 | private System.Windows.Forms.ToolStripMenuItem miExit;
134 | private System.Windows.Forms.ContextMenuStrip menuSystemTray;
135 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
136 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2;
137 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3;
138 |
139 | }
140 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/MainForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Windows.Forms;
5 | using Wlx2Explorer.Utils;
6 | using Wlx2Explorer.Settings;
7 | using Wlx2Explorer.Native;
8 | using Wlx2Explorer.Hooks;
9 |
10 | namespace Wlx2Explorer.Forms
11 | {
12 | partial class MainForm : Form
13 | {
14 | private IList _plugins;
15 | private KeyboardHook _keyboardKook;
16 | private ProgramSettings _settings;
17 | private ListerForm _listerForm;
18 | private AboutForm _aboutForm;
19 | private ProgramSettingsForm _settingsForm;
20 | private bool _isProgramStarted;
21 |
22 | public MainForm()
23 | {
24 | InitializeComponent();
25 | iconSystemTray.Text = AssemblyUtils.AssemblyTitle;
26 |
27 | Start();
28 | ChangeMenuStartStopText();
29 | }
30 |
31 | protected override void OnLoad(EventArgs e)
32 | {
33 | BeginInvoke(new Action(Hide));
34 | base.OnLoad(e);
35 | }
36 |
37 | private void Start()
38 | {
39 | Environment.CurrentDirectory = AssemblyUtils.AssemblyDirectory;
40 | _isProgramStarted = false;
41 | try
42 | {
43 | _settings = ProgramSettings.Read();
44 | }
45 | catch
46 | {
47 | MessageBox.Show("Failed to read a program setting file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
48 | return;
49 | }
50 |
51 | if (_listerForm != null && _listerForm.IsHandleCreated)
52 | {
53 | _listerForm.Close();
54 | }
55 |
56 | _plugins = _plugins ?? new List();
57 | foreach (var plugin in _plugins)
58 | {
59 | try
60 | {
61 | plugin.UnloadModule();
62 | }
63 | catch
64 | {
65 | var message = $@"Failed to unload a plugin ""{plugin.ModuleName}"".";
66 | MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
67 | }
68 | }
69 | _plugins.Clear();
70 |
71 | foreach (var pluginInfo in _settings.Plugins)
72 | {
73 | var plugin = new Plugin(pluginInfo.Path);
74 | var pluginLoaded = false;
75 | var pluginInitialized = true;
76 |
77 | try
78 | {
79 | pluginLoaded = plugin.LoadModule();
80 | }
81 | catch
82 | {
83 | pluginLoaded = false;
84 | }
85 |
86 | try
87 | {
88 | if (plugin.ListSetDefaultParamsExist)
89 | {
90 | var pluginExtension = Path.GetExtension(pluginInfo.Path);
91 | var pluginIniFile = Path.GetFullPath(pluginInfo.Path).Replace(pluginExtension, ".ini");
92 | if (!File.Exists(pluginIniFile))
93 | {
94 | plugin.ListSetDefaultParams(_settings.PluginLowVersion, _settings.PluginHighVersion, _settings.PluginIniFile);
95 | }
96 | }
97 | }
98 | catch
99 | {
100 | pluginInitialized = false;
101 | }
102 |
103 | if (pluginLoaded && pluginInitialized)
104 | {
105 | _plugins.Add(plugin);
106 | }
107 | else
108 | if (!pluginLoaded)
109 | {
110 | MessageBox.Show($@"Failed to load the plugin {Environment.NewLine} ""{pluginInfo.Path}"".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
111 | }
112 | else
113 | {
114 | MessageBox.Show($@"Failed to initialize the plugin with default settings {Environment.NewLine} ""{pluginInfo.Path}"".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
115 | }
116 | }
117 |
118 | try
119 | {
120 | _keyboardKook = _keyboardKook ?? new KeyboardHook();
121 | _keyboardKook.Stop();
122 | _keyboardKook.Hooked -= KeyHooked;
123 | _keyboardKook.Hooked += KeyHooked;
124 | bool result = _keyboardKook.Start(_settings.ListerFormKey1, _settings.ListerFormKey2, _settings.ListerFormKey3);
125 | if (!result) throw new Exception("Failed to run a keyboard hook.");
126 | _isProgramStarted = true;
127 | }
128 | catch (Exception ex)
129 | {
130 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
131 | }
132 | }
133 |
134 | private void Stop()
135 | {
136 | if (_listerForm != null && _listerForm.IsHandleCreated)
137 | {
138 | _listerForm.Close();
139 | }
140 |
141 | _plugins = _plugins ?? new List();
142 | foreach (var plugin in _plugins)
143 | {
144 | try
145 | {
146 | plugin.UnloadModule();
147 | }
148 | catch
149 | {
150 | MessageBox.Show($@"Failed to unload a plugin ""{ plugin.ModuleName}"".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
151 | }
152 | }
153 | _plugins.Clear();
154 | _keyboardKook = _keyboardKook ?? new KeyboardHook();
155 | _keyboardKook.Stop();
156 | _keyboardKook.Hooked -= KeyHooked;
157 | _isProgramStarted = false;
158 | }
159 |
160 | private void KeyHooked(object sender, EventArgs e)
161 | {
162 | if (InvokeRequired)
163 | {
164 | Invoke(new Action(ShowListerForm));
165 | }
166 | else
167 | {
168 | ShowListerForm();
169 | }
170 | }
171 |
172 | private void ShowListerForm()
173 | {
174 | var fileName = (string)null;
175 | try
176 | {
177 | fileName = WindowUtils.GetSelectedFileFromDesktopOrExplorer();
178 | }
179 | catch (Exception e)
180 | {
181 | MessageBox.Show($"Failed to get selected file. {e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
182 | return;
183 | }
184 |
185 | Environment.CurrentDirectory = AssemblyUtils.AssemblyDirectory;
186 |
187 | if (_listerForm != null && _listerForm.IsHandleCreated)
188 | {
189 | _listerForm.Close();
190 | }
191 |
192 | if (_listerForm == null || _listerForm.IsDisposed)
193 | {
194 | _listerForm = new ListerForm(_settings, _plugins, fileName);
195 | }
196 |
197 | if (_listerForm.IsDisposed)
198 | {
199 | _listerForm = null;
200 | }
201 | else
202 | {
203 | var hwnd = NativeMethods.GetForegroundWindow();
204 | var className = WindowUtils.GetClassName(hwnd);
205 | if (className == "WorkerW" || className == "Progman")
206 | {
207 | _listerForm.Show();
208 | }
209 | else
210 | {
211 | _listerForm.Show(new Win32WindowWrapper(hwnd));
212 | }
213 | _listerForm.Activate();
214 | }
215 | }
216 |
217 | private void MenuItemStartStopClick(object sender, EventArgs e)
218 | {
219 | if (_isProgramStarted)
220 | {
221 | Stop();
222 | }
223 | else
224 | {
225 | Start();
226 | }
227 | ChangeMenuStartStopText();
228 | }
229 |
230 | private void MenuItemSettingsClick(object sender, EventArgs e)
231 | {
232 | if (_settingsForm == null || _settingsForm.IsDisposed || !_settingsForm.IsHandleCreated)
233 | {
234 | if (_settings != null)
235 | {
236 | _settings.AutoStartProgram = StartUpManager.IsInStartup(AssemblyUtils.AssemblyProductName, AssemblyUtils.AssemblyLocation);
237 | }
238 | Environment.CurrentDirectory = AssemblyUtils.AssemblyDirectory;
239 | _settingsForm = new ProgramSettingsForm(_settings);
240 | }
241 |
242 | if (!_settingsForm.Visible)
243 | {
244 | DialogResult result = _settingsForm.ShowDialog();
245 | if (result == DialogResult.OK)
246 | {
247 | try
248 | {
249 | ProgramSettings.Write(_settingsForm.Settings);
250 | }
251 | catch
252 | {
253 | MessageBox.Show("Failed to save program settings.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
254 | return;
255 | }
256 | if (_settingsForm.Settings.AutoStartProgram)
257 | {
258 | StartUpManager.AddToStartup(AssemblyUtils.AssemblyProductName, AssemblyUtils.AssemblyLocation);
259 | }
260 | else
261 | if (StartUpManager.IsInStartup(AssemblyUtils.AssemblyProductName, AssemblyUtils.AssemblyLocation))
262 | {
263 | StartUpManager.RemoveFromStartup(AssemblyUtils.AssemblyProductName);
264 | }
265 | Stop();
266 | Start();
267 | }
268 | }
269 | }
270 |
271 | private void MenuItemAboutClick(object sender, EventArgs e)
272 | {
273 | if (_aboutForm == null || _aboutForm.IsDisposed || !_aboutForm.IsHandleCreated)
274 | {
275 | _aboutForm = new AboutForm();
276 | }
277 | _aboutForm.Show();
278 | _aboutForm.Activate();
279 | }
280 |
281 | private void MenuItemExitClick(object sender, EventArgs e)
282 | {
283 | Close();
284 | }
285 |
286 | private void ChangeMenuStartStopText()
287 | {
288 | if (_isProgramStarted)
289 | {
290 | miStartStop.Image = Properties.Resources.Stop;
291 | miStartStop.Text = "Stop";
292 | }
293 | else
294 | {
295 | miStartStop.Image = Properties.Resources.Start;
296 | miStartStop.Text = "Start";
297 | }
298 | }
299 | }
300 | }
301 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/MainForm.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 46, 17
122 |
123 |
124 | 162, 16
125 |
126 |
127 |
128 |
129 | AAABAAEACxAAAAEAIAAoAwAAFgAAACgAAAALAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
130 | AAD///8A////AAD//wFQj68Q////AAAAAAF6WZhFb1bN1qI2EqoiZnEtAAAAEP///wBbl7URa8bc6k2P
131 | orJdSImaSD/Q+AkJ8f9VUff/oWJK/1XP6/+DtcXibrnQQX3X6vx94vj/SnvB/wwMzv9iYt7/y8vt/+HW
132 | 6/+kZU7/W9Hs/67V4P94zN/xjef6/4Pk+f9pnMn/u7vO/7q63v/IyO3/7OHp/6ZmTv9h0+3/s+by/3fL
133 | 3PeT6vv/ieb5/4CyzP+5uc7/wMDe/8zM7f/s4en/p2dO/2fV7v+25/L/esze95js+/+P6fr/gbvU/7Ky
134 | zv/Jyd7/zMzt/+LW5/+pZ0//btfv/4TJ2rh7zt72nu/8/5Xr+/+X0eX/sLDO/87Fzf/PlH//w04o/6to
135 | T/922vD/bL/WU3/R4fWj8f3/m+78/6DW4/+taFL/nEEl/5VdTP++PRP/rGhP/3zc8f91y+FLgtLl9an0
136 | /v+h8P3/nsvW/29aVv+dTTT/jFxN/749E/+talD/gt7y/3zO5EuD1Ob1r/b//6fz/v+g0t7/jYqK/5tM
137 | Mv+FU0X/vkAa/5qopf+I4PP/gNXoS4PV5vWx9///rfX+/67c5/+MiYn/gVFC/4p6c/+R0dv/jOL0/47i
138 | 9P+F1e9Lg9Xo9bH3//+y9///td3n/3x8ev+FxND/jNbl/5Pi8/+S5Pb/k+T1/4jb70uD1ej1sff//7L3
139 | //+45u//fLvI/4XI1v+R2ej/meb2/5jm9/+Y5vb/jdrvSoPV6PWy9///vfj//57R3f+Fx9X/ld/u/5rn
140 | 9/+b5/f/pur4+5/l9bZ///8EhNbo9bv1/f+d0d3/ld3r/6fq+POo6vi+pun4gabp9jeZzP8F////AP//
141 | /wCk3uvhq+LtxKXn9m6k7PkmAP//Af///wD///8A////AP///wD///8A////AP5gAADAAAAAgAAAAAAA
142 | AAAAAAAAAAAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAAeAAAD/gAAA=
143 |
144 |
145 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/MessageBoxForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Forms
2 | {
3 | partial class MessageBoxForm
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.btnOk = new System.Windows.Forms.Button();
32 | this.txtMessage = new System.Windows.Forms.TextBox();
33 | this.SuspendLayout();
34 | //
35 | // btnOk
36 | //
37 | this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
38 | this.btnOk.Location = new System.Drawing.Point(431, 137);
39 | this.btnOk.Name = "btnOk";
40 | this.btnOk.Size = new System.Drawing.Size(115, 30);
41 | this.btnOk.TabIndex = 0;
42 | this.btnOk.Text = "Ok";
43 | this.btnOk.UseVisualStyleBackColor = true;
44 | this.btnOk.Click += new System.EventHandler(this.OkClick);
45 | //
46 | // txtMessage
47 | //
48 | this.txtMessage.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
49 | | System.Windows.Forms.AnchorStyles.Left)
50 | | System.Windows.Forms.AnchorStyles.Right)));
51 | this.txtMessage.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
52 | this.txtMessage.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
53 | this.txtMessage.Location = new System.Drawing.Point(12, 12);
54 | this.txtMessage.Multiline = true;
55 | this.txtMessage.Name = "txtMessage";
56 | this.txtMessage.ReadOnly = true;
57 | this.txtMessage.Size = new System.Drawing.Size(534, 107);
58 | this.txtMessage.TabIndex = 1;
59 | this.txtMessage.TabStop = false;
60 | //
61 | // MessageBoxForm
62 | //
63 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
64 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
65 | this.AutoSize = true;
66 | this.ClientSize = new System.Drawing.Size(558, 201);
67 | this.Controls.Add(this.txtMessage);
68 | this.Controls.Add(this.btnOk);
69 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
70 | this.KeyPreview = true;
71 | this.MaximizeBox = false;
72 | this.MinimizeBox = false;
73 | this.Name = "MessageBoxForm";
74 | this.ShowIcon = false;
75 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
76 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormKeyDown);
77 | this.ResumeLayout(false);
78 | this.PerformLayout();
79 |
80 | }
81 |
82 | #endregion
83 | private System.Windows.Forms.Button btnOk;
84 | private System.Windows.Forms.TextBox txtMessage;
85 | }
86 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/MessageBoxForm.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace Wlx2Explorer.Forms
4 | {
5 | public partial class MessageBoxForm : Form
6 | {
7 | public string Message
8 | {
9 | get
10 | {
11 | return txtMessage.Text;
12 | }
13 | set
14 | {
15 | txtMessage.Text = value;
16 | }
17 | }
18 |
19 | public MessageBoxForm()
20 | {
21 | InitializeComponent();
22 | }
23 |
24 | private void OkClick(object sender, System.EventArgs e)
25 | {
26 | Close();
27 | }
28 |
29 | private void FormKeyDown(object sender, KeyEventArgs e)
30 | {
31 | if (e.KeyValue == 13 || e.KeyValue == 27)
32 | {
33 | Close();
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/MessageBoxForm.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/PluginSettingsForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Forms
2 | {
3 | partial class PluginSettingsForm
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.txtFileName = new System.Windows.Forms.TextBox();
32 | this.btnBrowse = new System.Windows.Forms.Button();
33 | this.txtExtensions = new System.Windows.Forms.TextBox();
34 | this.lblFileName = new System.Windows.Forms.Label();
35 | this.lblExtensions = new System.Windows.Forms.Label();
36 | this.btnOk = new System.Windows.Forms.Button();
37 | this.btnCancel = new System.Windows.Forms.Button();
38 | this.SuspendLayout();
39 | //
40 | // txtFileName
41 | //
42 | this.txtFileName.Location = new System.Drawing.Point(12, 30);
43 | this.txtFileName.Name = "txtFileName";
44 | this.txtFileName.Size = new System.Drawing.Size(426, 20);
45 | this.txtFileName.TabIndex = 1;
46 | //
47 | // btnBrowse
48 | //
49 | this.btnBrowse.Location = new System.Drawing.Point(444, 29);
50 | this.btnBrowse.Name = "btnBrowse";
51 | this.btnBrowse.Size = new System.Drawing.Size(43, 22);
52 | this.btnBrowse.TabIndex = 2;
53 | this.btnBrowse.Text = "...";
54 | this.btnBrowse.UseVisualStyleBackColor = true;
55 | this.btnBrowse.Click += new System.EventHandler(this.BrowseClick);
56 | //
57 | // txtExtensions
58 | //
59 | this.txtExtensions.Location = new System.Drawing.Point(12, 93);
60 | this.txtExtensions.Name = "txtExtensions";
61 | this.txtExtensions.Size = new System.Drawing.Size(474, 20);
62 | this.txtExtensions.TabIndex = 4;
63 | //
64 | // lblFileName
65 | //
66 | this.lblFileName.AutoSize = true;
67 | this.lblFileName.Location = new System.Drawing.Point(13, 13);
68 | this.lblFileName.Name = "lblFileName";
69 | this.lblFileName.Size = new System.Drawing.Size(58, 13);
70 | this.lblFileName.TabIndex = 0;
71 | this.lblFileName.Text = "Plugin File:";
72 | //
73 | // lblExtensions
74 | //
75 | this.lblExtensions.AutoSize = true;
76 | this.lblExtensions.Location = new System.Drawing.Point(13, 77);
77 | this.lblExtensions.Name = "lblExtensions";
78 | this.lblExtensions.Size = new System.Drawing.Size(113, 13);
79 | this.lblExtensions.TabIndex = 3;
80 | this.lblExtensions.Text = "Supported Extensions:";
81 | //
82 | // btnOk
83 | //
84 | this.btnOk.Location = new System.Drawing.Point(352, 131);
85 | this.btnOk.Name = "btnOk";
86 | this.btnOk.Size = new System.Drawing.Size(64, 23);
87 | this.btnOk.TabIndex = 5;
88 | this.btnOk.Text = "Ok";
89 | this.btnOk.UseVisualStyleBackColor = true;
90 | this.btnOk.Click += new System.EventHandler(this.OkClick);
91 | //
92 | // btnCancel
93 | //
94 | this.btnCancel.Location = new System.Drawing.Point(422, 131);
95 | this.btnCancel.Name = "btnCancel";
96 | this.btnCancel.Size = new System.Drawing.Size(64, 23);
97 | this.btnCancel.TabIndex = 6;
98 | this.btnCancel.Text = "Cancel";
99 | this.btnCancel.UseVisualStyleBackColor = true;
100 | this.btnCancel.Click += new System.EventHandler(this.CancelClick);
101 | //
102 | // PluginSettingsForm
103 | //
104 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
105 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
106 | this.ClientSize = new System.Drawing.Size(498, 168);
107 | this.Controls.Add(this.btnCancel);
108 | this.Controls.Add(this.btnOk);
109 | this.Controls.Add(this.lblExtensions);
110 | this.Controls.Add(this.lblFileName);
111 | this.Controls.Add(this.txtExtensions);
112 | this.Controls.Add(this.btnBrowse);
113 | this.Controls.Add(this.txtFileName);
114 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
115 | this.KeyPreview = true;
116 | this.MaximizeBox = false;
117 | this.MinimizeBox = false;
118 | this.Name = "PluginSettingsForm";
119 | this.ShowInTaskbar = false;
120 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
121 | this.Text = "Plugin Settings";
122 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormKeyDown);
123 | this.ResumeLayout(false);
124 | this.PerformLayout();
125 |
126 | }
127 |
128 | #endregion
129 |
130 | private System.Windows.Forms.TextBox txtFileName;
131 | private System.Windows.Forms.Button btnBrowse;
132 | private System.Windows.Forms.TextBox txtExtensions;
133 | private System.Windows.Forms.Label lblFileName;
134 | private System.Windows.Forms.Label lblExtensions;
135 | private System.Windows.Forms.Button btnOk;
136 | private System.Windows.Forms.Button btnCancel;
137 | }
138 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/PluginSettingsForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Windows.Forms;
4 | using Wlx2Explorer.Utils;
5 |
6 | namespace Wlx2Explorer.Forms
7 | {
8 | partial class PluginSettingsForm : Form
9 | {
10 | public string FileName { get { return txtFileName.Text; } }
11 |
12 | public string Extensions { get { return txtExtensions.Text; } }
13 |
14 | public PluginSettingsForm(string fileName, string extensions)
15 | {
16 | InitializeComponent();
17 |
18 | fileName = Path.IsPathRooted(fileName) ? fileName : Path.Combine(AssemblyUtils.AssemblyDirectory, fileName);
19 | txtFileName.Text = fileName;
20 | txtExtensions.Text = extensions;
21 | }
22 |
23 | private void BrowseClick(object sender, EventArgs e)
24 | {
25 | var dialog = new OpenFileDialog()
26 | {
27 | RestoreDirectory = true,
28 | Filter = "Plugin files (*.wlx;*.wlx64)|*.wlx;*.wlx64|All files (*.*)|*.*"
29 | };
30 |
31 | if (File.Exists(txtFileName.Text))
32 | {
33 | dialog.InitialDirectory = Path.GetDirectoryName(txtFileName.Text);
34 | }
35 |
36 | if (dialog.ShowDialog() == DialogResult.OK)
37 | {
38 | txtFileName.Text = dialog.FileName;
39 | txtExtensions.Text = string.Join(";", Plugin.GetSupportedExtensions(dialog.FileName));
40 | }
41 | }
42 |
43 | private void OkClick(object sender, EventArgs e)
44 | {
45 | if (!File.Exists(txtFileName.Text))
46 | {
47 | MessageBox.Show("You should select an existing file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
48 | return;
49 | }
50 |
51 | try
52 | {
53 | txtExtensions.Text.Split(';');
54 | }
55 | catch
56 | {
57 | MessageBox.Show("Extensions must be separated by semicolons.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
58 | return;
59 | }
60 |
61 | DialogResult = DialogResult.OK;
62 | Close();
63 | }
64 |
65 | private void CancelClick(object sender, EventArgs e)
66 | {
67 | DialogResult = DialogResult.Cancel;
68 | Close();
69 | }
70 |
71 | private void FormKeyDown(object sender, KeyEventArgs e)
72 | {
73 | if (e.KeyValue == 27)
74 | {
75 | CancelClick(sender, (EventArgs)e);
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/PluginSettingsForm.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/ProgramSettingsForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using System.Linq;
4 | using System.IO;
5 | using System.Windows.Forms;
6 | using Wlx2Explorer.Settings;
7 | using Wlx2Explorer.Utils;
8 | using Wlx2Explorer.Extensions;
9 | using Wlx2Explorer.Hooks;
10 |
11 | namespace Wlx2Explorer.Forms
12 | {
13 | partial class ProgramSettingsForm : Form
14 | {
15 | public ProgramSettings Settings { get; private set; }
16 |
17 | public ProgramSettingsForm(ProgramSettings settings)
18 | {
19 | InitializeComponent();
20 | try
21 | {
22 | InitializeControls(settings);
23 | }
24 | catch
25 | {
26 | tabMain.Enabled = false;
27 | btnOk.Enabled = false;
28 | MessageBox.Show("Failed to read settings.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
29 | }
30 | }
31 |
32 | private void InitializeControls(ProgramSettings settings)
33 | {
34 | chbAutoStart.Checked = settings.AutoStartProgram;
35 | chbListerMaximized.Checked = settings.ListerFormMaximized;
36 | txtListerWidth.Text = settings.ListerFormWidth.ToString();
37 | txtListerHeight.Text = settings.ListerFormHeight.ToString();
38 | txtHighVersion.Text = settings.PluginHighVersion.ToString();
39 | txtLowVersion.Text = settings.PluginLowVersion.ToString();
40 | txtIniFile.Text = settings.PluginIniFile;
41 | if (settings.PluginIniFile.StartsWith(AssemblyUtils.AssemblyDirectory, StringComparison.InvariantCultureIgnoreCase))
42 | {
43 | txtIniFile.Text = settings.PluginIniFile.Substring(AssemblyUtils.AssemblyDirectory.Length).TrimStart('\\');
44 | }
45 |
46 | cmbListerFormKey1.DataSource = Enum.GetValues(typeof(VirtualKeyModifier));
47 | cmbListerFormKey1.SelectedItem = (VirtualKeyModifier)settings.ListerFormKey1;
48 | cmbListerFormKey2.DataSource = Enum.GetValues(typeof(VirtualKeyModifier));
49 | cmbListerFormKey2.SelectedItem = (VirtualKeyModifier)settings.ListerFormKey2;
50 | cmbListerFormKey3.ValueMember = "Id";
51 | cmbListerFormKey3.DisplayMember = "Text";
52 | cmbListerFormKey3.DataSource = ((VirtualKey[])Enum.GetValues(typeof(VirtualKey))).Where(x => !string.IsNullOrEmpty(x.GetDescription())).Select(x => new { Id = (int)x, Text = x.GetDescription() }).ToList();
53 | cmbListerFormKey3.SelectedValue = settings.ListerFormKey3;
54 | cmbSearchDialogKey1.DataSource = Enum.GetValues(typeof(VirtualKeyModifier));
55 | cmbSearchDialogKey1.SelectedItem = (VirtualKeyModifier)settings.SearchDialogKey1;
56 | cmbSearchDialogKey2.DataSource = Enum.GetValues(typeof(VirtualKeyModifier));
57 | cmbSearchDialogKey2.SelectedItem = (VirtualKeyModifier)settings.SearchDialogKey2;
58 | cmbSearchDialogKey3.ValueMember = "Id";
59 | cmbSearchDialogKey3.DisplayMember = "Text";
60 | cmbSearchDialogKey3.DataSource = ((VirtualKey[])Enum.GetValues(typeof(VirtualKey))).Where(x => !string.IsNullOrEmpty(x.GetDescription())).Select(x => new { Id = (int)x, Text = x.GetDescription() }).ToList();
61 | cmbSearchDialogKey3.SelectedValue = settings.SearchDialogKey3;
62 | cmbPrintDialogKey1.DataSource = Enum.GetValues(typeof(VirtualKeyModifier));
63 | cmbPrintDialogKey1.SelectedItem = (VirtualKeyModifier)settings.PrintDialogKey1;
64 | cmbPrintDialogKey2.DataSource = Enum.GetValues(typeof(VirtualKeyModifier));
65 | cmbPrintDialogKey2.SelectedItem = (VirtualKeyModifier)settings.PrintDialogKey2;
66 | cmbPrintDialogKey3.ValueMember = "Id";
67 | cmbPrintDialogKey3.DisplayMember = "Text";
68 | cmbPrintDialogKey3.DataSource = ((VirtualKey[])Enum.GetValues(typeof(VirtualKey))).Where(x => !string.IsNullOrEmpty(x.GetDescription())).Select(x => new { Id = (int)x, Text = x.GetDescription() }).ToList();
69 | cmbPrintDialogKey3.SelectedValue = settings.PrintDialogKey3;
70 |
71 | foreach (var plugin in settings.Plugins)
72 | {
73 | var fileName = plugin.Path;
74 | if (fileName.StartsWith(AssemblyUtils.AssemblyDirectory, StringComparison.InvariantCultureIgnoreCase))
75 | {
76 | fileName = fileName.Substring(AssemblyUtils.AssemblyDirectory.Length).TrimStart('\\');
77 | }
78 | var index = gridViewPlugin.Rows.Add();
79 | var row = gridViewPlugin.Rows[index];
80 | row.Cells[0].Value = fileName;
81 | row.Cells[1].Value = string.Join(";", plugin.Extensions.ToArray());
82 | }
83 | gridViewPlugin.Columns[0].Width = gridViewPlugin.ClientSize.Width - 100;
84 | gridViewPlugin.Columns[1].Width = 100;
85 | }
86 |
87 | private void MaximizeWindowCheckedChanged(object sender, EventArgs e)
88 | {
89 | var checkBox = (CheckBox)sender;
90 | lblWindowWidth.Enabled = !checkBox.Checked;
91 | lblWindowHeight.Enabled = !checkBox.Checked;
92 | txtListerWidth.Enabled = !checkBox.Checked;
93 | txtListerHeight.Enabled = !checkBox.Checked;
94 | if (!checkBox.Checked)
95 | {
96 | txtListerWidth.Focus();
97 | }
98 | }
99 |
100 | private void BrowseWincmdIniClick(object sender, EventArgs e)
101 | {
102 | var dialog = new OpenFileDialog()
103 | {
104 | RestoreDirectory = true,
105 | FileName = "wincmd.ini",
106 | Filter = "Ini files (*.ini)|*.ini;|All files (*.*)|*.*"
107 | };
108 | if (dialog.ShowDialog() == DialogResult.OK)
109 | {
110 | var file = new InitializationFile(dialog.FileName);
111 | try
112 | {
113 | file.LoadFile();
114 | }
115 | catch
116 | {
117 | MessageBox.Show("Failed to read the file. May be wrong ini file format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
118 | return;
119 | }
120 | var listerSection = file.GetSection("ListerPlugins");
121 | if (listerSection == null)
122 | {
123 | MessageBox.Show("This file does not contain [ListerPlugins] section.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
124 | return;
125 | }
126 | if (gridViewPlugin.Rows.Count > 0 &&
127 | MessageBox.Show("Do you want to clear the current list of the plugins.", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
128 | {
129 | gridViewPlugin.Rows.Clear();
130 | }
131 | foreach (var pair in listerSection)
132 | {
133 | var fileName = pair.Value;
134 | if (File.Exists(fileName))
135 | {
136 | var index = gridViewPlugin.Rows.Add();
137 | var row = gridViewPlugin.Rows[index];
138 | row.Cells[0].Value = fileName;
139 | row.Cells[1].Value = string.Join(";", Plugin.GetSupportedExtensions(fileName));
140 | gridViewPlugin.FirstDisplayedScrollingRowIndex = gridViewPlugin.RowCount - 1;
141 | gridViewPlugin.Rows[index].Selected = true;
142 | }
143 | }
144 | }
145 | }
146 |
147 | private void AddPluginClick(object sender, EventArgs e)
148 | {
149 | var dialog = new OpenFileDialog()
150 | {
151 | RestoreDirectory = true,
152 | Filter = "Plugin files (*.wlx;*.wlx64)|*.wlx;*.wlx64|All files (*.*)|*.*"
153 | };
154 | if (dialog.ShowDialog() == DialogResult.OK)
155 | {
156 | var fileName = dialog.FileName;
157 | if (fileName.StartsWith(AssemblyUtils.AssemblyDirectory, StringComparison.InvariantCultureIgnoreCase))
158 | {
159 | fileName = fileName.Substring(AssemblyUtils.AssemblyDirectory.Length).TrimStart('\\');
160 | }
161 | if (IsGridViewContainFile(fileName))
162 | {
163 | MessageBox.Show("The file already exists in the list.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
164 | return;
165 | }
166 | var index = gridViewPlugin.Rows.Add();
167 | var row = gridViewPlugin.Rows[index];
168 | row.Cells[0].Value = fileName;
169 | row.Cells[1].Value = string.Join(";", Plugin.GetSupportedExtensions(fileName));
170 | gridViewPlugin.FirstDisplayedScrollingRowIndex = gridViewPlugin.RowCount - 1;
171 | gridViewPlugin.Rows[index].Selected = true;
172 | }
173 | }
174 |
175 | private void DeletePluginClick(object sender, EventArgs e)
176 | {
177 | if (gridViewPlugin.SelectedRows.Count > 0)
178 | {
179 | var index = gridViewPlugin.SelectedRows[0].Index;
180 | gridViewPlugin.Rows.RemoveAt(index);
181 | index = (index < gridViewPlugin.Rows.Count) ? index : (gridViewPlugin.Rows.Count > 0) ? gridViewPlugin.Rows.Count - 1 : 0;
182 | if (gridViewPlugin.Rows.Count > 0)
183 | {
184 | gridViewPlugin.Rows[index].Selected = true;
185 | }
186 | }
187 | else
188 | {
189 | MessageBox.Show("You should select an item in the list.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
190 | }
191 | }
192 |
193 | private void EditPluginClick(object sender, EventArgs e)
194 | {
195 | if (gridViewPlugin.SelectedRows.Count > 0)
196 | {
197 | var row = gridViewPlugin.SelectedRows[0];
198 | var pluginSettingsForm = new PluginSettingsForm((string)row.Cells[0].Value, (string)row.Cells[1].Value);
199 | if (pluginSettingsForm.ShowDialog() == DialogResult.OK)
200 | {
201 | var fileName = pluginSettingsForm.FileName;
202 | var extensions = pluginSettingsForm.Extensions;
203 | if (fileName.StartsWith(AssemblyUtils.AssemblyDirectory, StringComparison.InvariantCultureIgnoreCase))
204 | {
205 | fileName = fileName.Substring(AssemblyUtils.AssemblyDirectory.Length).TrimStart('\\');
206 | }
207 | row.Cells[0].Value = fileName;
208 | row.Cells[1].Value = extensions;
209 | }
210 | }
211 | else
212 | {
213 | MessageBox.Show("You should select an item in the list.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
214 | }
215 | }
216 |
217 | private void DownPluginClick(object sender, EventArgs e)
218 | {
219 | if (gridViewPlugin.SelectedRows.Count > 0)
220 | {
221 | var index = gridViewPlugin.SelectedRows[0].Index;
222 | var newIndex = index < gridViewPlugin.Rows.Count - 1 ? index + 1 : gridViewPlugin.Rows.Count - 1;
223 | var selectedRow = gridViewPlugin.SelectedRows[0];
224 | gridViewPlugin.Rows.RemoveAt(index);
225 | gridViewPlugin.Rows.Insert(newIndex, selectedRow);
226 | gridViewPlugin.Rows[newIndex].Selected = true;
227 | }
228 | }
229 |
230 | private void UpPluginClick(object sender, EventArgs e)
231 | {
232 | if (gridViewPlugin.SelectedRows.Count > 0)
233 | {
234 | var index = gridViewPlugin.SelectedRows[0].Index;
235 | var newIndex = index > 0 ? index - 1 : 0;
236 | var selectedRow = gridViewPlugin.SelectedRows[0];
237 | gridViewPlugin.Rows.RemoveAt(index);
238 | gridViewPlugin.Rows.Insert(newIndex, selectedRow);
239 | gridViewPlugin.Rows[newIndex].Selected = true;
240 | }
241 | }
242 |
243 | private void PluginListDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
244 | {
245 | EditPluginClick(sender, (EventArgs)e);
246 | }
247 |
248 | private void OkClick(object sender, EventArgs e)
249 | {
250 | int listerWidth = 0;
251 | int listerHeight = 0;
252 | int highVersion = 0;
253 | int lowVersion = 0;
254 | string iniFile = "";
255 | DialogResult = DialogResult.Cancel;
256 |
257 | try
258 | {
259 | listerWidth = int.Parse(txtListerWidth.Text);
260 | }
261 | catch
262 | {
263 | MessageBox.Show("Window width must be an integer number.");
264 | Close();
265 | }
266 |
267 | try
268 | {
269 | listerHeight = int.Parse(txtListerHeight.Text);
270 | }
271 | catch
272 | {
273 | MessageBox.Show("Window height must be an integer number.");
274 | Close();
275 | }
276 |
277 | try
278 | {
279 | highVersion = int.Parse(txtHighVersion.Text);
280 | }
281 | catch
282 | {
283 | MessageBox.Show("The integral part of version must be an integer number.");
284 | Close();
285 | }
286 |
287 | try
288 | {
289 | lowVersion = int.Parse(txtLowVersion.Text);
290 | }
291 | catch
292 | {
293 | MessageBox.Show("The fractional part of version must be an integer number.");
294 | Close();
295 | }
296 |
297 | try
298 | {
299 | var fileInfo = new FileInfo(txtIniFile.Text);
300 | if (!fileInfo.Exists) fileInfo.Create().Close();
301 | iniFile = fileInfo.FullName;
302 | }
303 | catch
304 | {
305 | MessageBox.Show($"Failed to create the file \"{txtIniFile.Text}\"");
306 | Close();
307 | }
308 |
309 | Settings = new ProgramSettings()
310 | {
311 | AutoStartProgram = chbAutoStart.Checked,
312 | ListerFormMaximized = chbListerMaximized.Checked,
313 | ListerFormWidth = listerWidth,
314 | ListerFormHeight = listerHeight,
315 | PluginLowVersion = lowVersion,
316 | PluginHighVersion = highVersion,
317 | PluginIniFile = txtIniFile.Text,
318 | ListerFormKey1 = (int)cmbListerFormKey1.SelectedValue,
319 | ListerFormKey2 = (int)cmbListerFormKey2.SelectedValue,
320 | ListerFormKey3 = (int)cmbListerFormKey3.SelectedValue,
321 | SearchDialogKey1 = (int)cmbSearchDialogKey1.SelectedValue,
322 | SearchDialogKey2 = (int)cmbSearchDialogKey2.SelectedValue,
323 | SearchDialogKey3 = (int)cmbSearchDialogKey3.SelectedValue,
324 | PrintDialogKey1 = (int)cmbPrintDialogKey1.SelectedValue,
325 | PrintDialogKey2 = (int)cmbPrintDialogKey2.SelectedValue,
326 | PrintDialogKey3 = (int)cmbPrintDialogKey3.SelectedValue
327 | };
328 |
329 | foreach (DataGridViewRow row in gridViewPlugin.Rows)
330 | {
331 | var fileName = (string)row.Cells[0].Value;
332 | var extensions = ((string)row.Cells[1].Value).Split(';').ToList();
333 | var pluginInfo = new PluginInfo(fileName, extensions);
334 | Settings.Plugins.Add(pluginInfo);
335 | }
336 |
337 | DialogResult = DialogResult.OK;
338 | Close();
339 | }
340 |
341 | private void CancelClick(object sender, EventArgs e)
342 | {
343 | DialogResult = DialogResult.Cancel;
344 | Close();
345 | }
346 |
347 | private void FormKeyDown(object sender, KeyEventArgs e)
348 | {
349 | if (e.KeyValue == 27)
350 | {
351 | CancelClick(sender, (EventArgs)e);
352 | }
353 | }
354 |
355 | private bool IsGridViewContainFile(string fileName)
356 | {
357 | foreach (DataGridViewRow row in gridViewPlugin.Rows)
358 | {
359 | if (string.Compare((string)row.Cells[0].Value, fileName, true) == 0) return true;
360 | }
361 | return false;
362 | }
363 | }
364 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/ProgramSettingsForm.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | True
122 |
123 |
124 | True
125 |
126 |
127 | 17, 17
128 |
129 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/SearchForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Forms
2 | {
3 | partial class SearchForm
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.btnOk = new System.Windows.Forms.Button();
32 | this.btnCancel = new System.Windows.Forms.Button();
33 | this.txtSearchText = new System.Windows.Forms.TextBox();
34 | this.lblSearchText = new System.Windows.Forms.Label();
35 | this.chbWholeWordsOnly = new System.Windows.Forms.CheckBox();
36 | this.chbCaseSensitive = new System.Windows.Forms.CheckBox();
37 | this.chbSearchBackwards = new System.Windows.Forms.CheckBox();
38 | this.chbSearchFromBeginning = new System.Windows.Forms.CheckBox();
39 | this.SuspendLayout();
40 | //
41 | // btnOk
42 | //
43 | this.btnOk.Location = new System.Drawing.Point(208, 120);
44 | this.btnOk.Name = "btnOk";
45 | this.btnOk.Size = new System.Drawing.Size(75, 23);
46 | this.btnOk.TabIndex = 6;
47 | this.btnOk.Text = "Ok";
48 | this.btnOk.UseVisualStyleBackColor = true;
49 | this.btnOk.Click += new System.EventHandler(this.OkClick);
50 | //
51 | // btnCancel
52 | //
53 | this.btnCancel.Location = new System.Drawing.Point(289, 120);
54 | this.btnCancel.Name = "btnCancel";
55 | this.btnCancel.Size = new System.Drawing.Size(75, 23);
56 | this.btnCancel.TabIndex = 7;
57 | this.btnCancel.Text = "Cancel";
58 | this.btnCancel.UseVisualStyleBackColor = true;
59 | this.btnCancel.Click += new System.EventHandler(this.CancelClick);
60 | //
61 | // txtSearchText
62 | //
63 | this.txtSearchText.Location = new System.Drawing.Point(12, 31);
64 | this.txtSearchText.Name = "txtSearchText";
65 | this.txtSearchText.Size = new System.Drawing.Size(354, 20);
66 | this.txtSearchText.TabIndex = 1;
67 | //
68 | // lblSearchText
69 | //
70 | this.lblSearchText.AutoSize = true;
71 | this.lblSearchText.Location = new System.Drawing.Point(9, 15);
72 | this.lblSearchText.Name = "lblSearchText";
73 | this.lblSearchText.Size = new System.Drawing.Size(56, 13);
74 | this.lblSearchText.TabIndex = 0;
75 | this.lblSearchText.Text = "Find what:";
76 | //
77 | // chbWholeWordsOnly
78 | //
79 | this.chbWholeWordsOnly.AutoSize = true;
80 | this.chbWholeWordsOnly.Location = new System.Drawing.Point(12, 67);
81 | this.chbWholeWordsOnly.Name = "chbWholeWordsOnly";
82 | this.chbWholeWordsOnly.Size = new System.Drawing.Size(110, 17);
83 | this.chbWholeWordsOnly.TabIndex = 2;
84 | this.chbWholeWordsOnly.Text = "Whole words only";
85 | this.chbWholeWordsOnly.UseVisualStyleBackColor = true;
86 | //
87 | // chbCaseSensitive
88 | //
89 | this.chbCaseSensitive.AutoSize = true;
90 | this.chbCaseSensitive.Location = new System.Drawing.Point(12, 90);
91 | this.chbCaseSensitive.Name = "chbCaseSensitive";
92 | this.chbCaseSensitive.Size = new System.Drawing.Size(94, 17);
93 | this.chbCaseSensitive.TabIndex = 3;
94 | this.chbCaseSensitive.Text = "Case sensitive";
95 | this.chbCaseSensitive.UseVisualStyleBackColor = true;
96 | //
97 | // chbSearchBackwards
98 | //
99 | this.chbSearchBackwards.AutoSize = true;
100 | this.chbSearchBackwards.Location = new System.Drawing.Point(150, 90);
101 | this.chbSearchBackwards.Name = "chbSearchBackwards";
102 | this.chbSearchBackwards.Size = new System.Drawing.Size(115, 17);
103 | this.chbSearchBackwards.TabIndex = 5;
104 | this.chbSearchBackwards.Text = "Search backwards";
105 | this.chbSearchBackwards.UseVisualStyleBackColor = true;
106 | //
107 | // chbSearchFromBeginning
108 | //
109 | this.chbSearchFromBeginning.AutoSize = true;
110 | this.chbSearchFromBeginning.Location = new System.Drawing.Point(150, 67);
111 | this.chbSearchFromBeginning.Name = "chbSearchFromBeginning";
112 | this.chbSearchFromBeginning.Size = new System.Drawing.Size(150, 17);
113 | this.chbSearchFromBeginning.TabIndex = 4;
114 | this.chbSearchFromBeginning.Text = "Search from the beginning";
115 | this.chbSearchFromBeginning.UseVisualStyleBackColor = true;
116 | //
117 | // SearchForm
118 | //
119 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
120 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
121 | this.ClientSize = new System.Drawing.Size(376, 155);
122 | this.Controls.Add(this.chbSearchFromBeginning);
123 | this.Controls.Add(this.chbSearchBackwards);
124 | this.Controls.Add(this.chbCaseSensitive);
125 | this.Controls.Add(this.chbWholeWordsOnly);
126 | this.Controls.Add(this.lblSearchText);
127 | this.Controls.Add(this.txtSearchText);
128 | this.Controls.Add(this.btnCancel);
129 | this.Controls.Add(this.btnOk);
130 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
131 | this.KeyPreview = true;
132 | this.MaximizeBox = false;
133 | this.MinimizeBox = false;
134 | this.Name = "SearchForm";
135 | this.ShowInTaskbar = false;
136 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
137 | this.Text = "Search text";
138 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormKeyDown);
139 | this.ResumeLayout(false);
140 | this.PerformLayout();
141 |
142 | }
143 |
144 | #endregion
145 |
146 | private System.Windows.Forms.Button btnOk;
147 | private System.Windows.Forms.Button btnCancel;
148 | private System.Windows.Forms.TextBox txtSearchText;
149 | private System.Windows.Forms.Label lblSearchText;
150 | private System.Windows.Forms.CheckBox chbWholeWordsOnly;
151 | private System.Windows.Forms.CheckBox chbCaseSensitive;
152 | private System.Windows.Forms.CheckBox chbSearchBackwards;
153 | private System.Windows.Forms.CheckBox chbSearchFromBeginning;
154 | }
155 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/SearchForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Wlx2Explorer.Forms
5 | {
6 | partial class SearchForm : Form
7 | {
8 | public static string SearchingText { get; set; }
9 |
10 | public static bool SearchWholeWordsOnly { get; set; }
11 |
12 | public static bool SearchCaseSensitive { get; set; }
13 |
14 | public static bool SearchFromBeginning { get; set; }
15 |
16 | public static bool SearchBackwards { get; set; }
17 |
18 | static SearchForm()
19 | {
20 | SearchingText = "";
21 | SearchWholeWordsOnly = false;
22 | SearchCaseSensitive = false;
23 | SearchFromBeginning = false;
24 | SearchBackwards = false;
25 | }
26 |
27 | public SearchForm()
28 | {
29 | InitializeComponent();
30 |
31 | txtSearchText.Text = SearchingText;
32 | chbWholeWordsOnly.Checked = SearchWholeWordsOnly;
33 | chbCaseSensitive.Checked = SearchCaseSensitive;
34 | chbSearchFromBeginning.Checked = SearchFromBeginning;
35 | chbSearchBackwards.Checked = SearchBackwards;
36 | }
37 |
38 | private void OkClick(object sender, EventArgs e)
39 | {
40 | SearchingText = txtSearchText.Text;
41 | SearchWholeWordsOnly = chbWholeWordsOnly.Checked;
42 | SearchCaseSensitive = chbCaseSensitive.Checked;
43 | SearchFromBeginning = chbSearchFromBeginning.Checked;
44 | SearchBackwards = chbSearchBackwards.Checked;
45 |
46 | DialogResult = DialogResult.OK;
47 | Close();
48 | }
49 |
50 | private void CancelClick(object sender, EventArgs e)
51 | {
52 | DialogResult = DialogResult.Cancel;
53 | Close();
54 | }
55 |
56 | private void FormKeyDown(object sender, KeyEventArgs e)
57 | {
58 | switch (e.KeyValue)
59 | {
60 | case 13:
61 | {
62 | OkClick(sender, (EventArgs)e);
63 | } break;
64 |
65 | case 27:
66 | {
67 | CancelClick(sender, (EventArgs)e);
68 | } break;
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Forms/SearchForm.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Hooks/KeyboardHook.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using Wlx2Explorer.Native;
4 |
5 | namespace Wlx2Explorer.Hooks
6 | {
7 | class KeyboardHook
8 | {
9 | private IntPtr _hookHandle;
10 | private KeyboardHookProc _hookProc;
11 | private int _key1;
12 | private int _key2;
13 | private int _key3;
14 |
15 | public event EventHandler Hooked;
16 |
17 | public bool Start(int key1, int key2, int key3)
18 | {
19 | _key1 = key1;
20 | _key2 = key2;
21 | _key3 = key3;
22 | _hookProc = HookProc;
23 | using var currentProcess = Process.GetCurrentProcess();
24 | using var currentModule = currentProcess.MainModule;
25 | var moduleHandle = NativeMethods.GetModuleHandle(currentModule.ModuleName);
26 | _hookHandle = NativeMethods.SetWindowsHookEx(NativeConstants.WH_KEYBOARD_LL, _hookProc, moduleHandle, 0);
27 | var hookStarted = _hookHandle != IntPtr.Zero;
28 | return hookStarted;
29 | }
30 |
31 | public bool Stop()
32 | {
33 | if (_hookHandle == IntPtr.Zero)
34 | {
35 | return true;
36 | }
37 | var hookStoped = NativeMethods.UnhookWindowsHookEx(_hookHandle);
38 | return hookStoped;
39 | }
40 |
41 | private int HookProc(int code, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
42 | {
43 | if (code == NativeConstants.HC_ACTION)
44 | {
45 | if (wParam.ToInt32() == NativeConstants.WM_KEYDOWN || wParam.ToInt32() == NativeConstants.WM_SYSKEYDOWN)
46 | {
47 | var key1 = true;
48 | var key2 = true;
49 |
50 | if (_key1 != (int)VirtualKeyModifier.None)
51 | {
52 | var key1State = NativeMethods.GetAsyncKeyState(_key1) & 0x8000;
53 | key1 = Convert.ToBoolean(key1State);
54 | }
55 |
56 | if (_key2 != (int)VirtualKeyModifier.None)
57 | {
58 | var key2State = NativeMethods.GetAsyncKeyState(_key2) & 0x8000;
59 | key2 = Convert.ToBoolean(key2State);
60 | }
61 |
62 | if (key1 && key2 && lParam.vkCode == _key3)
63 | {
64 | var handler = Hooked;
65 | handler?.BeginInvoke(this, EventArgs.Empty, null, null);
66 | }
67 | }
68 | }
69 | return NativeMethods.CallNextHookEx(_hookHandle, code, wParam, ref lParam);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Hooks/VirtualKey.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace Wlx2Explorer.Hooks
4 | {
5 | enum VirtualKey : int
6 | {
7 | VK_LBUTTON = 0x01,
8 | VK_RBUTTON = 0x02,
9 | VK_CANCEL = 0x03,
10 | VK_MBUTTON = 0x04,
11 |
12 | [Description("BACKSPACE")]
13 | VK_BACK = 0x08,
14 |
15 | [Description("TAB")]
16 | VK_TAB = 0x09,
17 |
18 | VK_CLEAR = 0x0C,
19 | VK_RETURN = 0x0D,
20 | VK_SHIFT = 0x10,
21 | VK_CONTROL = 0x11,
22 | VK_MENU = 0x12,
23 |
24 | [Description("PAUSE")]
25 | VK_PAUSE = 0x13,
26 |
27 | [Description("CAPS LOCK")]
28 | VK_CAPITAL = 0x14,
29 |
30 | [Description("ESC")]
31 | VK_ESCAPE = 0x1B,
32 |
33 | [Description("SPACE")]
34 | VK_SPACE = 0x20,
35 |
36 | [Description("PAGE UP")]
37 | VK_PRIOR = 0x21,
38 |
39 | [Description("PAGE DOWN")]
40 | VK_NEXT = 0x22,
41 |
42 | [Description("END")]
43 | VK_END = 0x23,
44 |
45 | [Description("HOME")]
46 | VK_HOME = 0x24,
47 |
48 | [Description("LEFT ARROW")]
49 | VK_LEFT = 0x25,
50 |
51 | [Description("UP ARROW")]
52 | VK_UP = 0x26,
53 |
54 | [Description("RIGHT ARROW")]
55 | VK_RIGHT = 0x27,
56 |
57 | [Description("DOWN ARROW")]
58 | VK_DOWN = 0x28,
59 |
60 | VK_SELECT = 0x29,
61 | VK_EXECUTE = 0x2B,
62 |
63 | [Description("PRINT SCREEN")]
64 | VK_SNAPSHOT = 0x2C,
65 |
66 | [Description("INS")]
67 | VK_INSERT = 0x2D,
68 |
69 | [Description("DEL")]
70 | VK_DELETE = 0x2E,
71 |
72 | [Description("HELP")]
73 | VK_HELP = 0x2F,
74 |
75 | [Description("0")]
76 | VK_0 = 0x30,
77 |
78 | [Description("1")]
79 | VK_1 = 0x31,
80 |
81 | [Description("2")]
82 | VK_2 = 0x32,
83 |
84 | [Description("3")]
85 | VK_3 = 0x33,
86 |
87 | [Description("4")]
88 | VK_4 = 0x34,
89 |
90 | [Description("5")]
91 | VK_5 = 0x35,
92 |
93 | [Description("6")]
94 | VK_6 = 0x36,
95 |
96 | [Description("7")]
97 | VK_7 = 0x37,
98 |
99 | [Description("8")]
100 | VK_8 = 0x38,
101 |
102 | [Description("9")]
103 | VK_9 = 0x39,
104 |
105 | [Description("A")]
106 | VK_A = 0x41,
107 |
108 | [Description("B")]
109 | VK_B = 0x42,
110 |
111 | [Description("C")]
112 | VK_C = 0x43,
113 |
114 | [Description("D")]
115 | VK_D = 0x44,
116 |
117 | [Description("E")]
118 | VK_E = 0x45,
119 |
120 | [Description("F")]
121 | VK_F = 0x46,
122 |
123 | [Description("G")]
124 | VK_G = 0x47,
125 |
126 | [Description("H")]
127 | VK_H = 0x48,
128 |
129 | [Description("I")]
130 | VK_I = 0x49,
131 |
132 | [Description("J")]
133 | VK_J = 0x4A,
134 |
135 | [Description("K")]
136 | VK_K = 0x4B,
137 |
138 | [Description("L")]
139 | VK_L = 0x4C,
140 |
141 | [Description("M")]
142 | VK_M = 0x4D,
143 |
144 | [Description("N")]
145 | VK_N = 0x4E,
146 |
147 | [Description("O")]
148 | VK_O = 0x4F,
149 |
150 | [Description("P")]
151 | VK_P = 0x50,
152 |
153 | [Description("Q")]
154 | VK_Q = 0x51,
155 |
156 | [Description("R")]
157 | VK_R = 0x52,
158 |
159 | [Description("S")]
160 | VK_S = 0x53,
161 |
162 | [Description("T")]
163 | VK_T = 0x54,
164 |
165 | [Description("U")]
166 | VK_U = 0x55,
167 |
168 | [Description("V")]
169 | VK_V = 0x56,
170 |
171 | [Description("W")]
172 | VK_W = 0x57,
173 |
174 | [Description("X")]
175 | VK_X = 0x58,
176 |
177 | [Description("Y")]
178 | VK_Y = 0x59,
179 |
180 | [Description("Z")]
181 | VK_Z = 0x5A,
182 | VK_LWIN = 0x5B,
183 | VK_RWIN = 0x5C,
184 | VK_APPS = 0x5D,
185 |
186 | [Description("NUMPAD 0")]
187 | VK_NUMPAD0 = 0x60,
188 |
189 | [Description("NUMPAD 1")]
190 | VK_NUMPAD1 = 0x61,
191 |
192 | [Description("NUMPAD 2")]
193 | VK_NUMPAD2 = 0x62,
194 |
195 | [Description("NUMPAD 3")]
196 | VK_NUMPAD3 = 0x63,
197 |
198 | [Description("NUMPAD 4")]
199 | VK_NUMPAD4 = 0x64,
200 |
201 | [Description("NUMPAD 5")]
202 | VK_NUMPAD5 = 0x65,
203 |
204 | [Description("NUMPAD 6")]
205 | VK_NUMPAD6 = 0x66,
206 |
207 | [Description("NUMPAD 7")]
208 | VK_NUMPAD7 = 0x67,
209 |
210 | [Description("NUMPAD 8")]
211 | VK_NUMPAD8 = 0x68,
212 |
213 | [Description("NUMPAD 9")]
214 | VK_NUMPAD9 = 0x69,
215 |
216 | [Description("MULTIPLY")]
217 | VK_MULTIPLY = 0x6A,
218 |
219 | [Description("ADD")]
220 | VK_ADD = 0x6B,
221 |
222 | [Description("SEPARATOR")]
223 | VK_SEPARATOR = 0x6C,
224 |
225 | [Description("SUBTRACT")]
226 | VK_SUBTRACT = 0x6D,
227 |
228 | [Description("DECIMAL")]
229 | VK_DECIMAL = 0x6E,
230 |
231 | [Description("DIVIDE")]
232 | VK_DIVIDE = 0x6F,
233 |
234 | [Description("F1")]
235 | VK_F1 = 0x70,
236 |
237 | [Description("F2")]
238 | VK_F2 = 0x71,
239 |
240 | [Description("F3")]
241 | VK_F3 = 0x72,
242 |
243 | [Description("F4")]
244 | VK_F4 = 0x73,
245 |
246 | [Description("F5")]
247 | VK_F5 = 0x74,
248 |
249 | [Description("F6")]
250 | VK_F6 = 0x75,
251 |
252 | [Description("F7")]
253 | VK_F7 = 0x76,
254 |
255 | [Description("F8")]
256 | VK_F8 = 0x77,
257 |
258 | [Description("F9")]
259 | VK_F9 = 0x78,
260 |
261 | [Description("F10")]
262 | VK_F10 = 0x79,
263 |
264 | [Description("F11")]
265 | VK_F11 = 0x7A,
266 |
267 | [Description("F12")]
268 | VK_F12 = 0x7B,
269 |
270 | [Description("F13")]
271 | VK_F13 = 0x7C,
272 |
273 | [Description("F14")]
274 | VK_F14 = 0x7D,
275 |
276 | [Description("F15")]
277 | VK_F15 = 0x7E,
278 |
279 | [Description("F16")]
280 | VK_F16 = 0x7F,
281 |
282 | [Description("F17")]
283 | VK_F17 = 0x80,
284 |
285 | [Description("F18")]
286 | VK_F18 = 0x81,
287 |
288 | [Description("F19")]
289 | VK_F19 = 0x82,
290 |
291 | [Description("F20")]
292 | VK_F20 = 0x83,
293 |
294 | [Description("F21")]
295 | VK_F21 = 0x84,
296 |
297 | [Description("F22")]
298 | VK_F22 = 0x85,
299 |
300 | [Description("F23")]
301 | VK_F23 = 0x86,
302 |
303 | [Description("F24")]
304 | VK_F24 = 0x87,
305 |
306 | [Description("NUM LOCK")]
307 | VK_NUMLOCK = 0x90,
308 |
309 | [Description("SCROLL LOCK")]
310 | VK_SCROLL = 0x91,
311 | VK_LSHIFT = 0xA0,
312 | VK_RSHIFT = 0xA1,
313 | VK_LCONTROL = 0xA2,
314 | VK_RCONTROL = 0xA3,
315 | VK_LMENU = 0xA4,
316 | VK_RMENU = 0xA5,
317 | VK_PACKET = 0xE7,
318 | VK_ATTN = 0xF6,
319 | VK_CRSEL = 0xF7,
320 | VK_EXSEL = 0xF8,
321 | VK_EREOF = 0xF9,
322 | VK_PLAY = 0xFA,
323 | VK_ZOOM = 0xFB,
324 | VK_NONAME = 0xFC,
325 | VK_PA1 = 0xFD,
326 | }
327 | }
328 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Hooks/VirtualKeyModifier.cs:
--------------------------------------------------------------------------------
1 | namespace Wlx2Explorer.Hooks
2 | {
3 | enum VirtualKeyModifier : int
4 | {
5 | None = 0x00,
6 | Alt = 0x12,
7 | Shift = 0x10,
8 | Ctrl = 0x11
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Images/Down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Images/Down.png
--------------------------------------------------------------------------------
/Wlx2Explorer/Images/Start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Images/Start.png
--------------------------------------------------------------------------------
/Wlx2Explorer/Images/Stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Images/Stop.png
--------------------------------------------------------------------------------
/Wlx2Explorer/Images/Up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Images/Up.png
--------------------------------------------------------------------------------
/Wlx2Explorer/Images/Wlx2Explorer.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Images/Wlx2Explorer.ico
--------------------------------------------------------------------------------
/Wlx2Explorer/Images/Wlx2Explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Images/Wlx2Explorer.png
--------------------------------------------------------------------------------
/Wlx2Explorer/InitializationFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.IO;
5 |
6 | namespace Wlx2Explorer
7 | {
8 | class InitializationFile
9 | {
10 | private string _fileName = null;
11 | private Encoding _fileEncoding = null;
12 | private IDictionary> _content = null;
13 |
14 | public InitializationFile(string file) : this(file, Encoding.Default)
15 | {
16 | }
17 |
18 | public InitializationFile(string file, Encoding encoding)
19 | {
20 | _fileName = file;
21 | _fileEncoding = encoding;
22 | }
23 |
24 | public IDictionary GetSection(string sectionName) => _content.ContainsKey(sectionName) ? _content[sectionName] : null;
25 |
26 | public string GetValue(string sectionName, string keyName) => _content.ContainsKey(sectionName) && _content[sectionName].ContainsKey(keyName) ? _content[sectionName][keyName] : null;
27 |
28 | public void SetSection(string sectionName, IDictionary items)
29 | {
30 | _content[sectionName] = items;
31 | }
32 |
33 | public void SetValue(string sectionName, string keyName, string value)
34 | {
35 | if (!_content.ContainsKey(sectionName))
36 | {
37 | _content[sectionName] = new Dictionary();
38 | }
39 | _content[sectionName][keyName] = value;
40 | }
41 |
42 | public void LoadFile() => LoadFile(_fileName, _fileEncoding);
43 |
44 | public void LoadFile(string fileName) => LoadFile(fileName, _fileEncoding);
45 |
46 | public void LoadFile(string fileName, Encoding fileEncoding)
47 | {
48 | _content = Load(fileName, fileEncoding);
49 | }
50 |
51 | public void SaveFile() => SaveFile(_fileName, _fileEncoding);
52 |
53 | public void SaveFile(string fileName) => SaveFile(fileName, _fileEncoding);
54 |
55 | public void SaveFile(string fileName, Encoding fileEncoding)
56 | {
57 | using var file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read);
58 | using var writer = new StreamWriter(file, fileEncoding);
59 | writer.Write(ToString());
60 | }
61 |
62 | public override string ToString()
63 | {
64 | var content = new StringBuilder();
65 | foreach (var pair in _content)
66 | {
67 | content.AppendFormat("[{0}]{1}", pair.Key, Environment.NewLine);
68 | foreach (var pairInner in pair.Value)
69 | {
70 | content.AppendFormat("{0}={1}{2}", pairInner.Key, pairInner.Value, Environment.NewLine);
71 | }
72 | content.AppendLine();
73 | }
74 | return content.ToString();
75 | }
76 |
77 | private Dictionary> Load(string fileName, Encoding fileEncoding)
78 | {
79 | var content = new Dictionary>();
80 | using var file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
81 | using var reader = new StreamReader(file, _fileEncoding);
82 | string line = null;
83 | string section = null;
84 | while ((line = reader.ReadLine()) != null)
85 | {
86 | if (line.Length == 0) continue;
87 | if (line.StartsWith(";")) continue;
88 | if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
89 | {
90 | section = line.Substring(1, line.Length - 2);
91 | if (content.ContainsKey(section)) continue;
92 | content[section] = new Dictionary();
93 | }
94 | else
95 | {
96 | if (section == null) continue;
97 | var pair = line.Split('=');
98 | if (pair.Length < 2) continue;
99 | var keyValue = new KeyValuePair(pair[0], pair[1]);
100 | if (content[section].Contains(keyValue)) continue;
101 | content[section].Add(keyValue);
102 | }
103 | }
104 | return content;
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Libs/UnRAR.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Libs/UnRAR.dll
--------------------------------------------------------------------------------
/Wlx2Explorer/Libs/UnRAR64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Libs/UnRAR64.dll
--------------------------------------------------------------------------------
/Wlx2Explorer/Native/Interfaces/IServiceProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Wlx2Explorer.Native.Interfaces
5 | {
6 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
7 | interface IServiceProvider
8 | {
9 | void QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Native/Interfaces/IShellBrowser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Wlx2Explorer.Native.Interfaces
5 | {
6 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214E2-0000-0000-C000-000000000046")]
7 | interface IShellBrowser
8 | {
9 | void GetWindow(out IntPtr phwnd);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Native/NativeConstants.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Wlx2Explorer.Native
4 | {
5 | static class NativeConstants
6 | {
7 | public const int WM_COMMAND = 0x0111;
8 | public const int WM_NOTIFY = 0x004E;
9 | public const int WM_MEASUREITEM = 0x002C;
10 | public const int WM_DRAWITEM = 0x002B;
11 | public const int WM_KEYDOWN = 0x0100;
12 | public const int WM_SYSKEYDOWN = 0x0104;
13 | public const int WH_KEYBOARD_LL = 0x0D;
14 |
15 | public const uint HC_ACTION = 0;
16 |
17 | public const int LCS_FINDFIRST = 0x01;
18 | public const int LCS_MATCHCASE = 0x02;
19 | public const int LCS_WHOLEWORDS = 0x04;
20 | public const int LCS_BACKWARDS = 0x08;
21 |
22 | public const uint LVM_FIRST = 0x1000;
23 | public const uint LVM_GETITEMCOUNT = LVM_FIRST + 4;
24 | public const uint LVM_GETITEMW = LVM_FIRST + 75;
25 | public const uint LVM_GETITEMPOSITION = LVM_FIRST + 16;
26 | public const uint LVM_GETITEMSTATE = LVM_FIRST + 44;
27 |
28 | public const uint PROCESS_VM_OPERATION = 0x0008;
29 | public const uint PROCESS_VM_READ = 0x0010;
30 | public const uint PROCESS_VM_WRITE = 0x0020;
31 |
32 | public const uint MEM_COMMIT = 0x1000;
33 | public const uint MEM_RELEASE = 0x8000;
34 | public const uint MEM_RESERVE = 0x2000;
35 |
36 | public const uint PAGE_READWRITE = 4;
37 | public const int LVIF_TEXT = 0x0001;
38 | public const uint LVIS_SELECTED = 0x2;
39 |
40 | public static readonly Guid SID_STopLevelBrowser = new Guid(0x4C96BE40, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37);
41 | }
42 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Native/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Wlx2Explorer.Native
6 | {
7 | class NativeMethods
8 | {
9 | public delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);
10 |
11 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
12 | public static extern IntPtr LoadLibrary(string fileName);
13 |
14 | [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
15 | public static extern bool FreeLibrary(IntPtr hModule);
16 |
17 | [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
18 | public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
19 |
20 | [DllImport("user32.dll")]
21 | public static extern IntPtr GetForegroundWindow();
22 |
23 | [DllImport("user32.dll")]
24 | [return: MarshalAs(UnmanagedType.Bool)]
25 | public static extern bool DestroyWindow(IntPtr hwnd);
26 |
27 | [DllImport("user32.dll")]
28 | [return: MarshalAs(UnmanagedType.Bool)]
29 | public static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy, uint flags);
30 |
31 | [DllImport("user32.dll", SetLastError = true)]
32 | public static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProc callback, IntPtr hInstance, uint threadId);
33 |
34 | [DllImport("user32.dll")]
35 | public static extern bool UnhookWindowsHookEx(IntPtr handleHook);
36 |
37 | [DllImport("user32.dll")]
38 | public static extern int CallNextHookEx(IntPtr handleHook, int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
39 |
40 | [DllImport("user32.dll")]
41 | public static extern int GetAsyncKeyState(int key);
42 |
43 | [DllImport("user32.dll")]
44 | public static extern IntPtr GetThreadDesktop(int threadId);
45 |
46 | [DllImport("user32.dll")]
47 | public static extern IntPtr SetFocus(IntPtr hwnd);
48 |
49 | [DllImport("user32.dll")]
50 | public static extern IntPtr GetParent(IntPtr hwnd);
51 |
52 | [DllImport("kernel32.dll")]
53 | public static extern IntPtr GetModuleHandle(string name);
54 |
55 | [DllImport("kernel32.dll")]
56 | public static extern uint GetCurrentThreadId();
57 |
58 | [DllImport("user32")]
59 | public static extern int GetClassName(IntPtr hwnd, StringBuilder name, int count);
60 |
61 | [DllImport("kernel32.dll")]
62 | public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
63 |
64 | [DllImport("kernel32.dll")]
65 | public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);
66 |
67 | [DllImport("kernel32.dll")]
68 | public static extern bool CloseHandle(IntPtr handle);
69 |
70 | [DllImport("kernel32.dll")]
71 | public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
72 |
73 | [DllImport("kernel32.dll")]
74 | public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
75 |
76 | [DllImport("kernel32.dll")]
77 | public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
78 |
79 | [DllImport("user32.DLL")]
80 | public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
81 |
82 | [DllImport("user32.DLL")]
83 | public static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
84 |
85 | [DllImport("user32.DLL")]
86 | public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
87 |
88 | [DllImport("user32.dll")]
89 | public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint dwProcessId);
90 |
91 | [DllImport("user32.dll")]
92 | [return: MarshalAs(UnmanagedType.Bool)]
93 | public static extern bool EnumWindows(EnumWindowProc lpEnumFunc, IntPtr lParam);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Native/NativeTypes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Wlx2Explorer.Native
5 | {
6 | [StructLayout(LayoutKind.Sequential)]
7 | struct KBDLLHOOKSTRUCT
8 | {
9 | public int vkCode;
10 | public int scanCode;
11 | public int flags;
12 | public int time;
13 | public IntPtr dwExtraInfo;
14 | }
15 |
16 | [StructLayout(LayoutKind.Sequential)]
17 | class ListDefaultParamStruct
18 | {
19 | public int size;
20 | public int interfaceVersionLow;
21 | public int interfaceVersionHigh;
22 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
23 | public string defaultIniFile;
24 | }
25 |
26 | [StructLayout(LayoutKind.Sequential)]
27 | class Rect
28 | {
29 | public int Left;
30 | public int Top;
31 | public int Right;
32 | public int Bottom;
33 | public int Width { get { return Right - Left; } }
34 | public int Height { get { return Bottom - Top; } }
35 | }
36 |
37 | struct LVITEM
38 | {
39 | public int mask;
40 | public int iItem;
41 | public int iSubItem;
42 | public int state;
43 | public int stateMask;
44 | public IntPtr pszText; // string
45 | public int cchTextMax;
46 | public int iImage;
47 | public IntPtr lParam;
48 | public int iIndent;
49 | public int iGroupId;
50 | public int cColumns;
51 | public IntPtr puColumns;
52 | }
53 |
54 | delegate int KeyboardHookProc(int code, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
55 | }
56 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Plugin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 | using System.Text.RegularExpressions;
5 | using System.Runtime.InteropServices;
6 | using System.Runtime.ExceptionServices;
7 | using Wlx2Explorer.Native;
8 |
9 | namespace Wlx2Explorer
10 | {
11 | class Plugin
12 | {
13 | private IntPtr _moduleHandle;
14 | private delegate IntPtr ListLoadDelegate(IntPtr hwndParent, string fileName, int flags);
15 | private delegate void ListCloseWindowDelegate(IntPtr hwndList);
16 | private delegate void ListGetDetectStringDelegate(StringBuilder detectString, int size);
17 | private delegate void ListNotificationReceivedDelegate(IntPtr hwndList, int message, IntPtr wParam, IntPtr lParam);
18 | private delegate void ListSetDefaultParamsDelegate(ListDefaultParamStruct defaultParams);
19 | private delegate int ListSearchTextDelegate(IntPtr hwndList, string searchString, int flags);
20 | private delegate int ListSearchDialogDelegate(IntPtr hwndList, int flags);
21 | private delegate int ListPrintDelegate(IntPtr hwndList, string fileName, string printerName, int flags, ref Rect margins);
22 |
23 | private delegate IntPtr ListLoadWDelegate(IntPtr hwndParent, [MarshalAs(UnmanagedType.LPTStr)] string fileName, int flags);
24 | private delegate int ListSearchTextWDelegate(IntPtr hwndList, [MarshalAs(UnmanagedType.LPTStr)] string searchString, int flags);
25 | private delegate int ListPrintWDelegate(IntPtr hwndList, [MarshalAs(UnmanagedType.LPTStr)] string fileName, [MarshalAs(UnmanagedType.LPTStr)] string printerName, int flags, ref Rect margins);
26 |
27 |
28 | public string ModuleName
29 | {
30 | get;
31 | private set;
32 | }
33 |
34 | public bool ListCloseWindowExist
35 | {
36 | get
37 | {
38 | var listCloseWindow = (ListCloseWindowDelegate)LoadFunction("ListCloseWindow");
39 | var exist = listCloseWindow != null;
40 | return exist;
41 | }
42 | }
43 |
44 | public bool ListGetDetectStringExist
45 | {
46 | get
47 | {
48 | var listGetDetectString = (ListGetDetectStringDelegate)LoadFunction("ListGetDetectString");
49 | var exist = listGetDetectString != null;
50 | return exist;
51 | }
52 | }
53 |
54 | public bool ListSetDefaultParamsExist
55 | {
56 | get
57 | {
58 | var listSetDefaultParams = (ListSetDefaultParamsDelegate)LoadFunction("ListSetDefaultParams");
59 | var exist = listSetDefaultParams != null;
60 | return exist;
61 | }
62 | }
63 |
64 | public bool ListSearchTextExist
65 | {
66 | get
67 | {
68 | var listSearchTextW = (ListSearchTextWDelegate)LoadFunction("ListSearchTextW");
69 | var listSearchText = (ListSearchTextDelegate)LoadFunction("ListSearchText");
70 | var exist = listSearchTextW != null || listSearchText != null;
71 | return exist;
72 | }
73 | }
74 |
75 | public bool ListSearchDialogExist
76 | {
77 | get
78 | {
79 | var listSearchDialog = (ListSearchDialogDelegate)LoadFunction("ListSearchDialog");
80 | var exist = listSearchDialog != null;
81 | return exist;
82 | }
83 | }
84 |
85 | public bool ListPrintExist
86 | {
87 | get
88 | {
89 | var listPrintW = (ListPrintWDelegate)LoadFunction("ListPrintW");
90 | var listPrint = (ListPrintDelegate)LoadFunction("ListPrint");
91 | var exist = listPrintW != null || listPrint != null;
92 | return exist;
93 | }
94 | }
95 |
96 |
97 | public Plugin(string moduleName)
98 | {
99 | ModuleName = moduleName;
100 | _moduleHandle = IntPtr.Zero;
101 | }
102 |
103 | public bool LoadModule()
104 | {
105 | UnloadModule();
106 | _moduleHandle = NativeMethods.LoadLibrary(ModuleName);
107 | var result = _moduleHandle != IntPtr.Zero;
108 | return result;
109 | }
110 |
111 | public bool UnloadModule()
112 | {
113 | if (_moduleHandle == IntPtr.Zero)
114 | {
115 | return true;
116 | }
117 | var result = NativeMethods.FreeLibrary(_moduleHandle);
118 | return result;
119 | }
120 |
121 | public IntPtr ListLoad(IntPtr hwndParent, string fileName)
122 | {
123 | var listLoadW = (ListLoadWDelegate)LoadFunction("ListLoadW");
124 | if (listLoadW != null)
125 | {
126 | var hwnd = listLoadW(hwndParent, fileName, 0);
127 | return hwnd;
128 | }
129 | else
130 | {
131 | var listLoad = (ListLoadDelegate)LoadFunction("ListLoad");
132 | if (listLoad == null)
133 | {
134 | return IntPtr.Zero;
135 | }
136 | var hwnd = listLoad(hwndParent, fileName, 0);
137 | return hwnd;
138 | }
139 | }
140 |
141 | public void ListCloseWindow(IntPtr hwndList)
142 | {
143 | var function = (ListCloseWindowDelegate)LoadFunction("ListCloseWindow");
144 | function(hwndList);
145 | }
146 |
147 | public string ListGetDetectString()
148 | {
149 | var function = (ListGetDetectStringDelegate)LoadFunction("ListGetDetectString");
150 | var detectString = new StringBuilder(1024 * 10);
151 | function(detectString, detectString.Capacity);
152 | return detectString.ToString();
153 | }
154 |
155 | public void ListNotificationReceived(IntPtr hwndList, int message, IntPtr wParam, IntPtr lParam)
156 | {
157 | var function = (ListNotificationReceivedDelegate)LoadFunction("ListNotificationReceived");
158 | function(hwndList, message, wParam, lParam);
159 | }
160 |
161 | public void ListSetDefaultParams(int interfaceVersionLow, int interfaceVersionHigh, string iniFile)
162 | {
163 | var function = (ListSetDefaultParamsDelegate)LoadFunction("ListSetDefaultParams");
164 | var defaultParams = new ListDefaultParamStruct();
165 | defaultParams.interfaceVersionLow = interfaceVersionLow;
166 | defaultParams.interfaceVersionHigh = interfaceVersionHigh;
167 | defaultParams.defaultIniFile = iniFile;
168 | defaultParams.size = Marshal.SizeOf(defaultParams);
169 | function(defaultParams);
170 | }
171 |
172 | public int ListSearchText(IntPtr hwndList, string searchString, int flags)
173 | {
174 | var listSearchTextW = (ListSearchTextWDelegate)LoadFunction("ListSearchTextW");
175 | if (listSearchTextW != null)
176 | {
177 | var result = listSearchTextW(hwndList, searchString, flags);
178 | return result;
179 | }
180 | else
181 | {
182 | var listSearchText = (ListSearchTextDelegate)LoadFunction("ListSearchText");
183 | var result = listSearchText(hwndList, searchString, flags);
184 | return result;
185 | }
186 | }
187 |
188 | public int ListSearchDialog(IntPtr hwndList, int flags)
189 | {
190 | var function = (ListSearchDialogDelegate)LoadFunction("ListSearchDialog");
191 | var result = function(hwndList, flags);
192 | return result;
193 | }
194 |
195 | public int ListPrint(IntPtr hwndList, string fileName, string printerName, int flags, ref Rect margins)
196 | {
197 | var listPrintW = (ListPrintWDelegate)LoadFunction("ListPrintW");
198 | if (listPrintW != null)
199 | {
200 | var result = listPrintW(hwndList, fileName, printerName, flags, ref margins);
201 | return result;
202 |
203 | }
204 | else
205 | {
206 | var listPrint = (ListPrintDelegate)LoadFunction("ListPrint");
207 | var result = listPrint(hwndList, fileName, printerName, flags, ref margins);
208 | return result;
209 | }
210 | }
211 |
212 | [HandleProcessCorruptedStateExceptions]
213 | public static string[] GetSupportedExtensions(string fileName)
214 | {
215 | try
216 | {
217 | var plugin = new Plugin(fileName);
218 | var pluginLoaded = plugin.LoadModule();
219 | if (!pluginLoaded) return new string[0];
220 | var detectString = plugin.ListGetDetectStringExist ? plugin.ListGetDetectString() : string.Empty;
221 | var regExp = new Regex("EXT=\\\"(\\w+)\\\"", RegexOptions.IgnoreCase | RegexOptions.Compiled);
222 | var matches = regExp.Matches(detectString);
223 | var result = matches.Cast().Select(m => m.Groups[1].Value).ToArray();
224 | plugin.UnloadModule();
225 | return result;
226 | }
227 | catch
228 | {
229 | return new string[0];
230 | }
231 | }
232 |
233 | private Delegate LoadFunction(string functionName)
234 | {
235 | if (_moduleHandle == IntPtr.Zero) throw new Exception("Plugin module is not loaded.");
236 | var functionAddress = NativeMethods.GetProcAddress(_moduleHandle, functionName);
237 | if (functionAddress == IntPtr.Zero)
238 | {
239 | return null;
240 | }
241 | var function = Marshal.GetDelegateForFunctionPointer(functionAddress, typeof(T));
242 | return function;
243 | }
244 | }
245 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 | using System.Threading;
5 | using System.IO;
6 | using System.Linq;
7 | using Wlx2Explorer.Forms;
8 | using Wlx2Explorer.Utils;
9 | using Wlx2Explorer.Settings;
10 |
11 | namespace Wlx2Explorer
12 | {
13 | static class Program
14 | {
15 | private static Mutex _mutex;
16 |
17 | ///
18 | /// The main entry point for the application.
19 | ///
20 | [STAThread]
21 | static void Main(string[] args)
22 | {
23 | AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainUnhandledException;
24 | Application.ThreadException += OnThreadException;
25 | Environment.CurrentDirectory = AssemblyUtils.AssemblyDirectory;
26 |
27 | // Command Line Interface
28 | var toggleParser = new ToggleParser(args);
29 | if (toggleParser.HasToggle("h") || toggleParser.HasToggle("help"))
30 | {
31 | var messageBoxForm = new MessageBoxForm();
32 | messageBoxForm.Message = BuildHelpString();
33 | messageBoxForm.Text = "Help";
34 | messageBoxForm.ShowDialog();
35 | return;
36 | }
37 |
38 | if (toggleParser.HasToggle("f") || toggleParser.HasToggle("file"))
39 | {
40 | var suppressmsg = toggleParser.HasToggle("f") || toggleParser.HasToggle("suppressmsg");
41 | var fileName = toggleParser.GetToggleValueOrDefault("f", null) ?? toggleParser.GetToggleValueOrDefault("file", null);
42 | if (!File.Exists(fileName))
43 | {
44 | if (!suppressmsg)
45 | {
46 | MessageBox.Show($"{fileName} does not exist.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
47 | }
48 | }
49 | else
50 | {
51 | ProgramSettings settings;
52 | try
53 | {
54 | settings = ProgramSettings.Read();
55 | }
56 | catch
57 | {
58 | if (!suppressmsg)
59 | {
60 | MessageBox.Show("Failed to read a program setting file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
61 | }
62 | return;
63 | }
64 |
65 | var plugins = new List();
66 | foreach (var pluginInfo in settings.Plugins)
67 | {
68 | var plugin = new Plugin(pluginInfo.Path);
69 | var pluginLoaded = false;
70 | var pluginInitialized = true;
71 |
72 | try
73 | {
74 | pluginLoaded = plugin.LoadModule();
75 | }
76 | catch
77 | {
78 | pluginLoaded = false;
79 | }
80 |
81 | try
82 | {
83 | if (plugin.ListSetDefaultParamsExist)
84 | {
85 | var pluginExtension = Path.GetExtension(pluginInfo.Path);
86 | var pluginIniFile = Path.GetFullPath(pluginInfo.Path).Replace(pluginExtension, ".ini");
87 | if (!File.Exists(pluginIniFile))
88 | {
89 | plugin.ListSetDefaultParams(settings.PluginLowVersion, settings.PluginHighVersion, settings.PluginIniFile);
90 | }
91 | }
92 | }
93 | catch
94 | {
95 | pluginInitialized = false;
96 | }
97 |
98 | if (pluginLoaded && pluginInitialized)
99 | {
100 | plugins.Add(plugin);
101 | }
102 | else if (!pluginLoaded)
103 | {
104 | if (!suppressmsg)
105 | {
106 | MessageBox.Show($@"Failed to load the plugin {Environment.NewLine} ""{pluginInfo.Path}"".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
107 | }
108 | }
109 | else
110 | {
111 | if (!suppressmsg)
112 | {
113 | MessageBox.Show($@"Failed to initialize the plugin with default settings {Environment.NewLine} ""{pluginInfo.Path}"".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
114 | }
115 | }
116 | }
117 |
118 | if (plugins.Any())
119 | {
120 | var listerForm = new ListerForm(settings, plugins, fileName);
121 | listerForm.ShowDialog();
122 | }
123 | }
124 | return;
125 | }
126 |
127 | var mutexName = "Wlx2Explorer";
128 | _mutex = new Mutex(false, mutexName, out var createNew);
129 | if (!createNew)
130 | {
131 | return;
132 | }
133 |
134 | Application.EnableVisualStyles();
135 | Application.SetCompatibleTextRenderingDefault(false);
136 | Application.Run(new MainForm());
137 | }
138 |
139 | static void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
140 | {
141 | var ex = e.ExceptionObject as Exception;
142 | ex = ex ?? new Exception("OnCurrentDomainUnhandledException");
143 | OnThreadException(sender, new ThreadExceptionEventArgs(ex));
144 | }
145 |
146 | static void OnThreadException(object sender, ThreadExceptionEventArgs e) =>
147 | MessageBox.Show(e.Exception.ToString(), AssemblyUtils.AssemblyProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
148 |
149 | static string BuildHelpString() =>
150 | @"-h --help The help
151 | -f --file Path to file
152 | -s --suppressmsg Suppress messages
153 |
154 | Example:
155 | Wlx2Explorer.exe -s --file ""C:\Temp\Image.jpeg""";
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("Total Commander lister plugin from File Explorer and Desktop")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("Alexander Illarionov")]
11 | [assembly: AssemblyProduct("Wlx2Explorer")]
12 | [assembly: AssemblyCopyright("Copyright © 2019")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("166879d2-29e4-4753-a30e-414cf690c2d9")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.6.0")]
35 | [assembly: AssemblyFileVersion("1.6.0")]
--------------------------------------------------------------------------------
/Wlx2Explorer/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Wlx2Explorer.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
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 | /// Returns the cached ResourceManager instance used by this class.
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("Wlx2Explorer.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
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 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap Down {
67 | get {
68 | object obj = ResourceManager.GetObject("Down", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Bitmap.
75 | ///
76 | internal static System.Drawing.Bitmap Start {
77 | get {
78 | object obj = ResourceManager.GetObject("Start", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// Looks up a localized resource of type System.Drawing.Bitmap.
85 | ///
86 | internal static System.Drawing.Bitmap Stop {
87 | get {
88 | object obj = ResourceManager.GetObject("Stop", resourceCulture);
89 | return ((System.Drawing.Bitmap)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// Looks up a localized resource of type System.Drawing.Bitmap.
95 | ///
96 | internal static System.Drawing.Bitmap Up {
97 | get {
98 | object obj = ResourceManager.GetObject("Up", resourceCulture);
99 | return ((System.Drawing.Bitmap)(obj));
100 | }
101 | }
102 |
103 | ///
104 | /// Looks up a localized resource of type System.Drawing.Bitmap.
105 | ///
106 | internal static System.Drawing.Bitmap Wlx2Explorer {
107 | get {
108 | object obj = ResourceManager.GetObject("Wlx2Explorer", resourceCulture);
109 | return ((System.Drawing.Bitmap)(obj));
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Wlx2Explorer/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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Images\Down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Images\Start.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Images\Stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Images\Up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | ..\Images\Wlx2Explorer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
135 |
136 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.1008
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Wlx2Explorer.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.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 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Settings/PluginInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Wlx2Explorer.Settings
4 | {
5 | class PluginInfo
6 | {
7 | public string Path { get; set; }
8 |
9 | public IList Extensions { get; set; }
10 |
11 | public PluginInfo() : this("", new List())
12 | {
13 | }
14 |
15 | public PluginInfo(string path, IList extensions)
16 | {
17 | Path = path;
18 | Extensions = extensions;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Settings/ProgramSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Xml.Linq;
4 | using System.Xml.XPath;
5 | using System.IO;
6 | using System.Text;
7 | using Wlx2Explorer.Utils;
8 |
9 | namespace Wlx2Explorer.Settings
10 | {
11 | class ProgramSettings
12 | {
13 | public IList Plugins { get; set; }
14 |
15 | public int ListerFormKey1 { get; set; }
16 |
17 | public int ListerFormKey2 { get; set; }
18 |
19 | public int ListerFormKey3 { get; set; }
20 |
21 | public int SearchDialogKey1 { get; set; }
22 |
23 | public int SearchDialogKey2 { get; set; }
24 |
25 | public int SearchDialogKey3 { get; set; }
26 |
27 | public int PrintDialogKey1 { get; set; }
28 |
29 | public int PrintDialogKey2 { get; set; }
30 |
31 | public int PrintDialogKey3 { get; set; }
32 |
33 | public int ListerFormWidth { get; set; }
34 |
35 | public int ListerFormHeight { get; set; }
36 |
37 | public bool ListerFormMaximized { get; set; }
38 |
39 | public bool AutoStartProgram { get; set; }
40 |
41 | public int PluginHighVersion { get; set; }
42 |
43 | public int PluginLowVersion { get; set; }
44 |
45 | public string PluginIniFile { get; set; }
46 |
47 |
48 | public ProgramSettings()
49 | {
50 | Plugins = new List();
51 | }
52 |
53 | public static ProgramSettings Read()
54 | {
55 | var fileName = AssemblyUtils.AssemblyFileNameWithoutExtension + ".xml";
56 | fileName = Path.Combine(AssemblyUtils.AssemblyDirectory, fileName);
57 | var document = XDocument.Load(fileName);
58 | var settings = Read(document);
59 | return settings;
60 | }
61 |
62 | public static ProgramSettings Read(XDocument document) => new ProgramSettings
63 | {
64 | ListerFormKey1 = int.Parse(document.XPathSelectElement("//Settings/ListerFormHotKeys").Attribute("key1").Value),
65 | ListerFormKey2 = int.Parse(document.XPathSelectElement("//Settings/ListerFormHotKeys").Attribute("key2").Value),
66 | ListerFormKey3 = int.Parse(document.XPathSelectElement("//Settings/ListerFormHotKeys").Attribute("key3").Value),
67 | SearchDialogKey1 = int.Parse(document.XPathSelectElement("//Settings/SearchDialogHotKeys").Attribute("key1").Value),
68 | SearchDialogKey2 = int.Parse(document.XPathSelectElement("//Settings/SearchDialogHotKeys").Attribute("key2").Value),
69 | SearchDialogKey3 = int.Parse(document.XPathSelectElement("//Settings/SearchDialogHotKeys").Attribute("key3").Value),
70 | PrintDialogKey1 = int.Parse(document.XPathSelectElement("//Settings/PrintDialogHotKeys").Attribute("key1").Value),
71 | PrintDialogKey2 = int.Parse(document.XPathSelectElement("//Settings/PrintDialogHotKeys").Attribute("key2").Value),
72 | PrintDialogKey3 = int.Parse(document.XPathSelectElement("//Settings/PrintDialogHotKeys").Attribute("key3").Value),
73 | ListerFormMaximized = bool.Parse(document.XPathSelectElement("//Settings/ListerForm").Attribute("maximized").Value),
74 | ListerFormWidth = int.Parse(document.XPathSelectElement("//Settings/ListerForm").Attribute("width").Value),
75 | ListerFormHeight = int.Parse(document.XPathSelectElement("//Settings/ListerForm").Attribute("height").Value),
76 | PluginHighVersion = int.Parse(document.XPathSelectElement("//Settings/PluginDefaultSettings").Attribute("highVersion").Value),
77 | PluginLowVersion = int.Parse(document.XPathSelectElement("//Settings/PluginDefaultSettings").Attribute("lowVersion").Value),
78 | PluginIniFile = new FileInfo(document.XPathSelectElement("//Settings/PluginDefaultSettings").Attribute("iniFile").Value).FullName,
79 | Plugins = document.XPathSelectElements("//Settings/Plugins/Plugin")
80 | .Select(el => new PluginInfo(el.Attribute("path").Value, string.IsNullOrWhiteSpace(el.Attribute("extensions").Value) ? new List() : el.Attribute("extensions").Value.Split(';').ToList())).ToList()
81 | };
82 |
83 | public static void Write(ProgramSettings settings)
84 | {
85 | var fileName = AssemblyUtils.AssemblyFileNameWithoutExtension + ".xml";
86 | fileName = Path.Combine(AssemblyUtils.AssemblyDirectory, fileName);
87 | Write(settings, fileName);
88 | }
89 |
90 | public static void Write(ProgramSettings settings, string fileName)
91 | {
92 | var document = new XDocument(new XDeclaration("1.0", "utf-8", null),
93 | new XElement("Settings",
94 | new XElement("Plugins", settings.Plugins.Select(x => new XElement("Plugin",
95 | new XAttribute("path", x.Path),
96 | new XAttribute("extensions", string.Join(";", x.Extensions.ToArray()))))),
97 | new XElement("ListerFormHotKeys",
98 | new XAttribute("key1", settings.ListerFormKey1.ToString()),
99 | new XAttribute("key2", settings.ListerFormKey2.ToString()),
100 | new XAttribute("key3", settings.ListerFormKey3.ToString())),
101 | new XElement("SearchDialogHotKeys",
102 | new XAttribute("key1", settings.SearchDialogKey1.ToString()),
103 | new XAttribute("key2", settings.SearchDialogKey2.ToString()),
104 | new XAttribute("key3", settings.SearchDialogKey3.ToString())),
105 | new XElement("PrintDialogHotKeys",
106 | new XAttribute("key1", settings.PrintDialogKey1.ToString()),
107 | new XAttribute("key2", settings.PrintDialogKey2.ToString()),
108 | new XAttribute("key3", settings.PrintDialogKey3.ToString())),
109 | new XElement("ListerForm",
110 | new XAttribute("maximized", settings.ListerFormMaximized.ToString()),
111 | new XAttribute("width", settings.ListerFormWidth.ToString()),
112 | new XAttribute("height", settings.ListerFormHeight.ToString())),
113 | new XElement("PluginDefaultSettings",
114 | new XAttribute("highVersion", settings.PluginHighVersion.ToString()),
115 | new XAttribute("lowVersion", settings.PluginLowVersion.ToString()),
116 | new XAttribute("iniFile", settings.PluginIniFile))));
117 |
118 | Save(document, fileName);
119 | }
120 |
121 | private static void Save(XDocument document, string fileName)
122 | {
123 | using var writer = new Utf8StringWriter();
124 | document.Save(writer, SaveOptions.None);
125 | File.WriteAllText(fileName, writer.ToString());
126 | }
127 |
128 | private class Utf8StringWriter : StringWriter
129 | {
130 | public override Encoding Encoding { get { return Encoding.UTF8; } }
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/Wlx2Explorer/StartUpManager.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 |
3 | namespace Wlx2Explorer
4 | {
5 | static class StartUpManager
6 | {
7 | private const string RUN_LOCATION = @"Software\Microsoft\Windows\CurrentVersion\Run";
8 |
9 | public static void AddToStartup(string keyName, string assemblyLocation)
10 | {
11 | using var key = Registry.CurrentUser.OpenSubKey(RUN_LOCATION, true);
12 | key.SetValue(keyName, assemblyLocation);
13 | }
14 |
15 | public static void RemoveFromStartup(string keyName)
16 | {
17 | using var key = Registry.CurrentUser.OpenSubKey(RUN_LOCATION, true);
18 | key.DeleteValue(keyName);
19 | }
20 |
21 | public static bool IsInStartup(string keyName, string assemblyLocation)
22 | {
23 | using var key = Registry.CurrentUser.OpenSubKey(RUN_LOCATION, true);
24 | if (key == null)
25 | {
26 | return false;
27 | }
28 | var value = (string)key.GetValue(keyName);
29 | if (string.IsNullOrEmpty(value))
30 | {
31 | return false;
32 | }
33 | var result = (value == assemblyLocation);
34 | return result;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Wlx2Explorer/ToggleParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Wlx2Explorer
6 | {
7 | class ToggleParser
8 | {
9 | private readonly Dictionary toggles;
10 |
11 | public ToggleParser(string[] args)
12 | {
13 | toggles =
14 | args.Zip(args.Skip(1).Concat(new[] { string.Empty }), (first, second) => new { first, second })
15 | .Where(pair => IsToggle(pair.first))
16 | .ToDictionary(pair => RemovePrefix(pair.first).ToLowerInvariant(), g => IsToggle(g.second) ? string.Empty : g.second);
17 | }
18 |
19 | private static string RemovePrefix(string toggle) => new string(toggle.SkipWhile(c => c == '-').ToArray());
20 |
21 | private static bool IsToggle(string arg) => arg.StartsWith("-", StringComparison.InvariantCulture);
22 |
23 | public bool HasToggle(string toggle) => toggles.ContainsKey(toggle.ToLowerInvariant());
24 |
25 | public string GetToggleValueOrDefault(string toggle, string defaultValue) => toggles.TryGetValue(toggle.ToLowerInvariant(), out var value) ? value : defaultValue;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Utils/AssemblyUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.IO;
3 | using System.Linq;
4 |
5 | namespace Wlx2Explorer.Utils
6 | {
7 | static class AssemblyUtils
8 | {
9 | public static string AssemblyLocation => Assembly.GetExecutingAssembly().Location;
10 |
11 | public static string AssemblyDirectory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
12 |
13 | public static string AssemblyFileNameWithoutExtension => Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location);
14 |
15 | public static string AssemblyTitle => Assembly
16 | .GetExecutingAssembly()
17 | .GetCustomAttributes(typeof(AssemblyTitleAttribute), false)
18 | .OfType()
19 | .FirstOrDefault()?.Title ?? string.Empty;
20 |
21 |
22 | public static string AssemblyProductName => Assembly
23 | .GetExecutingAssembly()
24 | .GetCustomAttributes(typeof(AssemblyProductAttribute), false)
25 | .OfType()
26 | .FirstOrDefault()?.Product ?? string.Empty;
27 |
28 |
29 | public static string AssemblyProductVersion
30 | {
31 | get
32 | {
33 | var version = Assembly.GetExecutingAssembly().GetName().Version;
34 | return $"{version.Major}.{version.Minor}.{version.Build}";
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Utils/WindowUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.IO;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Runtime.InteropServices;
8 | using Wlx2Explorer.Native;
9 | using IWshRuntimeLibrary;
10 | using SHDocVw;
11 | using Shell32;
12 |
13 | namespace Wlx2Explorer.Utils
14 | {
15 | static class WindowUtils
16 | {
17 | public static string GetSelectedFileFromDesktopOrExplorer()
18 | {
19 | var hwnd = NativeMethods.GetForegroundWindow();
20 | var className = GetClassName(hwnd);
21 | if (className == "WorkerW" || className == "Progman")
22 | {
23 | var hwndSysListView32 = GetSysListView32();
24 | var fileName = GetSelectedFileFromDesktop(hwndSysListView32);
25 | return fileName;
26 | }
27 | else
28 | {
29 | var fileName = GetSelectedFileFromExplorer(hwnd);
30 | return fileName;
31 | }
32 | }
33 |
34 | private static string GetSelectedFileFromExplorer(IntPtr hwnd)
35 | {
36 | var hwndActiveTab = NativeMethods.FindWindowEx(hwnd, IntPtr.Zero, "ShellTabWindowClass", null);
37 | hwndActiveTab = hwndActiveTab != IntPtr.Zero ? hwndActiveTab : NativeMethods.FindWindowEx(hwnd, IntPtr.Zero, "TabWindowClass", null);
38 |
39 | var fileNames = new List();
40 | var shellAppType = Type.GetTypeFromProgID("Shell.Application");
41 | var shellObject = Activator.CreateInstance(shellAppType);
42 | var shellWindows = (IShellWindows)shellAppType.InvokeMember("Windows", BindingFlags.InvokeMethod, null, shellObject, new object[] { });
43 | foreach (IWebBrowser2 window in shellWindows)
44 | {
45 | if (window.HWND != hwnd.ToInt32())
46 | {
47 | continue;
48 | }
49 |
50 | if (hwndActiveTab != IntPtr.Zero && window is Native.Interfaces.IServiceProvider serviceProvider)
51 | {
52 | object shellBrowserObject;
53 | serviceProvider.QueryService(NativeConstants.SID_STopLevelBrowser, typeof(Native.Interfaces.IShellBrowser).GUID, out shellBrowserObject);
54 | var shellBrowser = (Native.Interfaces.IShellBrowser)shellBrowserObject;
55 | var hwndThisTab = IntPtr.Zero;
56 | shellBrowser.GetWindow(out hwndThisTab);
57 | if (hwndThisTab != IntPtr.Zero && hwndActiveTab != hwndThisTab)
58 | {
59 | continue;
60 | }
61 | }
62 |
63 | if (window.Document is IShellFolderViewDual2 document2)
64 | {
65 | foreach (FolderItem folderItem in document2.SelectedItems())
66 | {
67 | fileNames.Add(folderItem.Path);
68 | }
69 | }
70 | else if (window.Document is IShellFolderViewDual document)
71 | {
72 | foreach (FolderItem folderItem in document.SelectedItems())
73 | {
74 | fileNames.Add(folderItem.Path);
75 | }
76 | }
77 | }
78 | return fileNames.Any() ? fileNames[0] : string.Empty;
79 | }
80 |
81 | private static string GetSelectedFileFromDesktop(IntPtr hwnd)
82 | {
83 | var processPointer = IntPtr.Zero;
84 | var virtualAllocPointer = IntPtr.Zero;
85 | try
86 | {
87 | var itemNames = new List();
88 | var processId = (uint)0;
89 | NativeMethods.GetWindowThreadProcessId(hwnd, out processId);
90 | var itemCount = NativeMethods.SendMessage(hwnd, NativeConstants.LVM_GETITEMCOUNT, 0, 0);
91 | processPointer = NativeMethods.OpenProcess(NativeConstants.PROCESS_VM_OPERATION | NativeConstants.PROCESS_VM_READ | NativeConstants.PROCESS_VM_WRITE, false, processId);
92 | virtualAllocPointer = NativeMethods.VirtualAllocEx(processPointer, IntPtr.Zero, 4096, NativeConstants.MEM_RESERVE | NativeConstants.MEM_COMMIT, NativeConstants.PAGE_READWRITE);
93 |
94 | for (int i = 0; i < itemCount; i++)
95 | {
96 | var buffer = new byte[256];
97 | var item = new LVITEM[1];
98 | item[0].mask = NativeConstants.LVIF_TEXT;
99 | item[0].iItem = i;
100 | item[0].iSubItem = 0;
101 | item[0].cchTextMax = buffer.Length;
102 | item[0].pszText = (IntPtr)((int)virtualAllocPointer + Marshal.SizeOf(typeof(LVITEM)));
103 | var numberOfBytesRead = (uint)0;
104 |
105 | NativeMethods.WriteProcessMemory(processPointer, virtualAllocPointer, Marshal.UnsafeAddrOfPinnedArrayElement(item, 0), Marshal.SizeOf(typeof(LVITEM)), ref numberOfBytesRead);
106 | NativeMethods.SendMessage(hwnd, NativeConstants.LVM_GETITEMW, i, virtualAllocPointer.ToInt32());
107 | NativeMethods.ReadProcessMemory(processPointer, (IntPtr)((int)virtualAllocPointer + Marshal.SizeOf(typeof(LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0), buffer.Length, ref numberOfBytesRead);
108 |
109 | var text = Encoding.Unicode.GetString(buffer, 0, (int)numberOfBytesRead);
110 | text = text.Substring(0, text.IndexOf('\0'));
111 | var result = NativeMethods.SendMessage(hwnd, NativeConstants.LVM_GETITEMSTATE, i, (int)NativeConstants.LVIS_SELECTED);
112 | if (result == NativeConstants.LVIS_SELECTED)
113 | {
114 | itemNames.Add(text);
115 | }
116 | }
117 |
118 | if (itemNames.Any())
119 | {
120 | var desktopDirectoryName = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
121 | var commonDesktopDirectoryName = Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory);
122 | var itemName = itemNames[0];
123 | var fileNames = Directory.GetFiles(desktopDirectoryName, itemName + ".*").ToList();
124 | fileNames.AddRange(Directory.GetFiles(commonDesktopDirectoryName, itemName + ".*"));
125 | if (fileNames.Any())
126 | {
127 | var fileName = fileNames[0];
128 | if (Path.GetExtension(fileName).ToLower() == ".lnk")
129 | {
130 | WshShell shell = new WshShell();
131 | IWshShortcut link = (IWshShortcut)shell.CreateShortcut(fileName);
132 | return link.TargetPath;
133 | }
134 | return fileName;
135 | }
136 | }
137 | return string.Empty;
138 | }
139 | finally
140 | {
141 | if (processPointer != IntPtr.Zero && virtualAllocPointer != IntPtr.Zero)
142 | {
143 | NativeMethods.VirtualFreeEx(processPointer, virtualAllocPointer, 0, NativeConstants.MEM_RELEASE);
144 | }
145 |
146 | if (processPointer != IntPtr.Zero)
147 | {
148 | NativeMethods.CloseHandle(processPointer);
149 | }
150 | }
151 | }
152 |
153 | public static bool IsChildWindow(IntPtr hwnd, IntPtr parentHwnd)
154 | {
155 | var result = false;
156 | var currentHwnd = hwnd;
157 | for ( ; ; )
158 | {
159 | if (currentHwnd == parentHwnd)
160 | {
161 | result = true;
162 | break;
163 | }
164 |
165 | if (currentHwnd == IntPtr.Zero)
166 | {
167 | result = false;
168 | break;
169 | }
170 |
171 | currentHwnd = NativeMethods.GetParent(currentHwnd);
172 | }
173 | return result;
174 | }
175 |
176 | public static string GetClassName(IntPtr hwnd)
177 | {
178 | var builder = new StringBuilder(1024);
179 | NativeMethods.GetClassName(hwnd, builder, builder.Capacity);
180 | var className = builder.ToString();
181 | return className;
182 | }
183 |
184 | public static IntPtr GetSysListView32()
185 | {
186 | if (Environment.OSVersion.Version.Major == 5)
187 | {
188 | var hwndProgman = NativeMethods.FindWindow("Progman", null);
189 | var hwndShell = NativeMethods.FindWindowEx(hwndProgman, IntPtr.Zero, "SHELLDLL_DefView", null);
190 | var hwnd = NativeMethods.FindWindowEx(hwndShell, IntPtr.Zero, "SysListView32", "FolderView");
191 | return hwnd;
192 | }
193 | else
194 | {
195 | var hwnd = IntPtr.Zero;
196 | NativeMethods.EnumWindows(new NativeMethods.EnumWindowProc((tophandle, topparamhandle) =>
197 | {
198 | var parent = NativeMethods.FindWindowEx(tophandle, IntPtr.Zero, "SHELLDLL_DefView", null);
199 | if (parent != IntPtr.Zero)
200 | {
201 | hwnd = NativeMethods.FindWindowEx(parent, IntPtr.Zero, "SysListView32", null);
202 | return false;
203 | }
204 |
205 | return true;
206 | }), IntPtr.Zero);
207 | return hwnd;
208 | }
209 | }
210 | }
211 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Win32WindowWrapper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Wlx2Explorer
5 | {
6 | class Win32WindowWrapper : IWin32Window
7 | {
8 | public IntPtr Handle { get; private set; }
9 |
10 | public Win32WindowWrapper(IntPtr handle)
11 | {
12 | Handle = handle;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Wlx2Explorer/Wlx2Explorer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {82A3A166-142C-4C62-8D57-6CF8678402AA}
9 | WinExe
10 | Properties
11 | Wlx2Explorer
12 | Wlx2Explorer
13 | v4.0
14 | Client
15 | 512
16 | 9
17 |
18 |
19 | x86
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 | true
28 |
29 |
30 | x86
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 |
38 |
39 | Wlx2Explorer.ico
40 |
41 |
42 | true
43 | bin\x64\Debug\
44 | DEBUG;TRACE
45 | full
46 | x64
47 | prompt
48 | MinimumRecommendedRules.ruleset
49 |
50 |
51 | bin\x64\Release\
52 | TRACE
53 | true
54 | pdbonly
55 | x64
56 | prompt
57 | MinimumRecommendedRules.ruleset
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Form
74 |
75 |
76 | MessageBoxForm.cs
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | Form
97 |
98 |
99 | AboutForm.cs
100 |
101 |
102 | Form
103 |
104 |
105 | SearchForm.cs
106 |
107 |
108 | Form
109 |
110 |
111 | ListerForm.cs
112 |
113 |
114 | Form
115 |
116 |
117 | MainForm.cs
118 |
119 |
120 | Form
121 |
122 |
123 | PluginSettingsForm.cs
124 |
125 |
126 | Form
127 |
128 |
129 | ProgramSettingsForm.cs
130 |
131 |
132 |
133 |
134 |
135 | AboutForm.cs
136 |
137 |
138 | MessageBoxForm.cs
139 |
140 |
141 | SearchForm.cs
142 |
143 |
144 | ListerForm.cs
145 |
146 |
147 | MainForm.cs
148 |
149 |
150 | PluginSettingsForm.cs
151 |
152 |
153 | ProgramSettingsForm.cs
154 |
155 |
156 | ResXFileCodeGenerator
157 | Resources.Designer.cs
158 | Designer
159 |
160 |
161 | True
162 | Resources.resx
163 | True
164 |
165 |
166 | SettingsSingleFileGenerator
167 | Settings.Designer.cs
168 |
169 |
170 | True
171 | Settings.settings
172 | True
173 |
174 |
175 | PreserveNewest
176 |
177 |
178 |
179 |
180 | {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}
181 | 1
182 | 0
183 | 0
184 | tlbimp
185 | False
186 | True
187 |
188 |
189 | {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}
190 | 1
191 | 1
192 | 0
193 | tlbimp
194 | False
195 | True
196 |
197 |
198 | {50A7E9B0-70EF-11D1-B75A-00A0C90564FE}
199 | 1
200 | 0
201 | 0
202 | tlbimp
203 | False
204 | True
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | PreserveNewest
219 |
220 |
221 |
222 |
223 |
224 | call "$(DevEnvDir)..\tools\vsdevcmd.bat"
225 | editbin.exe /NXCOMPAT:NO "$(TargetPath)"
226 | copy /Y "$(ProjectDir)Libs\*.dll" "$(TargetDir)"
227 |
228 |
229 |
236 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Wlx2Explorer.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexanderPro/Wlx2Explorer/da03c8aa3b6882362b2d772b46f7f2a2f8b3c7d5/Wlx2Explorer/Wlx2Explorer.ico
--------------------------------------------------------------------------------
/Wlx2Explorer/Wlx2Explorer.ini:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Wlx2Explorer/Wlx2Explorer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------