diff --git a/.gitignore b/.gitignore
index bb6b332..e1d2199 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,6 +114,7 @@ UpgradeLog*.XML
*.pyc
Visual Studio Project Template C#/$projectname$.sln
-NppCSharpPluginPack/.vs
+**/.vs
+!NppCSharpPluginPack/Dependencies/x64
NppCSharpPluginPack/UpgradeLog.htm
!testfiles/**/*example*.log
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc5226f..13f12d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Avoid plugin crash when too-large int values are entered in the selection-remembering form.
- Holding down `Enter` in a multiline textbox does not add multiple new lines; it only adds one newline on keyup.
+## [0.0.4] - (UNRELEASED) YYYY-MM-DD
+
+### Added
+
+1. Make it much easier to [include third-party dependencies](/docs/README.md#loading-third-party-dependencies) in your plugin.
+
## [0.0.3] - 2024-02-26
### Added
diff --git a/ExampleDependency/ExampleClass.cs b/ExampleDependency/ExampleClass.cs
new file mode 100644
index 0000000..addd377
--- /dev/null
+++ b/ExampleDependency/ExampleClass.cs
@@ -0,0 +1,31 @@
+namespace ExampleDependency
+{
+ public class ExampleClass
+ {
+ public static int ExampleClassInstancesCreated = 0;
+ public string Name = "";
+ public int InstancesCreatedBeforeThis { get; private set; }
+
+ public ExampleClass(string name)
+ {
+ Name = name;
+ InstancesCreatedBeforeThis = ExampleClassInstancesCreated;
+ ExampleClassInstancesCreated = Add(ExampleClassInstancesCreated, 1);
+ }
+
+ public override string ToString()
+ {
+ return $"ExampleClass(\"{Name}\") ({InstancesCreatedBeforeThis} instances created before it)";
+ }
+
+ public static int Add(int x, int y)
+ {
+ return x + y;
+ }
+
+ public static int Subtract(int x, int y)
+ {
+ return x - y;
+ }
+ }
+}
diff --git a/ExampleDependency/ExampleDependency.csproj b/ExampleDependency/ExampleDependency.csproj
new file mode 100644
index 0000000..0d60b35
--- /dev/null
+++ b/ExampleDependency/ExampleDependency.csproj
@@ -0,0 +1,57 @@
+
+
+
+ Debug
+ x86
+ net4.8
+ AnyCPU;x64;x86
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;TRACE
+ prompt
+ 4
+ x86
+ true
+
+
+ none
+ true
+ bin\Release
+ prompt
+ 4
+ 512
+ x86
+ AllRules.ruleset
+ true
+
+
+ true
+ full
+ false
+ bin\Debug-x64
+ DEBUG;TRACE
+ prompt
+ 4
+ x64
+ true
+
+
+ none
+ true
+ bin\Release-x64
+ prompt
+ 4
+ 512
+ x64
+ AllRules.ruleset
+ true
+
+
+
+
+
+
diff --git a/ExampleDependency/ExampleDependency.sln b/ExampleDependency/ExampleDependency.sln
new file mode 100644
index 0000000..8f199b0
--- /dev/null
+++ b/ExampleDependency/ExampleDependency.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34330.188
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExampleDependency", "ExampleDependency.csproj", "{76493ED8-B97B-4C27-91EE-CE065270D87F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Debug|x64.ActiveCfg = Debug|x64
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Debug|x64.Build.0 = Debug|x64
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Debug|x86.ActiveCfg = Debug|x86
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Debug|x86.Build.0 = Debug|x86
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Release|x64.ActiveCfg = Release|x64
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Release|x64.Build.0 = Release|x64
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Release|x86.ActiveCfg = Release|Any CPU
+ {76493ED8-B97B-4C27-91EE-CE065270D87F}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5D7E4DE6-C9EA-4A10-A65B-AC464D1711B7}
+ EndGlobalSection
+EndGlobal
diff --git a/NppCSharpPluginPack/Dependencies/x64/ExampleDependency.dll b/NppCSharpPluginPack/Dependencies/x64/ExampleDependency.dll
new file mode 100644
index 0000000..9257d53
Binary files /dev/null and b/NppCSharpPluginPack/Dependencies/x64/ExampleDependency.dll differ
diff --git a/NppCSharpPluginPack/Dependencies/x86/ExampleDependency.dll b/NppCSharpPluginPack/Dependencies/x86/ExampleDependency.dll
new file mode 100644
index 0000000..9fbdb27
Binary files /dev/null and b/NppCSharpPluginPack/Dependencies/x86/ExampleDependency.dll differ
diff --git a/NppCSharpPluginPack/Forms/PopupDialog.cs b/NppCSharpPluginPack/Forms/PopupDialog.cs
index a8d1488..5fbcd5f 100644
--- a/NppCSharpPluginPack/Forms/PopupDialog.cs
+++ b/NppCSharpPluginPack/Forms/PopupDialog.cs
@@ -1,6 +1,7 @@
using NppDemo.Utils;
using Kbg.NppPluginNET;
using System.Windows.Forms;
+using ExampleDependency;
namespace NppDemo.Forms
{
@@ -21,10 +22,12 @@ private void ComboBox1EnabledCheckBox_CheckedChanged(object sender, System.Event
private void button1_Click(object sender, System.EventArgs e)
{
+
string msg = ComboBox1.Enabled
? $"ComboBox1 selected value = {ComboBox1.Text}"
: "ComboBox1 is disabled";
- MessageBox.Show(msg);
+ var exampleClassMember = new ExampleClass(msg);
+ MessageBox.Show(exampleClassMember.ToString());
}
///
diff --git a/NppCSharpPluginPack/Forms/SelectionRememberingForm.cs b/NppCSharpPluginPack/Forms/SelectionRememberingForm.cs
index 68e4c25..4ac16e4 100644
--- a/NppCSharpPluginPack/Forms/SelectionRememberingForm.cs
+++ b/NppCSharpPluginPack/Forms/SelectionRememberingForm.cs
@@ -1,16 +1,11 @@
using NppDemo.Utils;
using System;
using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Kbg.NppPluginNET;
using System.IO;
-using System.Runtime.CompilerServices;
namespace NppDemo.Forms
{
diff --git a/NppCSharpPluginPack/Main.cs b/NppCSharpPluginPack/Main.cs
index aa6b80d..db0573f 100644
--- a/NppCSharpPluginPack/Main.cs
+++ b/NppCSharpPluginPack/Main.cs
@@ -17,6 +17,7 @@
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
+using System.Reflection;
namespace Kbg.NppPluginNET
{
@@ -50,6 +51,9 @@ class Main
static internal void CommandMenuInit()
{
+ // first make it so that all references to any third-party dependencies point to the correct location
+ // see https://github.com/oleg-shilo/cs-script.npp/issues/66#issuecomment-1086657272 for more info
+ AppDomain.CurrentDomain.AssemblyResolve += LoadDependency;
// Initialization of your plugin commands
// with function :
@@ -97,7 +101,19 @@ static internal void CommandMenuInit()
}
- static internal void SetToolBarIcons()
+ private static Assembly LoadDependency(object sender, ResolveEventArgs args)
+ {
+ // Path.GetFullPath(".") will return the path to the Notepad++ executable
+ // I have *very rarely* seen it instead return another path, but in general this should work properly.
+ // Unfortunately Npp.notepad.GetNppPath() cannot be used here for reasons discussed in this comment by rdipardo:
+ // https://github.com/molsonkiko/NppCSharpPluginPack/issues/5#issuecomment-1982167513
+ string assemblyFile = Path.Combine(Path.GetFullPath("."), "plugins", PluginName, new AssemblyName(args.Name).Name) + ".dll";
+ if (File.Exists(assemblyFile))
+ return Assembly.LoadFrom(assemblyFile);
+ return null;
+ }
+
+ static internal void SetToolBarIcons()
{
string iconsToUseChars = settings.toolbar_icons.ToLower();
var iconInfo = new (Bitmap bmp, Icon icon, Icon iconDarkMode, int id, char representingChar)[]
diff --git a/NppCSharpPluginPack/NppCSharpPluginPack.csproj b/NppCSharpPluginPack/NppCSharpPluginPack.csproj
index 3179164..b7f65b1 100644
--- a/NppCSharpPluginPack/NppCSharpPluginPack.csproj
+++ b/NppCSharpPluginPack/NppCSharpPluginPack.csproj
@@ -145,6 +145,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -153,6 +168,10 @@
+
+
+ @(DEPENDENCY_DIR)\ExampleDependency.dll
+
@@ -191,37 +210,32 @@
-
+
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NppCSharpPluginPack/PluginInfrastructure/NppPluginNETHelper.cs b/NppCSharpPluginPack/PluginInfrastructure/NppPluginNETHelper.cs
index e1fc988..a15ac00 100644
--- a/NppCSharpPluginPack/PluginInfrastructure/NppPluginNETHelper.cs
+++ b/NppCSharpPluginPack/PluginInfrastructure/NppPluginNETHelper.cs
@@ -175,11 +175,14 @@ public enum DockMgrMsg : uint
//nmhdr.hwndFrom = hwndNpp;
//nmhdr.IdFrom = ctrlIdNpp;
- DMN_DOCK = (DMN_FIRST + 2),
- DMN_FLOAT = (DMN_FIRST + 3)
- //nmhdr.Code = DWORD(DMN_XXX, int newContainer);
- //nmhdr.hwndFrom = hwndNpp;
- //nmhdr.IdFrom = ctrlIdNpp;
+ DMN_DOCK = (DMN_FIRST + 2),
+ DMN_FLOAT = (DMN_FIRST + 3),
+ DMN_SWITCHIN = (DMN_FIRST + 4),
+ DMN_SWITCHOFF = (DMN_FIRST + 5),
+ DMN_FLOATDROPPED = (DMN_FIRST + 6),
+ //nmhdr.Code = DWORD(DMN_XXX, int newContainer);
+ //nmhdr.hwndFrom = hwndNpp;
+ //nmhdr.IdFrom = ctrlIdNpp;
}
[StructLayout(LayoutKind.Sequential)]
diff --git a/NppCSharpPluginPack/Properties/AssemblyInfo.cs b/NppCSharpPluginPack/Properties/AssemblyInfo.cs
index 86dc2a4..7a1427c 100644
--- a/NppCSharpPluginPack/Properties/AssemblyInfo.cs
+++ b/NppCSharpPluginPack/Properties/AssemblyInfo.cs
@@ -28,5 +28,5 @@
// Build Number
// Revision
//
-[assembly: AssemblyVersion("0.0.3.0")]
-[assembly: AssemblyFileVersion("0.0.3.0")]
+[assembly: AssemblyVersion("0.0.3.1")]
+[assembly: AssemblyFileVersion("0.0.3.1")]
diff --git a/PluginPackArchitecture.md b/PluginPackArchitecture.md
index d7f5464..41d914b 100644
--- a/PluginPackArchitecture.md
+++ b/PluginPackArchitecture.md
@@ -35,7 +35,7 @@ Many of the files in the [PluginInfrastructure folder](/NppCSharpPluginPack/Plug
The way to regenerate the auto-generated portions of these code is to download the Notepad++ source code from master and run the Python scripts in [ToolsForMaintainersOfTheProjectTemplate](/ToolsForMaintainersOfTheProjectTemplate/) folder. Read the documentation of those scripts if you're still unsure how to proceed.
-## Plugins using this pluginpack (or the original)
+## Plugins using this pluginpack (or kbilsted's original)
* https://github.com/kbilsted/NppPluginGuidHelper
* https://github.com/zkirkland/FirstUpper
diff --git a/docs/README.md b/docs/README.md
index 5070162..0a7d0ce 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -137,6 +137,29 @@ Here are some important ways that the popup dialog differs from other dialogs:
![Popup dialog](/docs/popup%20dialog.PNG)
+## Loading third-party dependencies ##
+
+There are two ways that I (Mark J. Olson) know of to incorporate third-party dependencies into the project, using [NuGet](https://www.nuget.org/) and loading locally installed DLL's. Each will be covered below.
+
+Regardless of which type of dependency you use, __make sure that the depenendencies work for both 32-bit and 64-bit Notepad++.__
+
+Note that the first version of this project to directly support 3rd-party DLL's in this way is `0.0.3.1`.
+
+### Including NuGet packages in your project ###
+
+I have tested this (as of version `0.0.3.1`) by installing [ExcelDataReader 3.6.0](https://www.nuget.org/packages/ExcelDataReader/3.6.0), adding some ExcelDataReader method calls to the [PopupDialog](#popup-dialog), and verifying that the method calls run successfully.
+
+1. Install the NuGet package. In Visual Studio, this entails going to `Project->Manage NuGet packages...` from the main menu, then installing a package.
+2. Build the project as normal. The NuGet package should be usable as expected.
+
+### Including locally installed DLL's in your project ###
+
+This is demonstrated with the [ExampleDependency](/ExampleDependency) example dependency, which is referenced in the [Popup Dialog](/NppCSharpPluginPack/Forms/PopupDialog.cs).
+
+1. Add a *64-bit* build of the DLL to the [NppCSharpPluginPack\Dependencies\x64](/NppCSharpPluginPack/Dependencies/x64) directory.
+2. Add a *32-bit* build of the DLL to the [NppCSharpPluginPackDependencies\x86](/NppCSharpPluginPack/Dependencies/x86) directory.
+3. Build the project for 64-bit and 32-bit Notepad++. Verify that any 3rd-party DLL's are usable as normal.
+
## Running tests ##
I (Mark J. Olson) believe that without a robust automated test suite, it is hard to make major changes to any large project without breaking things unexpectedly. Over the course of developing my JsonTools plugin, I developed a strategy for running automated tests and performance benchmarks inside of Notepad++.
diff --git a/most recent errors.txt b/most recent errors.txt
index 0655164..95e65f2 100644
--- a/most recent errors.txt
+++ b/most recent errors.txt
@@ -1,4 +1,4 @@
-Test results for CSharpPluginPack v0.0.2.4 on Notepad++ 8.6.4 64bit
+Test results for CSharpPluginPack v0.0.3.1 on Notepad++ 8.6.4 64bit
NOTE: Ctrl-F (regular expressions *on*) for "Failed [1-9]\d*" to find all failed tests
No tests failed
=========================
@@ -21,8 +21,8 @@ Testing Performance of something
Performance tests for My benchmarks (test1)
=========================
-To run query "foo" on file of size 7913 into took 0 +/- 0 ms over 32 trials
-Query times (ms): 0.002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+To run query "foo" on file of size 7913 into took 0 +/- 0.001 ms over 32 trials
+Query times (ms): 0.003, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Preview of result: Preview of result
=========================
Performance tests for My benchmarks (test2)