Windows services Log4net在windows服务中不工作

Windows services Log4net在windows服务中不工作,windows-services,log4net,Windows Services,Log4net,我正在尝试为我的windows服务创建一个简单的文件记录器,但是没有写入该文件。这是我的app.config文件: <?xml version="1.0"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configS

我正在尝试为我的windows服务创建一个简单的文件记录器,但是没有写入该文件。这是我的app.config文件:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <connectionStrings>
    <add name="MyAppConnectionString" connectionString="Data Source=.;Initial Catalog=MyApp;Integrated Security=True;MultipleActiveResultSets=True" />
    <add name="MyAppEntities" connectionString="metadata=res://*/MyAppModel.csdl|res://*/MyAppModel.ssdl|res://*/MyAppModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=MyApp;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <system.web>
    <roleManager enabled="true" defaultProvider="MyAppSqlRoleProvider">
      <providers>
        <add name="MyAppSqlRoleProvider"
             type="System.Web.Security.SqlRoleProvider"
             applicationName="MyApp"
             connectionStringName="MyAppConnectionString"/>
      </providers>
    </roleManager>
  </system.web>
  <log4net>
    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="C:/logfiles/MyAppAlarms.txt" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %message%newline" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="FileAppender" />
    </root>
  </log4net>
</configuration>

我知道还有其他类似的帖子,但我读过,尝试过其中的所有内容,但都没有成功。我试着把同样的标签放在一个控制台应用程序上面,结果成功了。我尝试将app.config复制并粘贴到C:\驱动器,并在my AssemblyInfo.cs中引用它:

[程序集:log4net.Config.XmlConfigurator(Watch=true,ConfigFile=@“C:\app.Config”)]

但这并不奏效。我能够使用调试器连接到该服务,但我不确定如何在这里利用它。没有什么会引发异常。我尝试使用StreamWriter写入同一个文件,但效果良好,因此我知道这不是写入权限问题


我不知道下一步该做什么。有没有一种方法可以让我得到一些调试信息,这样我就可以找出什么是错误的?我尝试启用内部调试并运行DebugView,但除了低级网络消息外,我什么也看不到。我还尝试设置log4net debug=true,但我认为这会写入控制台,这对服务没有帮助。

检查app.config文件的命名是否正确。如果服务可执行文件为MyService.exe,则配置文件应命名为MyService.exe.config

我已经被它咬过好几次了,现在这是我检查的第一件事


另请参见:

检查app.config文件的名称是否正确。如果服务可执行文件为MyService.exe,则配置文件应命名为MyService.exe.config

我已经被它咬过好几次了,现在这是我检查的第一件事


另请参见:

如果正在调试服务,请确保在DbgView中启用了捕获全局Win32。当设置log4net debug=true时,您应该在控制台和dbgview中同时看到消息

如果在调用ServiceBase.Run(..)命令之前,在程序开始时有一个log.Debug调用,然后,您应该能够从命令提示符直接运行exe,并且它应该初始化日志记录,从而在显示错误消息(表示无法从命令行启动服务)之前初始化任何内部日志记录消息。这可能会说明问题所在。(当然,您必须知道,这样做可能是在不同的凭据下运行程序。)

另外,如果您想从命令行在非服务程序中运行整个程序,通常可以通过更改几行来实现

您的服务可能会开始使用以下内容

static void Main()
{
     log.Debug("Start Up");
     ServiceBase.Run(new MainService());         
}
你可以把它改成

static void Main()
{
     log.Debug("Start Up");
     MainService ms = new MainService();
     ms.OnStart(null);
}
 // The main entry point for the process
    static void Main(string[] args)
    {
       log.Debug("Start Up");

        string cmdLine = args.Length == 0 ? "" : args[0].ToLower().Substring(1);

        // If we are debugging or if we have been passed the /NonService 
        // commandline, then start the program in non-service mode.

        if (System.Diagnostics.Debugger.IsAttached 
             || string.Equals(cmdLine, "NonService" , System.StringComparison.CurrentCultureIgnoreCase))
        {
            MainService ms = new MainService();
            ms.OnStart(null);
        }
        else
        {
            ServiceBase.Run(new MainService());
        }
    }
或者,如果您希望能够在不重新编译的情况下切换,那么

