Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# InnoSetup DLL卸载_C#_Dll_Callback_Inno Setup - Fatal编程技术网

C# InnoSetup DLL卸载

C# InnoSetup DLL卸载,c#,dll,callback,inno-setup,C#,Dll,Callback,Inno Setup,我有一个InnoSetup,在那里我加载了一个C#DLL。安装程序在安装结束时挂断。 我在stackoverflow上发现了一个线程,里面似乎有一些很好的信息,但我没有经验获得提供的信息 my DLL的基本功能是: 在某些线程中解压*.zip文件 通过回调向innoSetup提供反馈 Inno会发生什么: 启动导出的DLL方法 接收回拨 解压完成后,卸载DLL 但DLL似乎从未卸载过。 我通过一个TimerEvent进行了测试,它每5秒启动一次,计时器从不停止 以下是一段代码片段: 创新: C

我有一个InnoSetup,在那里我加载了一个C#DLL。安装程序在安装结束时挂断。 我在stackoverflow上发现了一个线程,里面似乎有一些很好的信息,但我没有经验获得提供的信息

my DLL的基本功能是:

  • 在某些线程中解压*.zip文件
  • 通过回调向innoSetup提供反馈
  • Inno会发生什么:

  • 启动导出的DLL方法
  • 接收回拨
  • 解压完成后,卸载DLL
  • 但DLL似乎从未卸载过。 我通过一个TimerEvent进行了测试,它每5秒启动一次,计时器从不停止

    以下是一段代码片段: 创新:

    C#:


    有人知道为什么我的安装程序最终会冻结,为什么DLL从未卸载,或者为什么它一直在运行吗?我试图释放C#part使用的所有数据实际上我认为您没有正确调用innocallback.dll-存在目录不匹配(您是从{tmp}调用它,但它被声明为@files:)

    {tmp}文件夹中是否有innocallback.dll?在调用UnloadDLL之前立即检查它。并且不需要有两个调用来UnloadDLL

    正确的用法应该是:

    procedure DllFunc; external 'DllFunc@{app}\MyDll.dll stdcall uninstallonly';
    
    ...
    
    begin
      // Call DllFunc
      DllFunc;
    
      // Unload the DLL
      UnloadDLL(ExpandConstant('{app}\MyDll.dll'));
    
      // Now we can delete the DLL
      DeleteFile(ExpandConstant('{app}\MyDll.dll'));
    end;
    
    因此dll被复制到{app}文件夹中(在[Files]部分)

    第二件事:

    永远不要比较浮点数、进度和类似的东西是否相等。 进度可能是非线性的,因此可能会在值105处结束

    使用

    如果(进度>=100),则开始


    我终于找到了我的设置挂起的原因。我无法描述原因,因为我无法查看微软的资料来源,但我把范围缩小到计时器对象

    以下是我正在做的一些背景工作: 我编写了一个C#Dll,并在该Dll的帮助下公开了一个静态方法

    在sherlock软件的InnoCallback库的帮助下,我从Inno设置调用这个公开的方法

    我将回调方法传递给我的公开方法,以便接收状态更新。在此,我提供一个工作示例:

    Inno安装程序的回调是从计时器调用的。 这就是问题所在。计时器对象,即使它被停止并设置为NULL,也会继续执行阻止Inno设置完成的操作。 我自己在thread对象的帮助下编写了一个计时器,它比计时器工作得更好。 此解决方案并不完美,但可以在设置过程中使用线程


    如果将来有人有更多信息,请随时使用下面的评论部分。

    如果我有两个DLL,我真的需要只调用一次卸载DLL吗?我觉得这有点奇怪。根据你说得对的进度,我应该检查它是否高于或等于100。为了测试的目的,我创建了一个版本,它只给我100作为testvalue,所以我只将它与之进行了比较;)不,你是对的,你需要为两个单独的DLL调用两次,我的错-我没有注意到你正在卸载两个不同的DLL:)UnloadDLL()在我的用例中不起作用。请参阅此相关问题:您还记得我什么时候不允许从工作线程访问UI控件吗?这可能就是后果。您必须以某种方式将代码与主线程同步。您不能仅仅从工作线程调用回调并访问主线程的控件。这是即使在纯C应用程序中也无法做到的。我知道你是对的:)但谢谢你提醒我我错了:D@TLama顺便说一句,它现在可以与一个线程一起工作,但我的完成屏幕最终会重置它的图形。但没有冻结任何东西。我正在考虑如何在inno安装程序中单独完成这项工作,但inno安装程序不提供线程。当我有一个解决方案时,我会在这里提供它
        [DllExport("ReadZipEx", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static int ReadZipEx(string xml, ReportProgress repoProg)
        {
          //start threads
          //start timers which fire the callback
        }
    
    procedure DllFunc; external 'DllFunc@{app}\MyDll.dll stdcall uninstallonly';
    
    ...
    
    begin
      // Call DllFunc
      DllFunc;
    
      // Unload the DLL
      UnloadDLL(ExpandConstant('{app}\MyDll.dll'));
    
      // Now we can delete the DLL
      DeleteFile(ExpandConstant('{app}\MyDll.dll'));
    end;