当前位置: 首页 > 知识库问答 >
问题:

将WinForms表单嵌入Inno安装向导

曹和正
2023-03-14

我需要将WinForms表单(边框样式= 无)嵌入到Inno设置向导中,并且遇到了问题。

这是一个Inno安装脚本:

procedure EmbedConfiguratorForm(parentWnd: HWND);
  external 'EmbedConfiguratorForm@files:configurator.dll stdcall';

procedure InitializeWizard();
var
  cfgPageHandle: HWND;
begin
  cfgPageHandle := CreateCustomPage(wpSelectDir, 
    'Configuration', 
    ExpandConstant(description)).Surface.Handle;
  EmbedConfiguratorForm(cfgPageHandle);
end;

下面是一个 C# 代码:

class WizardWindow : IWin32Window
{
    public WizardWindow(IntPtr handle)
    {
        Handle = handle;
    }

    public WizardWindow(int handle) : this(new IntPtr(handle))
    {
    }

    public IntPtr Handle { get; private set; }
}

public static class MainClass
{
    [DllExport("EmbedConfiguratorForm", CallingConvention.StdCall)]
    public static void EmbedConfiguratorForm(int parentWnd)
    {
        // System.Diagnostics.Debugger.Launch();
        ConfiguratorForm form = new ConfiguratorForm();
        form.Show(new WizardWindow(parentWnd));
    }
}

它可以工作,但不像预期的那样。安装程序加载后,它会自动从< code>configurator.dll调用< code > EmbedConfiguratorForm ,该表单会显示,但不会进入安装向导页面。它显示在后面(见截图)。那么我做错了什么?

共有1个答案

谯皓君
2023-03-14

解决了。

解决方案是从DLL返回新窗口(表单)的句柄,并使用user32.SetParentWinAPI函数强制将表单嵌入向导。这里有一段代码。

C#:

namespace configurator
{
    class WizardWindow : IWin32Window
    {
        public WizardWindow(IntPtr handle)
        {
            Handle = handle;
        }

        public WizardWindow(int handle) : this(new IntPtr(handle))
        {
        }

        public IntPtr Handle { get; private set; }
    }

    public static class MainClass
    {
        private static ConfiguratorForm _configuratorForm;

        [DllExport("EmbedConfiguratorForm", CallingConvention.StdCall)]
        public static IntPtr EmbedConfiguratorForm(int parentWnd)
        {
            _configuratorForm = new ConfiguratorForm();
            _configuratorForm.Show(new WizardWindow(parentWnd));
            return _configuratorForm.Handle;

        }

        [DllExport("CloseConfiguratorForm", CallingConvention.StdCall)]
        public static void CloseConfiguratorForm()
        {
            if (_configuratorForm != null)
            {
                _configuratorForm.Close();
                _configuratorForm.Dispose();
                _configuratorForm = null;
            }
        }
    }
}

创新安装脚本:

[Code]
const
  description = 'my page description';

var
  configFile: string;
  configuratorPage: TWizardPage;

function EmbedConfiguratorForm(parentWnd: HWND): HWND;
external 'EmbedConfiguratorForm@files:configurator.dll stdcall';

procedure CloseConfiguratorForm();
external 'CloseConfiguratorForm@files:configurator.dll stdcall';

function SetParent(hWndChild, hWndNewParent: HWND): HWND;
external 'SetParent@user32.dll stdcall';

procedure InitializeWizard();
begin
  configuratorPage := CreateCustomPage(wpSelectDir, 
    'Title', 'Description');
end;

procedure ShowConfigurationStep();
var
  cfgPageHandle: HWND;
  cfgWinHandle: HWND;
begin
  cfgPageHandle := configuratorPage.Surface.Handle;
  cfgWinHandle := EmbedConfiguratorForm(cfgPageHandle);
  SetParent(cfgWinHandle, cfgPageHandle);
end;

procedure CurPageChanged(CurPageId: Integer);
begin
  if (CurPageId = configuratorPage.ID) then
  begin
    ShowConfigurationStep();
  end else
  begin
    CloseConfiguratorForm(); // here we can make some optimization like checking previos page
  end;
end;

procedure DeinitializeSetup();
begin
  CloseConfiguratorForm();
end;

关于C#DLL的注意事项:
它使用Un的导出Nuget数据包(包含DLLExportAt的)。

关于Inno安装脚本的注意事项:
初始化向导函数中我们只需要创建新页面,但是DLL调用我们需要实现到CurPageChanged中以确保我们的页面现在被打开。

经过一些研究工作,我创建了一个小样本项目解释双向集成。Net和InnoSetup

https://github.com/sharpcoder7/innoGlue.net

 类似资料:
  • 我有两个二进制文件,必须为它们创建一个服务。我尝试了一个解决方案,使用“SC创建”从如何安装Windows服务与Inno安装?

  • 问题内容: 我正在尝试通过Inno Setup(以及另一个应用程序)安装最新的平台(x64或x86)合适的Java Runtime Environment。我找到了一些脚本示例,这些脚本示例说明了如何检测版本并在正确的情况下进行安装并使其适应我的需要,但我一直遇到以下问题: 无法打开文件“ path \ to \ JREInstall.exe”: CreateProcess失败:代码5: 拒绝访问

  • 引用 Setup.nsi 的内容: !addPluginDir ".\" !include "MUI2.nsh" !include "WinVer.nsh" !include "TextFunc.nsh" Name "测试程序" Caption "$(^NameDA) 1.0" OutFile Setup.exe ;SetFont "Tahoma" 8 InstallDir $TEMP Re

  • 我想用Inno Setup创建一个安装程序,这是我第一次使用这个工具。< br >我尝试做的是用一个更详细的自制安装程序(指Setup.exe里面的Setup.exe)包装一个现有软件的现有安装程序。 到目前为止的研究后,对我有用的是要求安装程序(Inno Setup *.exe)运行随附的安装程序(实际软件设置)。 为什么我需要另一个安装程序?因为我想给它一些额外的功能。 特别是:我想在安装结束

  • 然后出现欢迎界面,点击下一步:

  • 遇到此问题时,我正在尝试使用 Inno Setup 创建安装程序,其他所有内容都在安装,但注册表项未安装在当前用户中。我发现了这个有用的主题(非常感谢! Inno 设置 为登录用户(非管理员用户)创建注册表项 这解决了添加注册表项的问题,如下所示: 我的问题: 指的是管理员用户(管理员)而不是本地用户(测试): 它添加了:HKCU\Software\myprinter OutputFile REG