【问题】
折腾:
【未解决】C#中实现Log同时输出内容到文件和文本框(或终端)
过程中,用参考官网的示例代码:
然后去用NLog的RichTextBoxTarget,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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); 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的初始化。
改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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); //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
所以,再去试试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 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); 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)
核心相关代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); } |
就可以了。