c# - Inno Setup .NET DLL 调用在 64 位中有效,在 32 位中失败

标签 c# .net inno-setup dllexport

我在 SQL SMO 库中编写了一个简单的接口(interface),因此我可以在安装过程中从 Inno Setup 脚本停止和启动 SQL Server。我的开发机器是 64 位处理器机器。托管代码是使用 DllExport for .Net 在 Visual Basic 中编写的,面向 .NET 4.0 并针对 x86 平台进行编译。我使用的是 Inno Setup 5.5.9 Unicode 版本。

设置可执行文件在我的开发机器和我尝试过的其他 64 位处理器上运行良好。当我在 32 位处理器系统上运行可执行文件时出现错误:

External Exception E0434352

这是非常无用且通用的。两个系统都是 Windows 10,但我也在其他 Windows 版本上尝试过,64 位可以,32 位不能。那么我做了什么来阻碍在 32 位上运行?

Inno 设置代码:

[Files]
Source: "fiSqlSmoLib2\bin\x86\Debug\fiSqlSmoLib2.dll"; DestDir: "{app}"; \
    Flags: nocompression 32bit

[Code]

function StartSql(machineName, sqlServerName: AnsiString): Integer;
external 'StartSql@files:fiSqlSmoLib2.dll stdcall setuponly delayload';

function StopSql(machineName, sqlServerName: AnsiString): Integer;
external 'StopSql@files:fiSqlSmoLib2.dll stdcall setuponly delayload';

function InitializeSetup(): Boolean;
var
  SQLresultCode : Integer;
  Computer : String;
  SQLServer : String;
begin
  Computer := GetComputerNameString;
  SQLServer := 'FACTORYINSITE';

  try
    SQLresultCode := StopSql(Computer, SQLServer);
  except
    ShowExceptionMessage;
    exit;
  end;
  try
    SQLresultCode := StartSql(Computer, SQLServer);
  except
    ShowExceptionMessage;
    exit;
  end;
end;

Visual Basic 代码:

Imports System.Runtime.InteropServices
Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft.SqlServer.Management.Smo.Wmi
Imports RGiesecke.DllExport

Public Class fiSqlSmo

    <DllExport("StartSql", CallingConvention.StdCall)> _
    Public Shared Function StartSql(<MarshalAs(UnmanagedType.LPStr)> machineName As String, <MarshalAs(UnmanagedType.LPStr)> sqlServerName As String) As Integer
        Dim mc As ManagedComputer
        Dim Svc As Service
        Dim svcState As ServiceState
        Try
            mc = New ManagedComputer(machineName)
            Svc = mc.Services("MSSQL$" + sqlServerName)
        Catch ex As Exception
            Return ServiceState.Unknown
        End Try
        Try
            svcState = Svc.ServiceState
        Catch ex As Exception
            Return ServiceState.Unknown
        End Try
        If (Svc.ServiceState <> ServiceState.Running) Then
            Svc.Start()
        End If
        Return svcState
    End Function

    <DllExport("StopSql", CallingConvention.StdCall)> _
    Public Shared Function StopSql(<MarshalAs(UnmanagedType.LPStr)> machineName As String, <MarshalAs(UnmanagedType.LPStr)> sqlServerName As String) As Integer
        Dim mc As ManagedComputer
        Dim Svc As Service
        Dim svcState As ServiceState
        Try
            mc = New ManagedComputer(machineName)
            Svc = mc.Services("MSSQL$" + sqlServerName)
        Catch ex As Exception
            Return ServiceState.Unknown
        End Try
        Try
            svcState = Svc.ServiceState
        Catch ex As Exception
            Return ServiceState.Unknown
        End Try
        If (Svc.ServiceState = ServiceState.Running) Then
            Svc.Stop()
        End If
        Return svcState
    End Function
End Class

最佳答案

问题似乎出在所用 SMO 程序集的版本上。有效的安装程序与 SMO 的 SLQ 2016 版本相关联,而它失败的机器只安装了 SQL 2008 R2。老版本的机器都是32位的,这似乎是巧合。

重建 .NET 代码以引用最旧的 SMO 版本使其可以在所有机器上运行。

关于c# - Inno Setup .NET DLL 调用在 64 位中有效,在 32 位中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41000793/

相关文章:

inno-setup - 如何在 ExtractTemporaryFile 中使用多个同名文件?

inno-setup - ArchitecturesAllowed Inno Setup 指令是否涉及 CPU 架构或操作系统架构?

c# - 使用 MemoryStream 的 Open XML WordprocessingDocument 为 0KB

c# - 函数的监听器无法启动。为什么?

c# - 为什么是 -1L * -9223372036854775808L == -9223372036854775808L

c# - InvalidOperationException 调用 ResourceManager.GetString 时

java - .NET - .NET 的安全框架

inno-setup - Inno Setup - 禁用选定组件菜单上的下拉列表

c# - 使用 linq 时摆脱嵌套的 foreach 循环

c# - 在 wpf 中找不到 MainWindow.xaml 文件