2016-12-06 8 views
2

SQL SMOライブラリへの簡単なインターフェイスを作成したので、インストール中にInno SetupスクリプトからSQL Serverを停止して開始できます。私の開発マシンは64ビットプロセッサマシンです。マネージドコードは.NET用のDllExportを使用してVisual Basicで作成され、.NET 4.0をターゲットとし、x86プラットフォーム用にコンパイルされます。 Inno Setup 5.5.9 Unicodeバージョンを使用しています。Inno Setup .NET DLL呼び出しが64ビットで動作し、32ビットで失敗する

セットアップ実行ファイルは、開発マシンや他の64ビットプロセッサでうまく動作します。 32ビットプロセッサシステムで実行可能ファイルを実行すると、エラーが発生します。

External Exception E0434352

これはかなり役に立ちません。どちらのシステムもWindows 10ですが、他のWindowsバージョンや64ビット版や32ビット版でも試してみました。それで32ビットで動くのを妨害するために私は何をしましたか?

Inno Setupのコード:

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

[Code] 

function StartSql(machineName, sqlServerName: AnsiString): Integer; 
external '[email protected]:fiSqlSmoLib2.dll stdcall setuponly delayload'; 

function StopSql(machineName, sqlServerName: AnsiString): Integer; 
external '[email protected]: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

私はSMOがデフォルトでインストールされていないと確信していますが、それは失敗したマシンで利用できますか?あなたのコードは、それらのマシン上のコンソールアプリケーションから動作しますか?あなたは単純に 'ServiceController'を使うか、[Pascal Scriptを使って] .Netの依存関係を取り除くことができるMSSQLサービスの開始/停止にSMOは必要ありません(http://stackoverflow.com/questions/2456987/upgrading-windows-service- using-inno-setup) –

+0

または、問題をデバッグするためにVB.NETコードで例外を捕捉してログに記録してみてください。 –

+0

私はSMOがテストマシンにインストールされていると思っていますが、それはチェックするのが良い提案です。私はコンソールアプリも試してみます。 SQLサーバーはセットアップコードと異なるノードにあるか、場合によってはAzure上にあるため、SMOが最良の方法かもしれません。完全インストールでは、SQLサーバーにログインしてスクリプトを実行するので、実行中であることを確認する必要があります。 – jphoekstra

答えて

1

問題は、使用SMOアセンブリのバージョンであるように思われます。動作するセットアッププログラムは、SMQのSLQ 2016バージョンとリンクしていましたが、失敗したマシンにはSQL 2008 R2しかインストールされていませんでした。古いバージョンのマシンが32ビットであることは偶然のようです。

最も古いSMOバージョンを参照するように.NETコードを再構築すると、すべてのマシンで動作します。

関連する問題