1

I've come across a weird issue and I wonder if it's configuration or a bug. I can't find anything online so here's the issue. My question is how can I write to the executable directory and not the launching directory.

Steps to reproduce:

  1. Create an application with logging (C:\Program Files\FooBar\FooBar.exe)
  2. Make this application a default handler for a particular file type (*.bar)
  3. Launch the application by double clicking the a file of the particular file type (C:\Desktop\foo.bar)
  4. The log file will be written to the directory of the file, not the executing directory. (C:\Desktop\log.txt instead of C:\Program Files\FooBar\log.txt.)

Am I doing something wrong? When I launch the application first and then load the file the logging occurs in the correct directory. My code and config is very simple:

public partial class Form1 : Form {
    private static Logger logger = LogManager.GetCurrentClassLogger();

    public Form1() {
        InitializeComponent();
        MessageBox.Show("Continue");
    }
}

And the config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
  autoReload="true"
  throwExceptions="false"
  internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log" >
  <targets>
    <target name="logfile" xsi:type="File" fileName="FooBar.txt" />
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="logfile" />    
  </rules>
</nlog>

I've put a debugger to see where Assembly.GetExecutingAssmebly() is located and it's in the correct place (C:\Program Files\FooBar\foobar.exe). So I'm not sure why NLog is writing a log to the directory with the file that launched the file and not the executable directory itself.

Ian R. O'Brien
  • 6,682
  • 9
  • 45
  • 73

1 Answers1

3

It will write to where it does because that's the current working directory for the application.

To fix this use something like ${basedir} in your target filename, for example:

<target
  xsi:type="File"
  name="File"
  fileName="${basedir}/logs/${shortdate}.log"
  layout="${level:uppercase=true} ${longdate} ${message} ${exception:format=ToString}"
  encoding="utf-8"
  />

This would output logs to a folder called logs where your application is executing from (assuming it has write permissions).

Lloyd
  • 29,197
  • 4
  • 84
  • 98
  • Related SO about what [`${basedir}`](https://stackoverflow.com/questions/35224317/where-is-basedir-located-using-nlog) actually resolves to. – Nigel Touch Sep 05 '18 at 12:06