My plugin crashes because of a C# NuGet



  • Hi, im trying to write a plugin with c#. The plugin connects to a server and gets json data and deserialize the data .It works succesfully on c# . before i tried to convert it to a npp plugin .

    I noticed the reason of plugins crash , notepad++ cannot use or read a c# nuget named newtonsoft.json and crashes. But if i dont use that NuGet i cant use deserialization .Whole program written with that NuGet and my boss dont want to change it. So what should i do ? Is there any solution to get this plugin worked with newtonsoft.json NuGet?

    pluginCrash.PNG



  • @Yunus-Emre-Kütükçü

    I doubt that npp crashes just because you use some C# library
    in your C# created plugin. I assume that it is caused by a
    incorrect handling of pointers, but you didn’t give enough
    information to identify the source of the problem.



  • using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Net.Http;
    using System.Text;
    using System.Windows.Forms;

    namespace Kbg.NppPluginNET
    {
    public partial class getScript : Form
    {
    Microsoft.Win32.RegistryKey key;
    List<Project> projects;
    List<Scripts> scripts;

        string URL;
        string TOKEN;
    
        public class Project : IEquatable<Project>
        {
       [JsonProperty]
            public string name { get; set; }
           [JsonProperty]
            public string dsc { get; set; }
           [JsonProperty]
            public int id { get; set; }
    
            public bool Equals(Project other)
            {
                if (other == null) return false;
                return (this.id.Equals(other.id));
            }
    
            public override bool Equals(object obj)
            {
                if (obj == null) return false;
                Project objAsPart = obj as Project;
                if (objAsPart == null) return false;
                else return Equals(objAsPart);
            }
    
            public override string ToString()
            {
                return "ID: " + id + "Name: " + name;
            }
            public override int GetHashCode()
            {
                return id;
            }
        }
    
        public class Scripts
        {
            public string name { get; set; }
            public string dsc { get; set; }
            public string id { get; set; }
    
        }
        public getScript()
        {
            InitializeComponent();
            key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("insAddin");
            if (key != null)
            {
                URL = key.GetValue("BaseUrl").ToString();
                TOKEN = key.GetValue("Token").ToString();
                HttpClient client = new HttpClient();
    
                Uri result = null;
                Uri.TryCreate(URL, UriKind.Absolute, out result);
                if (result != null)
                {
                    if (result.IsAbsoluteUri)
                    {
                        read(URL, TOKEN, "/projects");
                    }
                }
            }
        }
    
        public async void read(string URL, string TOKEN, string relativeAddress, string prms = "")
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Add("X-Auth-Token", TOKEN);
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            HttpResponseMessage response = await client.GetAsync(URL + relativeAddress + prms);
           if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                string responseBody;
                switch (relativeAddress)
                {
                    case "/projects":
                        responseBody = await response.Content.ReadAsStringAsync();
                        projects = JsonConvert.DeserializeObject<List<Project>>(responseBody);
              
                        for (int i = 0; i < projects.Count; i++)
                        {
                            comboBoxProjects.Items.Add(projects[i].name);
                        }
                        break;
    
                     case "/scripts":
                        responseBody = await response.Content.ReadAsStringAsync();
                      scripts = JsonConvert.DeserializeObject<List<Scripts>>(responseBody);
                        for (int i = 0; i < scripts.Count; i++)
                        {
                            comboBoxScripts.Items.Add(scripts[i].name);
                        }
                        break;
    
                    default:
                        break;
                }
            }
            else
            {
                MessageBox.Show(new Form { TopMost = true }, "Response Error" + response.ToString());
            }
        }
    

    if i comment JsonConvert section in read function, plugin runs without the data i wanted .Just throwing nullreferanceexpeption but it doesnt matter



  • Also if i uncomment the sections i mentioned program didnt even get in the read method, just crashes



  • @Yunus-Emre-Kütükçü
    First of all, I would like to clarify that I am not a C# developer.
    I recently started taking my first C# steps, but I don’t have a
    basic understanding of this programming language.

    If it crashes, even if your code doesn’t call the read method,
    doesn’t that mean the problem is somewhere else?
    Have you tried building the C# example plugin that comes with
    it? Is this crashing as well? If so, you might think about reporting a bug.
    Is your plugin project open source so one can try to figure out what’s going on?



  • I am a C# developer and I am also familiar with the use of nuget packages and the newtonsoft json package in particular, and what you need to check is that you are copying the relevant newtonsoft json .dll file from the package to the plugin directory under notepad++ that you are putting your plugin dll file. Without those newtonsoft json .dll file locally it is probably unable to find it.

    The file you need to copy will be Newtonsoft.Json.dll, and should be in the bin folder of wherever your c# project is building to.



  • I copied package to plugin directory but still having same error. I think @Ekopalypse is right. Problem seems to be elsewhere. Also I noticed when I debugging , program gets in the read function until the if(response.StatusCode ==… line and it goes to my main function ,creates my form then it enters the read function again, if i commented projects = JsonConvert.DeserializeObject<List<Project>>(responseBody); and script = JsonConvert… . sections . I couldnt figure out why is that happening



  • @Ekopalypse I wish it was open source . Program gets data from admin panel and gives permission to change all data. Because of that I cant share the whole code



  • @Yunus-Emre-Kütükçü main class* not function



  • @Yunus-Emre-Kütükçü

    I downloaded the latest pre-release and installed the template accordingly.

    Opened a new Notepad++ project in VS2019 and added a button to the frmMyDlg.cs.

    Added/modified the following code

        public partial class frmMyDlg : Form
        {
            static IScintillaGateway editor = new ScintillaGateway(PluginBase.GetCurrentScintilla());
            public frmMyDlg()
            {
                InitializeComponent();
            }
    
            private void frmMyDlg_Load(object sender, EventArgs e)
            {
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                string text = System.IO.File.ReadAllText(@"shortcuts.xml");
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(text);
    
                string json = JsonConvert.SerializeXmlNode(doc);
                editor.SetText(json);
            }
        }
    

    After building and running it crashed when I pressed the button.
    I investigated what was happening with loading the necessary dlls with procmon and found that it was
    NOT looking in the plugins directory to find the
    Newtonsoft.Json.dll, but instead was looking in the root directory.
    I copied Newtonsoft.Json(.dll/.xml) into the directory and ran it again and it worked

    18c4c935-afd9-43e3-bec8-12940ae4eeaf-image.png

    I don’t know what needs to be done to load the Newtonsoft.Json.dll from another directory, but I’d be surprised if it couldn’t be done.



  • It worked ! Thanks a lot



  • From the Home page of NotepadPlusPlusPluginPack.Net

    References
    The prefered way to use dependencies is via References, in the best-case through NuGet.
    
    Via NuGet you are able to add packages to your project, certain versions etc. through a global repository. Package information is stored in your project and other developers can gather the same, correct versions through the global repository without committing masses of data.
    
    To use included references in your compiled plugin you need to merge these into the .dll as Notepad++ is not fond of locating non-plugin .dll's in its folder. ILMerge was developed for the purpose of merging managed libraries. It can be installed via NuGet and used manually.
    
    The best way is to install MSBuild.ILMerge.Task via NuGet in your plugin project. It will include ILMerge as dependency and attach itself to your Visual Studio build process. By that, with every build you compile a merged plugin .dll including all your custom references to use. ILMerge will add configuration files to your project: ILMerge.props and ILMergeOrder.txt. Refer to the official homepage for more information about the configuration possibilities.
    
    Note: To use ILMerge in your plugin you have to change the Target Framework of your plugin project to at least .NET Framework 4.0 (CP). ILMerge can work with .NET 3.5 and below, but requires additional configuration and adaptation. If you do not required the extreme backwards compatibility, upgrade the .NET Framework target as quick and easy solution.
    

Log in to reply