Tech Tip: Fixing 'File Cannot be Found in Temp Directory' Error in a .Net Core Self-Contained Single Executable File App

Updated on: 27 May 2020

Recently I had a .Net core 3.0 console app project where one of the requirements was to create a self-contained single executable file targeted for Windows 10. When I publish this .Net core App project, it generates a .exe file.

The console app also has an additional requirement where I will need to read a file that is stored in the same location as the .exe file. For the purpose of this blog post, let's call this file DataFile.txt.

To read the file, I will fetch the current directory of the console app using the code below:

string appDirectory = AppDomain.CurrentDomain.BaseDirectory

And this would work fine when I want to read files in the same directory as the app which in this case is C:\Apps.

However, when I run this code in an app that is published as a self-contained single executable file, I will hit a FileNotFoundException error like below:

Unhandled exception. System.IO.FileNotFoundException: Could not find file 'C:\Users\PersonalAccountAppData\Local\Temp\.net\MyTestApp\4cxtqrvs.3yz\DataFile.txt'.
File name: 'C:\Users\Labwo\AppData\Local\Temp\.net\MyTestApp\4cxtqrvs.3yz\DataFile.txt'
at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.File.AsyncStreamReader(String path, Encoding encoding)
at System.IO.File.InternalReadAllTextAsync(String path, Encoding encoding, CancellationToken cancellationToken)
at MyTestApp.Program.Main(String[] args)
at MyTestApp.Program.<Main>(String[] args)

It seems that the app is not running in the C:\Apps directory but instead in a temporary directory called C:\Users\PersonalAccountAppData\Local\Temp\.net\MyTestApp\4cxtqrvs.3yz.

This is happening because the executable file produced is actually a zip file of your compiled .net core app and other relevant files needed in order for the app to run. When the .exe file is executed,  these files are unzipped into a temporary folder before your actual .net core app runs.

Hence,  the current directory you get in your code ends up being the temporary folder instead of the directory the .exe file is actually in.

To fix this problem, you will need to use the following code instead:

Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

Here are some more posts