我寫了一個簡單的接口到SQL SMO庫,所以我可以停止並從Inno安裝腳本安裝過程中啓動SQL Server。我的開發機器是一個64位處理器機器。託管代碼使用DllExport for .Net以Visual Basic編寫,面向.NET 4.0並針對x86平臺進行編譯。我正在使用Inno Setup 5.5.9 Unicode版本。Inno安裝.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
我很確定默認情況下沒有安裝SMO,它在失敗的機器上可用嗎?你的代碼是否在這些機器上的控制檯應用程序中工作?您不需要SMO來啓動/停止MSSQL服務,您可以簡單地使用「ServiceController」或通過[使用Pascal Script]刪除任何.Net依賴項(http://stackoverflow.com/questions/2456987/upgrading-windows-service- using-inno-setup) –
或者嘗試在VB.NET代碼中捕獲並記錄任何異常以調試問題。 –
我相信SMO安裝在測試機器上,但這是一個很好的建議來檢查。我也會嘗試一個控制檯應用程序。 SQL服務器將與安裝程序代碼不同,或者可能位於Azure上,因此我認爲SMO可能是最好的方法。在完整安裝中,我還登錄到SQL服務器並運行腳本,這就是爲什麼我需要確保它正在運行。 – jphoekstra