在NSIS中调用外部dll函数

在NSIS中调用外部dll函数,nsis,Nsis,我使用C Utils.dll创建了dll文件,其中的内容函数替换类StringUtils中的\u字符串。该函数已成功调用,并在控制台应用程序内调用时给出结果。现在,我已经将dll文件包含在NSIS中的plugins/ansi文件夹中 我尝试将函数调用为: Utils.StringUtils::replace_string "E:\\test\\test.txt" 'abcd' 'efgh' 我也尝试过使用CLR CLR::Call /NOUNLOAD Utils.dll Utils.Stri

我使用C Utils.dll创建了dll文件,其中的内容函数替换类StringUtils中的\u字符串。该函数已成功调用,并在控制台应用程序内调用时给出结果。现在,我已经将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输出错误中调用时。

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


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

CLR插件是使用.NET Framework 2.0构建的。使用此版本,无法启动使用较新版本的.NET Framework构建的库。在C代码中,使用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,则可以在项目的选项中选择框架

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

这里是你仍然应该注意的旧观念:

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

可能导致异常的一些问题包括:

文件不可用 无法访问文件 没有创建.tmp文件的权限 另一个问题:

调用第二个函数是从NSIS打印文本还是引发相同的异常

这样称呼它:

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'

System::Call只知道普通的C/Win32函数……那么,第二个使用CLR的示例对我来说不起作用……仅仅说它不起作用是没有帮助的,我们需要知道编译器错误消息等等。@Anders这不是编译时的错误,而是执行时的错误,我已经根据你发送的url进行了尝试,包括插件中的clr.dll,但对我无效。你能再精确一点吗?它以哪种方式不起作用?编译时出错了吗?什么错误或执行时出错了吗?也许您可以泄露您收到的错误消息的秘密?在.dll方法中出错,由于调用的目标而发生异常如果您像原始帖子中的示例那样调用您的方法,则必须对其进行更改。在函数名之后,必须输入参数3的数量,然后输入参数:CLR::Call/NOUNLOAD Utils.dll Utils.StringUtils replace_string 3 E:\\test\\test.txt“abcd”“efgh”。请参阅给定的链接以供参考。感谢您的回复。我还附加了控制台应用程序,在这里我调用了这个函数。当程序被执行时,它会以正确的输出成功。这意味着文件可用,可以访问文件,有权创建.tml文件。“我认为函数定义中肯定缺少什么,但无法找到它。”纳瓦斯塔用一个经过测试的解决方案更新了我的答案。