C# DLL配置NLog后,C++程序读取日志文件遇共享冲突问题
问题描述
我用C# DLL通过以下代码配置NLog写入日志文件:
private static void SetupLogging() { var Config = new NLog.Config.LoggingConfiguration(); var logfile = new NLog.Targets.FileTarget("logfile") { FileName = m_LogFile, WriteBom = true, Layout = "${longdate}|${level:uppercase=true}|${logger}|${message:withException=true:exceptionSeparator=|}" }; var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); Config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole); Config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile); LogManager.Configuration = Config; }
我的C++应用调用该DLL执行任务,检测到错误时尝试读取日志文件,代码如下:
CFile file{}; CFileException ex{}; if (!file.Open(filePath, CFile::modeRead, &ex)) { TCHAR szError[_MAX_PATH]{}; ex.GetErrorMessage(&szError[0], _MAX_PATH); AfxMessageBox(&szError[0], MB_OK | MB_ICONERROR); return; }
此时触发文件共享冲突异常,但弹窗提示期间用记事本可以正常打开日志文件,请问如何解决共享冲突,让C++程序正常读取日志文件?
解决方案
方法1:修改NLog的文件共享设置
NLog的FileTarget默认以独占模式写入文件,导致其他进程无法读取。可以给FileTarget添加FileShare.Read配置,让写入时允许其他进程只读打开文件:
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = m_LogFile, WriteBom = true, Layout = "${longdate}|${level:uppercase=true}|${logger}|${message:withException=true:exceptionSeparator=|}", FileShare = System.IO.FileShare.Read // 新增这一行 };
这样NLog写入日志时的文件共享策略和记事本一致,就能避免冲突。
方法2:修改C++的文件打开模式
如果没法修改C# DLL的代码,可以调整C里CFile::Open的共享参数,允许文件被其他进程写入:
把Open方法的第三个参数(共享模式)改成CFile::shareDenyWrite,这样C只读打开文件时,只禁止其他进程写入,不影响NLog的写入操作:
if (!file.Open(filePath, CFile::modeRead | CFile::shareDenyWrite, &ex))
也可以用更宽松的CFile::shareReadWrite,允许其他进程同时读写文件:
if (!file.Open(filePath, CFile::modeRead | CFile::shareReadWrite, &ex))
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

