Inno Setup .NET DLL调用工作在64位,在32位失败

时间:2016-12-06 16:58:04

标签: c# .net inno-setup dllexport

我在SQL SMO库中编写了一个简单的接口,因此我可以在从Inno安装脚本安装期间停止并启动SQL Server。我的开发机器是64位处理器机器。托管代码使用DllExport for .Net以Visual Basic编写,目标是.NET 4.0并编译为x86平台。我正在使用Inno Setup 5.5.9 Unicode版本。

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

  

外部异常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

1 个答案:

答案 0 :(得分:1)

问题似乎是使用的SMO程序集的版本。有效的安装程序与SLQ 2016版本的SMO相关联,而失败的机器只安装了SQL 2008 R2。具有较旧版本的机器是32位似乎是巧合。

重建.NET代码以引用最早的SMO版本,使其在所有计算机上都能正常工作。