Inno Setup Calling DLL with string as parameter

2019-06-13 16:37发布

问题:

I'm getting a exception when I attempt to use my DLL from the Inno Setup script.

I think the problem is this line in the dll code:

StreamReader sreader = new StreamReader(newpath);

If I hard code the path as @"D:\source.txt", it doesn't crash. What should the string, representing the path to the source.txt file, look like when passed as an argument from the script?

DLL code:

using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.IO;
using System;
using System.Text;

namespace DotNet64
{
   public class InnSetDLL
   {
      [DllExport("test", CallingConvention = CallingConvention.StdCall)]
      public static bool test(
          [MarshalAs(UnmanagedType.LPStr)] string path,
          [MarshalAs(UnmanagedType.LPStr)] string fileName)
      {

         string original_path = path;
         string newpath = path + fileName;

         StreamReader sreader = new StreamReader(newpath);

         string line, newline;
         StreamWriter swriter = new StreamWriter(@"d:\newfile.ini");
         while ((line = sreader.ReadLine()) != null)
         {
            if (line.Contains("$(installdir)"))
            {

               string a = line.Replace("$(installdir)", path);
               newline = a.Replace(@"\\", @"\");
               swriter.WriteLine(newline);
            }
            else
            {
               swriter.WriteLine(line);
            }
         }

         sreader.Close();
         swriter.Close();

         return false;
      }
   }
}

Inno Setup script:

[Files]
Source: "DotNet64.dll"; Flags: dontcopy

[Code]
function test(path : String; name : String): Boolean;
external 'test@files:DotNet64.dll stdcall setuponly delayload';

procedure CurPageChanged(CurPageID: Integer);
var
  bres : Boolean;
begin
  if CurPageID = wpWelcome then begin
    bres := test('D:\','source.txt');
  end;
end;

回答1:

I assume you are (correctly) using Unicode version of Inno Setup.

In Unicode version of Inno Setup, string is a wide string. For wide string, you need to use UnmanagedType.LPWStr, not UnmanagedType.LPStr.


UnmanagedType.LPStr is Ansi string – equivalent of AnsiString in Inno Setup and string in Ansi version of Inno Setup.


Though as @mirtheil commented already, replacing a string in a text file can easily be implemented in Pascal Script: Replace a text in a file with Inno Setup.