在NSIS中调用外部DLL函数

时间:2013-12-09 11:09:08

标签: nsis

我使用C# Utils.dll 创建了dll文件,其中 StringUtils 类中的内容函数 replace_string 。在控制台应用程序中调用时,该函数成功调用并给出结果。现在,我已将dll文件包含在NSIS中的plugins / ansi文件夹中。

我试图将该函数称为:

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

我也尝试过使用CLR

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

再次使用系统调用

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

但是我在编译nsi文件时遇到了错误。什么可以在NSIS的dll文件中正确实现函数?

C#代码:

    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();
            }
        }
    }

控制台应用程序:

    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();
            }
        }
    }

这里我从控制台应用程序中调用了replace_string函数并成功执行并给出了正确的结果,就像在NSIS中调用时输出错误一样。

2 个答案:

答案 0 :(得分:0)

NSIS本身只能执行C dll。但也许这个插件会帮助你:

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

答案 1 :(得分:0)

好的,我看到了真正的问题:

CLR PlugIn是使用.NET Framework 2.0构建的。使用此版本,无法启动使用较新版本的.NET Framework构建的库。在您的C#代码中,您有一个(不需要的)行using System.Linq;,因此您的.NET库是使用的 3.5或更高版本。

您可以使用此命令行调用确保使用2.0版编译库(调整环境的文件名):

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

如果您使用的是Visual Studio,则可以在项目选项中选择框架。

如果您需要使用比2.0更新的.NET版本的库,您可以重新编译CLR插件。源代码和proejct文件包含在Zip文件中。


这里你仍然应该关注旧观点:

根据您的C#代码,有些事情可能会出错,因为现在已经完成了错误/异常处理。

可能以例外结束的一些问题是:

  • 文件不可用
  • 无法访问文件
  • 无权创建.tmp文件

另一个问题:

从NSIS调用第二个函数“print_text()”是否有效或是否抛出相同的异常?

以这种方式调用它:

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

还有第三件事:在NSIS中,您不必将字符串中的\加倍,因此您的调用将是

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