static void Main()
{
     log.Debug("Start Up");
     MainService ms = new MainService();
     ms.OnStart(null);
}
 // The main entry point for the process
    static void Main(string[] args)
    {
       log.Debug("Start Up");

        string cmdLine = args.Length == 0 ? "" : args[0].ToLower().Substring(1);

        // If we are debugging or if we have been passed the /NonService 
        // commandline, then start the program in non-service mode.

        if (System.Diagnostics.Debugger.IsAttached 
             || string.Equals(cmdLine, "NonService" , System.StringComparison.CurrentCultureIgnoreCase))
        {
            MainService ms = new MainService();
            ms.OnStart(null);
        }
        else
        {
            ServiceBase.Run(new MainService());
        }
    }

如果正在调试服务,请确保在DbgView中启用了捕获全局Win32。当设置log4net debug=true时,您应该在控制台和dbgview中同时看到消息

如果在调用ServiceBase.Run(..)命令之前,在程序开始时有一个log.Debug调用,然后,您应该能够从命令提示符直接运行exe,并且它应该初始化日志记录,从而在显示错误消息(表示无法从命令行启动服务)之前初始化任何内部日志记录消息。这可能会说明问题所在。(当然,您必须知道,这样做可能是在不同的凭据下运行程序。)

另外,如果您想从命令行在非服务程序中运行整个程序,通常可以通过更改几行来实现

您的服务可能会开始使用以下内容

static void Main()
{
     log.Debug("Start Up");
     ServiceBase.Run(new MainService());         
}
你可以把它改成

static void Main()
{
     log.Debug("Start Up");
     MainService ms = new MainService();
     ms.OnStart(null);
}
 // The main entry point for the process
    static void Main(string[] args)
    {
       log.Debug("Start Up");

        string cmdLine = args.Length == 0 ? "" : args[0].ToLower().Substring(1);

        // If we are debugging or if we have been passed the /NonService 
        // commandline, then start the program in non-service mode.

        if (System.Diagnostics.Debugger.IsAttached 
             || string.Equals(cmdLine, "NonService" , System.StringComparison.CurrentCultureIgnoreCase))
        {
            MainService ms = new MainService();
            ms.OnStart(null);
        }
        else
        {
            ServiceBase.Run(new MainService());
        }
    }
或者,如果您希望能够在不重新编译的情况下切换,那么

static void Main()
{
     log.Debug("Start Up");
     MainService ms = new MainService();
     ms.OnStart(null);
}
 // The main entry point for the process
    static void Main(string[] args)
    {
       log.Debug("Start Up");

        string cmdLine = args.Length == 0 ? "" : args[0].ToLower().Substring(1);

        // If we are debugging or if we have been passed the /NonService 
        // commandline, then start the program in non-service mode.

        if (System.Diagnostics.Debugger.IsAttached 
             || string.Equals(cmdLine, "NonService" , System.StringComparison.CurrentCultureIgnoreCase))
        {
            MainService ms = new MainService();
            ms.OnStart(null);
        }
        else
        {
            ServiceBase.Run(new MainService());
        }
    }

写入日志的服务需要具有管理员权限才能在事件查看器中访问安全日志。您可以通过使用具有管理员访问权限的帐户启动服务来测试这一点。不要在生产环境中使用具有管理员访问权限的帐户,而只是作为临时测试

要修复此问题,请创建自定义事件日志。它将绕过访问安全日志的需要

<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
      <logName value="System" />
      <applicationName value="AppName" />
      ...
</appender>

...

写入日志的服务需要具有管理员权限才能在事件查看器中访问安全日志。您可以通过使用具有管理员访问权限的帐户启动服务来测试这一点。不要在生产环境中使用具有管理员访问权限的帐户,而只是作为临时测试

要修复此问题,请创建自定义事件日志。它将绕过访问安全日志的需要

<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
      <logName value="System" />
      <applicationName value="AppName" />
      ...
</appender>

...

我也面临同样的问题,在我的服务运行以配置记录器时,我使用了下面的语句

XmlConfigurator.Configure()


它成功了。

我也面临着同样的问题,当我的服务运行以配置记录器时,我使用了下面的语句

XmlConfigurator.Configure()


它成功了。

像这里描述的那样启用内部log4net调试,看看这是否有助于您解决问题:像这里描述的那样启用内部log4net调试,看看这是否有助于您解决问题: