【问题】
折腾:
【未解决】C#中实现Log同时输出内容到文件和文本框(或终端)
过程中,用参考官网的示例代码:
然后去用NLog的RichTextBoxTarget,代码如下:
private void initLogger() { //logger = LogManager.GetCurrentClassLogger(); // Step 1. Create configuration object LoggingConfiguration logConfig = new LoggingConfiguration(); // Step 2. Create targets and add them to the configuration RichTextBoxTarget rtbTarget = new RichTextBoxTarget(); logConfig.AddTarget("richTextBox", rtbTarget); //http://nlog.codeplex.com/workitem/2707 rtbTarget.ControlName = "rtbLog"; //rtbTarget.FormName = "rtbLog"; FileTarget fileTarget = new FileTarget(); logConfig.AddTarget("logFile", fileTarget); // Step 3. Set target properties rtbTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}"; fileTarget.FileName = "${basedir}/${date}_log.txt"; fileTarget.Layout = "${message}"; // Step 4. Define rules LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, rtbTarget); logConfig.LoggingRules.Add(rule1); LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget); logConfig.LoggingRules.Add(rule2); // Step 5. Activate the configuration LogManager.Configuration = logConfig; // Example usage Logger logger = LogManager.GetLogger("Example"); logger.Trace("trace log message"); logger.Debug("debug log message"); logger.Info("info log message"); logger.Warn("warn log message"); logger.Error("error log message"); logger.Fatal("fatal log message"); }
结果可以显示出RichTextBox,但是是每次都新建一个,而不是我们所希望的,用自己的已有的rtbLog的那个RichTextBox:
【解决过程】
1.继续参考:
RichTextBox target always opens new form
其说是,需要在NLog的配置文件中找对应的formName的。
但是很明显,此处没有配置文件,而只是代码中去配置的。
2.想到了,是不是由于当前的代码是在winform_Load中加载的,而此处整个窗体还没有完全初始化完毕,所以找不到对应的Winform中的rtxLog的。那就在xxx_Load之后,再去运行此logger的初始化。
改为:
private void initLogger() { //logger = LogManager.GetCurrentClassLogger(); // Step 1. Create configuration object LoggingConfiguration logConfig = new LoggingConfiguration(); // Step 2. Create targets and add them to the configuration RichTextBoxTarget rtbTarget = new RichTextBoxTarget(); logConfig.AddTarget("richTextBox", rtbTarget); //http://nlog.codeplex.com/workitem/2707 //rtbTarget.ControlName = "rtbLog"; rtbTarget.FormName = "rtbLog"; FileTarget fileTarget = new FileTarget(); logConfig.AddTarget("logFile", fileTarget); // Step 3. Set target properties rtbTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}"; fileTarget.FileName = "${basedir}/${date}_log.txt"; fileTarget.Layout = "${message}"; // Step 4. Define rules LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, rtbTarget); logConfig.LoggingRules.Add(rule1); LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget); logConfig.LoggingRules.Add(rule2); // Step 5. Activate the configuration LogManager.Configuration = logConfig; // Example usage Logger logger = LogManager.GetLogger("Example"); logger.Trace("trace log message"); logger.Debug("debug log message"); logger.Info("info log message"); logger.Warn("warn log message"); logger.Error("error log message"); logger.Fatal("fatal log message"); } private void btnInitLogger_Click(object sender, EventArgs e) { initLogger(); } private void frmScrapeAmazonProduct_Load(object sender, EventArgs e) { //initLogger(); //debug ////init //initMainCategoryToBestSellerCategoryMapping(); //outputExcelFullFilename = Path.Combine(Environment.CurrentDirectory, outputExcelFilename); //initSearchCategory(); }
结果问题依旧。
3.再去参考之前就看到的:
NLog control to an existing RichTextBox Windows Form
才有点明白:
FormName:指的是Winform,即当前的frmScrapeAmazonProduct
ControlName:指的是RichTextBox ,即此处的rtbLog
所以,再去试试:
private void initLogger() { //logger = LogManager.GetCurrentClassLogger(); // Step 1. Create configuration object LoggingConfiguration logConfig = new LoggingConfiguration(); // Step 2. Create targets and add them to the configuration RichTextBoxTarget rtbTarget = new RichTextBoxTarget(); logConfig.AddTarget("richTextBox", rtbTarget); //http://nlog.codeplex.com/workitem/2707 rtbTarget.ControlName = "rtbLog"; rtbTarget.FormName = "frmScrapeAmazonProduct"; FileTarget fileTarget = new FileTarget(); logConfig.AddTarget("logFile", fileTarget); // Step 3. Set target properties rtbTarget.Layout = "${date:format=HH\\:MM\\:ss} ${logger} ${message}"; fileTarget.FileName = "${basedir}/${date}_log.txt"; fileTarget.Layout = "${message}"; // Step 4. Define rules LoggingRule rule1 = new LoggingRule("*", LogLevel.Debug, rtbTarget); logConfig.LoggingRules.Add(rule1); LoggingRule rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget); logConfig.LoggingRules.Add(rule2); // Step 5. Activate the configuration LogManager.Configuration = logConfig; // Example usage Logger logger = LogManager.GetLogger("Example"); logger.Trace("trace log message"); logger.Debug("debug log message"); logger.Info("info log message"); logger.Warn("warn log message"); logger.Error("error log message"); logger.Fatal("fatal log message"); } private void frmScrapeAmazonProduct_Load(object sender, EventArgs e) { initLogger(); // init logger in winform1_Load here, also work //debug ////init //initMainCategoryToBestSellerCategoryMapping(); //outputExcelFullFilename = Path.Combine(Environment.CurrentDirectory, outputExcelFilename); //initSearchCategory(); }
果然可以了:
会在当前的Winform类frmScrapeAmazonProduct下面的名为rtbLog的RichTextBox控件(control)中,输出上述log信息:
【总结】
想要让RichTextBoxTarget,输出内容到自己的RichTextBox控件中
(而不要每次都是重新创建一个另外的,新的RichTextBox控件)
那么要确保:
RichTextBoxTarget的初始化时,对应的FormName和ControlName都要初始化正确,名字确保要正确。
然后正常的,在窗体的load中,即形如winform1_Load的函数中,去初始化即可。
(此时,由于是winform的load,所以之前的winform的构造函数中,已经调用了InitializeComponent,已经初始化好了自己的那个RichTextBox了,所以此处是可以找到自己的那个RichTextBox)
核心相关代码为:
private void initLogger() { ...... RichTextBoxTarget rtbTarget = new RichTextBoxTarget(); logConfig.AddTarget("richTextBox", rtbTarget); rtbTarget.FormName = "frmScrapeAmazonProduct"; // your winform class name rtbTarget.ControlName = "rtbLog"; // your RichTextBox control/variable name ...... } private void winform1_Load(object sender, EventArgs e) { initLogger(); }
就可以了。