0
votes

I have created dll file using C# Utils.dll which content function replace_string within the class StringUtils. The function is successfully call and give result when call within the console application. Now, I have included the dll file in plugins/ansi folder within NSIS.

I have tried to call the function as :

Utils.StringUtils::replace_string "E:\\test\\test.txt" 'abcd' 'efgh'

I have also tried using CLR

 CLR::Call /NOUNLOAD Utils.dll Utils.StringUtils replace_string 3 "E:\\test\\test.txt" 'abcd' 'efgh'

And again with System call

System::Call 'Utils::StringUtils.replace_string("E:\\test\\test.txt", "abcd", "efgh");'

But i got errors while compiling the nsi file. What could be the correct implementation of function in dll file at NSIS?

C# Code :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.IO;


    namespace Utils
    {
        public class StringUtils
        {

            public StringUtils()
            {
            }   
            /// 
            /// Replace the data in the Huge files searching and replacing chunk        
            /// by chunk. It will create new file as filepath + ".tmp" file with        
            /// replaced data        
            /// 
            /// Path of the file
            /// Text to be replaced
            /// Text with which it is replaced        
            public static void replace_string(string filePath, string replaceText, string withText)
            {
                StreamReader streamReader = new StreamReader(filePath);
                StreamWriter streamWriter = new StreamWriter(filePath + ".tmp");

                while (!streamReader.EndOfStream)
                {
                    string data = streamReader.ReadLine();
                    data = data.Replace(replaceText, withText);

                    data = Regex.Replace(data, replaceText, withText);

                    streamWriter.WriteLine(data);
                }

                streamReader.Close();
                streamWriter.Close();
            }

            public static void print_text()
            {
                Console.WriteLine("test");
                Console.ReadKey();
            }
        }
    }

Console Application Program:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Utils;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                StringUtils.replace_string("E:\\test\\test.txt", "abcd", "efgh");

                //Class1.print_text();
            }
        }
    }

Here i have called the replace_string function from the console application and it successfully executed and give the correct result where as when called within NSIS outputs error.

2
System::Call only knows about plain C/Win32 functions... - Anders
How about the second example using CLR doesn't work for me then... - NavaStha
Just saying it does not work is not helpful, we need to know compiler error messages etc... - Anders
@Anders it is not the error from compiling, its from while executing, Try yourself - NavaStha

2 Answers

0
votes

NSIS itself can only execute C dll's. But maybe this plugin will help you:

http://nsis.sourceforge.net/Call_.NET_DLL_methods_plug-in

0
votes

OK, I saw the real Problem:

The CLR PlugIn is built with the .NET Framework 2.0. With this Version it is not possible to start Libraries that were built with newer Versions of the .NET Framework. In your C# Code you have an (unneeded) Line using System.Linq;, so your .NET Library is built with Version 3.5 or higher.

You can ensure to compile your library with the Version 2.0 with this command line call (adapt the file names for your environment):

C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc /t:library /out:Utils.dll Utils.cs

If you are using Visual Studio, you can select the Framework in the options of the project.

If you need to use the Library with a .NET Version newer than 2.0 you can recompile the CLR Plugin. The Source code and the proejct file are included in the Zip File.


Here the old ideas you should still take care of:

According to your C# Code some things could go wrong there as there is now error/exception handling done.

Some of the problems that could end in an exception are:

  • file not available
  • no access to file
  • no rights to create the .tmp file

Another Question:

Does calling the second function "print_text()" from NSIS work or does it throw the same exception?

Call it in this way:

CLR::Call /NOUNLOAD Utils.dll Utils.StringUtils print_text 0

And a third thing: In NSIS you don't have to double the \ in a string, so your call would be

CLR::Call /NOUNLOAD Utils.dll Utils.StringUtils replace_string 3 "E:\test\test.txt" 'abcd' 'efgh'