Community
    • Login

    .Net versions

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    5 Posts 3 Posters 243 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • General CoderG
      General Coder
      last edited by General Coder

      Hi
      I just “upgraded” my visual studio C# plugin to more recent .Net but when I try to run the plugin I get message saying its not valid plugin. i mean this:

      Cannot load 64-bit plugin.
      
      *********.dll is not compatible with the current version of Notepad++.
      
      Do you want to remove this plugin from the plugins directory to prevent this message from the next launch?
      

      So I wonder if there is anything that can be done about that to make it load in NP?

      or do I just have to stick with .Net 4.8

      thx

      CoisesC rdipardoR 2 Replies Last reply Reply Quote 0
      • CoisesC
        Coises @General Coder
        last edited by

        @General-Coder

        I’m not familiar with C#, but messages like that usually occur either when you’re trying to load a 32-bit plugin in 64-bit Notepad++, or vice versa; or, the plugin fails to correctly implement the required interfaces. In addition to DllMain, these functions (from PluginInterface.h):

        // You should implement (or define an empty function body) those functions which are called by Notepad++ plugin manager
        extern "C" __declspec(dllexport) void setInfo(NppData);
        extern "C" __declspec(dllexport) const wchar_t * getName();
        extern "C" __declspec(dllexport) FuncItem * getFuncsArray(int *);
        extern "C" __declspec(dllexport) void beNotified(SCNotification *);
        extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam);
        
        // This API return always true now, since Notepad++ isn't compiled in ANSI mode anymore
        extern "C" __declspec(dllexport) BOOL isUnicode();
        

        must be implemented with the correct signatures, or loading will fail.

        General CoderG 1 Reply Last reply Reply Quote 3
        • rdipardoR
          rdipardo @General Coder
          last edited by

          @General-Coder said in .Net versions:

          do I just have to stick with .Net 4.8 [?]

          For modern .NET, have a look at https://github.com/npp-dotnet.

          Initial project setup is a bit involved; It’ll be easier when there’s a .NET project template on NuGet.

          Start with a new class library, e.g.,

          dotnet new classlib --name YourPluginProject
          

          Make sure the <TargetFramework> and <RuntimeIdentifiers> property specifies the Windows platform.

          Also make sure to set the <PublishAot> and <AllowUnsafeBlocks> properties, e.g.,

            <PropertyGroup>
          -   <TargetFramework>net9.0</TargetFramework>
          +   <TargetFramework>net9.0-windows</TargetFramework>
          +   <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
          +   <PublishAot>true</PublishAot>
          +   <RuntimeIdentifiers>win-arm64;win-x64</RuntimeIdentifiers>
            </PropertyGroup>
          

          Install the plugin template package:

          cd YourPluginProject
          dotnet add package Npp.DotNet.Plugin --prerelease
          

          Define your plugin in the main class file, e.g.,

          namespace YourPluginProject;
          
          using Npp.DotNet.Plugin;
          using System.Runtime.CompilerServices;
          using System.Runtime.InteropServices;
          
          public class Class1 : IDotNetPlugin
          {
              #region "Implement the plugin interface"
              /// <summary>
              /// This method runs when Notepad++ calls the 'setInfo' API function.
              /// You can assume the application window handle is valid here.
              /// </summary>
              public void OnSetInfo()
              {
                  // TODO: provide setup code, i.e., assign plugin commands to shortcut keys, load configuration data, etc.
                  // For example:
                  var shortcut = new ShortcutKey(Win32.TRUE, Win32.FALSE, Win32.TRUE, 123); // Ctrl + Shift + F12
                  Utils.SetCommand(
                      $"About {PluginName}",
                      () => Win32.MsgBoxDialog(
                          PluginData.NppData.NppHandle,
                          $"Information about {PluginName}\0",
                          $"{PluginName}",
                          (uint)(Win32.MsgBox.ICONASTERISK | Win32.MsgBox.OK)),
                      shortcut);
              }
          
              /// <summary>
              /// This method runs when Notepad++ calls the 'beNotified' API function.
              /// </summary>
              public void OnBeNotified(ScNotification notification)
              {
                  // TODO: provide callbacks for editor events and notifications.
                  // For example:
                  if (notification.Header.HwndFrom == PluginData.NppData.NppHandle)
                  {
                      uint code = notification.Header.Code;
                      switch ((NppMsg)code)
                      {
                          case NppMsg.NPPN_SHUTDOWN:
                              // clean up resources
                              PluginData.PluginNamePtr = IntPtr.Zero;
                              PluginData.FuncItems.Dispose();
                              break;
                      }
                  }
              }
          
              /// <summary>
              /// This method runs when Notepad++ calls the 'oOnMessageProc' API function.
              /// </summary>
              public NativeBool OnMessageProc(uint msg, UIntPtr wParam, IntPtr lParam)
              {
                  // TODO: provide callbacks for Win32 window messages.
                  return Win32.TRUE;
              }
              #endregion
          
              /// <summary>
              /// Object reference to the main class -- must be initialized statically!
              /// </summary>
              static readonly IDotNetPlugin Instance;
          
              /// <summary>
              /// The unique name of the plugin -- appears in the 'Plugins' drop-down menu
              /// </summary>
              static readonly string PluginName = "Your .NET SDK Plugin\0";
          
              /// <summary>
              /// The main constructor must be static to ensure data is initialized *before*
              /// the Notepad++ application calls any unmanaged methods.
              /// At the very least, assign a unique name to 'Npp.DotNet.Plugin.PluginData.PluginNamePtr',
              /// otherwise the default name -- "Npp.DotNet.Plugin" -- will be used.
              /// </summary>
              static Class1()
              {
                  Instance = new Class1();
                  PluginData.PluginNamePtr = Marshal.StringToHGlobalUni(PluginName);
              }
          
              #region "==================== COPY & PASTE *ONLY* ========================"
              [UnmanagedCallersOnly(EntryPoint = "setInfo", CallConvs = [typeof(CallConvCdecl)])]
              internal unsafe static void SetInfo(NppData* notepadPlusData)
              {
                  PluginData.NppData = *notepadPlusData;
                  Instance.OnSetInfo();
              }
          
              [UnmanagedCallersOnly(EntryPoint = "beNotified", CallConvs = [typeof(CallConvCdecl)])]
              internal unsafe static void BeNotified(ScNotification* notification)
              {
                  Instance.OnBeNotified(*notification);
              }
          
              [UnmanagedCallersOnly(EntryPoint = "messageProc", CallConvs = [typeof(CallConvCdecl)])]
              internal static NativeBool MessageProc(uint msg, UIntPtr wParam, IntPtr lParam)
              {
                  return Instance.OnMessageProc(msg, wParam, lParam);
              }
          
              [UnmanagedCallersOnly(EntryPoint = "getFuncsArray", CallConvs = [typeof(CallConvCdecl)])]
              internal static IntPtr GetFuncsArray(IntPtr nbF) => IDotNetPlugin.OnGetFuncsArray(nbF);
          
              [UnmanagedCallersOnly(EntryPoint = "getName", CallConvs = [typeof(CallConvCdecl)])]
              internal static IntPtr GetName() => IDotNetPlugin.OnGetName();
          
              [UnmanagedCallersOnly(EntryPoint = "isUnicode", CallConvs = [typeof(CallConvCdecl)])]
              internal static NativeBool IsUnicode() => IDotNetPlugin.OnIsUnicode();
              #endregion
          }
          

          Build the plugin:

          dotnet publish -c Release -r win-x64 -o $(PLUGIN_FOLDER_PATH)
          

          where $(PLUGIN_FOLDER_PATH) is the plugin’s installation path, e.g., %ProgramFiles%\Notepad++\plugins\YourPluginProject.

          (Basic) support for *.Windows.Forms is implemented, but your mileage may vary.

          General CoderG 1 Reply Last reply Reply Quote 3
          • General CoderG
            General Coder @Coises
            last edited by

            @Coises I used the C# plugin template which version is limited to 4.8. it did all the things for me but upgrading from there is the problem

            1 Reply Last reply Reply Quote 0
            • General CoderG
              General Coder @rdipardo
              last edited by

              @rdipardo Thanks! i didnt know that modern C# plugin support existed
              I’m probably going to give that a try, for now i’m just going with 4.8

              1 Reply Last reply Reply Quote 1
              • First post
                Last post
              The Community of users of the Notepad++ text editor.
              Powered by NodeBB | Contributors