基于 Serilog WPF 的应用程序可以运行,但在作为 EXE 安装时无法运行
Serilog WPF based app works but not when installed as an EXE
注意:这是 Microsoft.Data.SqlClient 的问题,它是 SqlConnection 的实现。如果我创建一个实例 (_sqlConnection = new SqlConnection();) 然后检查状态 (_sqlConnection.State),我会得到一个 NullReferenceException。如果我分配一个有效的连接字符串,仍然是 Null 异常。
解决方案(为了节省您的时间)是恢复使用 System.Data.SqlClient,一切都很好。我将剩下的留在这里,以防它有助于追查原因 - 或者如果其他人有类似的问题。
我有一个 WPF .net 4.7.2 应用程序,它在我构建时 运行 并且在 VS 中 运行(或者在调试或发布时双击 .exe。)如果我生成一个.msi 文件并从那里安装,在将日志写入 MS SQL 服务器(但不写入本地文件)
时出现空异常错误
我正在使用:
- Serilog:2.10.0
- Serilog.Sinks.Console: 4.0.0
- Serilog.Sinks.File: 5.0.0
- Serilog.Sinks.PeriodicBatching:2.3.0
- Serilog.Sinks.MSSqlServer: 5.6.1
- MS.Data.SqlClient: 3.0.1
- System.Data.Common: 4.3.0
- System.Data.SqlClient:4.8.3
.msi 文件是使用以下方法创建的:
Microsoft Visual Studio 安装程序项目(可从 https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2017InstallerProjects&ssr=false#overview 获得)
已修改以下代码以消除所有干扰以及任何专有信息。请记住,除了作为 .msi 文件安装时,这可以正常工作。
当我的应用程序启动时,我调用以下命令:
Serilog.Debugging.SelfLog.Enable(味精 => Debug.WriteLine(味精));
导致问题的调用示例:
LogDebug("这是 {user} 对 LogDebug 的开发人员测试", );
代码:
// Primary method
public void LogDebug(string msgtemplate, params object[] parms){
var LogCfg = GetStdLogConfig();
Log.Logger = LogCfg.CreateLogger();
Log.Warning(msgtemplate, parms);
Log.CloseAndFlush(); // error happens on this line
}
protected virtual LoggerConfiguration GetStdLogConfig()
{
LoggerConfiguration logcfg = null;
logcfg = new LoggerConfiguration()
.MinimumLevel.ControlledBy(StandardLevelSwitch)
.Enrich.WithProperty("Fid1", AppValues.VersionNo)
.Enrich.WithProperty("Fid2", AppValues.UserId)
.Enrich.WithProperty("Fid3", getUserRightsString())
.Enrich.WithProperty("Fid4", AppValues.AppCompileMode);
AddLocalFile(logcfg, "std"); // this writes to local file just fine.
AddSql(logcfg, "std");
return logcfg;
}
protected virtual LoggerConfiguration AddSql(LoggerConfiguration logcfg, string mode = "")
{
try
{
var logTable = "App_Logs"; // Renamed for sample
var sinkOptions = new MSSqlServerSinkOptions { TableName = logTable };
var columnOptionVals = new ColumnOptions
{
AdditionalColumns = new System.Collections.ObjectModel.Collection<SqlColumn>()
};
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid1", System.Data.SqlDbType.NVarChar, true, 50));
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid2", System.Data.SqlDbType.NVarChar, true, 15));
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid3", System.Data.SqlDbType.NVarChar, true, 100));
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid4", System.Data.SqlDbType.NVarChar, true, 20));
columnOptionVals.Store.Remove(StandardColumn.MessageTemplate);
columnOptionVals.LogEvent.DataLength = 2048;
columnOptionVals.PrimaryKey = columnOptionVals.TimeStamp;
columnOptionVals.TimeStamp.NonClusteredIndex = true;
// <Valid ConnectionString> is the same as used to do other updates without issue
logcfg.WriteTo.MSSqlServer(
connectionString: <Valid ConnectionString>,
sinkOptions: sinkOptions,
columnOptions: columnOptionVals
);
return logcfg;
}
错误发生在Log.CloseAndFlush():.
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.Data.SqlClient
StackTrace:
at Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
如果我继续,此错误显示:
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.Data.SqlClient
StackTrace:
at Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
This exception was originally thrown at this call stack:
Microsoft.Data.SqlClient.SqlConnection.OpenAsync(System.Threading.CancellationToken)
System.Data.Common.DbConnection.OpenAsync()
Serilog.Sinks.MSSqlServer.Platform.SqlClient.SqlConnectionWrapper.OpenAsync()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in exceptionservicescommon.cs
如果我在 StackTrace 中查看此异常,我会注意到其他信息:
在 Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
在 System.Data.Common.DbConnection.OpenAsync()
在 Serilog.Sinks.MSSqlServer.Platform.SqlClient.SqlConnectionWrapper.d__6.MoveNext()
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 中
f:\dd\ndp\clr\src\BCL\system\runtime\exceptionservices\exceptionservicescommon.cs:第 133 行
然后继续(但没有任何内容记录到 SQL 服务器)
在输出 window 中我看到(由于上面的 SelfLog 调用):
Exception thrown: 'System.NullReferenceException' in mscorlib.dll
Object reference not set to an instance of an object.
我调试.exe时,实例化SqlConnection后,很多属性都是NullExceptions,不是NULL。尝试为它们赋值什么也不做,它们仍然是 NullExceptions。但它只发生在这个调用中,SqlConnection 的所有其他实例都按预期工作。
解决方案中的所有其他项目都使用 System.Data.SqlClient - 这就是所有代码的工作原理,只有这个接收器没有。
我根据电子邮件中的开放信息编辑了图书馆。最终修复它(有或没有这些步骤的帮助)是用默认系统 sql 库替换 Github MS SQL 库。
//using Microsoft.Data.SqlClient;
using System.Data.SqlClient;
注意:这是 Microsoft.Data.SqlClient 的问题,它是 SqlConnection 的实现。如果我创建一个实例 (_sqlConnection = new SqlConnection();) 然后检查状态 (_sqlConnection.State),我会得到一个 NullReferenceException。如果我分配一个有效的连接字符串,仍然是 Null 异常。
解决方案(为了节省您的时间)是恢复使用 System.Data.SqlClient,一切都很好。我将剩下的留在这里,以防它有助于追查原因 - 或者如果其他人有类似的问题。
我有一个 WPF .net 4.7.2 应用程序,它在我构建时 运行 并且在 VS 中 运行(或者在调试或发布时双击 .exe。)如果我生成一个.msi 文件并从那里安装,在将日志写入 MS SQL 服务器(但不写入本地文件)
时出现空异常错误我正在使用:
- Serilog:2.10.0
- Serilog.Sinks.Console: 4.0.0
- Serilog.Sinks.File: 5.0.0
- Serilog.Sinks.PeriodicBatching:2.3.0
- Serilog.Sinks.MSSqlServer: 5.6.1
- MS.Data.SqlClient: 3.0.1
- System.Data.Common: 4.3.0
- System.Data.SqlClient:4.8.3
.msi 文件是使用以下方法创建的: Microsoft Visual Studio 安装程序项目(可从 https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2017InstallerProjects&ssr=false#overview 获得)
已修改以下代码以消除所有干扰以及任何专有信息。请记住,除了作为 .msi 文件安装时,这可以正常工作。
当我的应用程序启动时,我调用以下命令: Serilog.Debugging.SelfLog.Enable(味精 => Debug.WriteLine(味精));
导致问题的调用示例: LogDebug("这是 {user} 对 LogDebug 的开发人员测试", );
代码:
// Primary method
public void LogDebug(string msgtemplate, params object[] parms){
var LogCfg = GetStdLogConfig();
Log.Logger = LogCfg.CreateLogger();
Log.Warning(msgtemplate, parms);
Log.CloseAndFlush(); // error happens on this line
}
protected virtual LoggerConfiguration GetStdLogConfig()
{
LoggerConfiguration logcfg = null;
logcfg = new LoggerConfiguration()
.MinimumLevel.ControlledBy(StandardLevelSwitch)
.Enrich.WithProperty("Fid1", AppValues.VersionNo)
.Enrich.WithProperty("Fid2", AppValues.UserId)
.Enrich.WithProperty("Fid3", getUserRightsString())
.Enrich.WithProperty("Fid4", AppValues.AppCompileMode);
AddLocalFile(logcfg, "std"); // this writes to local file just fine.
AddSql(logcfg, "std");
return logcfg;
}
protected virtual LoggerConfiguration AddSql(LoggerConfiguration logcfg, string mode = "")
{
try
{
var logTable = "App_Logs"; // Renamed for sample
var sinkOptions = new MSSqlServerSinkOptions { TableName = logTable };
var columnOptionVals = new ColumnOptions
{
AdditionalColumns = new System.Collections.ObjectModel.Collection<SqlColumn>()
};
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid1", System.Data.SqlDbType.NVarChar, true, 50));
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid2", System.Data.SqlDbType.NVarChar, true, 15));
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid3", System.Data.SqlDbType.NVarChar, true, 100));
columnOptionVals.AdditionalColumns.Add(new SqlColumn("Fid4", System.Data.SqlDbType.NVarChar, true, 20));
columnOptionVals.Store.Remove(StandardColumn.MessageTemplate);
columnOptionVals.LogEvent.DataLength = 2048;
columnOptionVals.PrimaryKey = columnOptionVals.TimeStamp;
columnOptionVals.TimeStamp.NonClusteredIndex = true;
// <Valid ConnectionString> is the same as used to do other updates without issue
logcfg.WriteTo.MSSqlServer(
connectionString: <Valid ConnectionString>,
sinkOptions: sinkOptions,
columnOptions: columnOptionVals
);
return logcfg;
}
错误发生在Log.CloseAndFlush():.
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.Data.SqlClient
StackTrace:
at Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
如果我继续,此错误显示:
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.Data.SqlClient
StackTrace:
at Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
This exception was originally thrown at this call stack:
Microsoft.Data.SqlClient.SqlConnection.OpenAsync(System.Threading.CancellationToken)
System.Data.Common.DbConnection.OpenAsync()
Serilog.Sinks.MSSqlServer.Platform.SqlClient.SqlConnectionWrapper.OpenAsync()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in exceptionservicescommon.cs
如果我在 StackTrace 中查看此异常,我会注意到其他信息:
在 Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken) 在 System.Data.Common.DbConnection.OpenAsync() 在 Serilog.Sinks.MSSqlServer.Platform.SqlClient.SqlConnectionWrapper.d__6.MoveNext() 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 中 f:\dd\ndp\clr\src\BCL\system\runtime\exceptionservices\exceptionservicescommon.cs:第 133 行
然后继续(但没有任何内容记录到 SQL 服务器)
在输出 window 中我看到(由于上面的 SelfLog 调用):
Exception thrown: 'System.NullReferenceException' in mscorlib.dll
Object reference not set to an instance of an object.
我调试.exe时,实例化SqlConnection后,很多属性都是NullExceptions,不是NULL。尝试为它们赋值什么也不做,它们仍然是 NullExceptions。但它只发生在这个调用中,SqlConnection 的所有其他实例都按预期工作。
解决方案中的所有其他项目都使用 System.Data.SqlClient - 这就是所有代码的工作原理,只有这个接收器没有。
我根据电子邮件中的开放信息编辑了图书馆。最终修复它(有或没有这些步骤的帮助)是用默认系统 sql 库替换 Github MS SQL 库。
//using Microsoft.Data.SqlClient;
using System.Data.SqlClient;