3

The application crashes when I try to run it inside a folder where the current user has no write access to it.

So my question is, does a .net application create by default temporary files in the parent folder ?

And if yes, can we explicitly set a path to set an external folder where the application has write access to create its temp files ?

Thanks

EDIT: I'm back with more details ... So the exception is a System.UnauthorizedAccessException, and the file it tries to create is named "l1m5tzj4.tmp"

So I'm now sure .NET application is trying to create a temporary file in the current folder ...

Here is the stacktrace

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
   at System.CodeDom.Compiler.TempFileCollection.EnsureTempNameCreated()
   at System.CodeDom.Compiler.TempFileCollection.get_BasePath()
   at System.CodeDom.Compiler.TempFileCollection.AddExtension(String fileExtension, Boolean keepFile)
   at System.CodeDom.Compiler.TempFileCollection.AddExtension(String fileExtension)
   at System.Configuration.Internal.WriteFileContext..ctor(String filename, String templateFilename)
   at System.Configuration.Internal.InternalConfigHost.StaticOpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext, Boolean assertPermissions)
   at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext, Boolean assertPermissions)
   at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext)
   at System.Configuration.ClientConfigurationHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext)
   at System.Configuration.UpdateConfigHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext)
   at System.Configuration.MgmtConfigurationRecord.SaveAs(String filename, ConfigurationSaveMode saveMode, Boolean forceUpdateAll)

EDIT 2: So it looks like it happens while I'm putting a new value in exe config file.

Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (configuration.AppSettings.Settings[key] != null)
{
    configuration.AppSettings.Settings[key].Value = value;
    configuration.Save();
    ConfigurationManager.RefreshSection("appSettings");
}

So why it tries to create a temporary file while I'm trying to save the configuration ? And is there any best practices to save configurations when we don't have write access to its folder ?

Hyukchan Kwon
  • 382
  • 1
  • 5
  • 20
  • Any application needs write permission if it is going to write anything in that folder – Samvel Petrosov May 09 '17 at 16:26
  • 1
    What temporary files are you referring? If you give write permission on parent folder is your application working? – Vivek Athalye May 09 '17 at 16:29
  • @S.Petrosov My question was maybe not clear, but my application is not supposed to write in its parent folder. Or at least, we didn't intend to do it. That's why I'm asking if every .NET applications do write temp files by default at runtime ... – Hyukchan Kwon May 09 '17 at 16:29
  • Can't the owner of the file give write permission to a user for one file and leave the folder as read-only to the same user? – jdweng May 09 '17 at 16:30
  • @VivekAthalye I don't know ... But my application does work perfectly when the current Windows user has write access to its parent folder, but crashes otherwise ... :( – Hyukchan Kwon May 09 '17 at 16:31
  • @jdweng What do you mean by the owner of the file ? – Hyukchan Kwon May 09 '17 at 16:32
  • 2
    @HyukchanKwon please debug application and add exception with it's stacktrace to the question – Samvel Petrosov May 09 '17 at 16:33
  • 1
    .NET programs do not write by default to their own folder or their parent folder, unless you program it to do so, or your program uses a library that is trying to do such shenanigans. Or perhaps your computer is infected with malware... –  May 09 '17 at 16:34
  • @S.Petrosov Yep, I should have given you that in the first place. Unfortunately, I'm not with my main PC right now, so I will try to remember a strange exception I had while debugging : "Unable to copy file" and it was for Services.dll file from absolute path to a relative path ... which is really weird – Hyukchan Kwon May 09 '17 at 16:37
  • 1
    @HyukchanKwon this exception sounds to me like Build Time Exception and not while debugging. – Samvel Petrosov May 09 '17 at 16:39
  • @S.Petrosov Yeah my bad, you are probably right. After check, I have the following exception: System.UnauthorizedAccessException, and the file it tries to create is named "l1m5tzj4.tmp" ... Any idea ? – Hyukchan Kwon May 11 '17 at 09:36
  • is there a stack trace going with that exception? it looks like a file name generated from `Path.GetTempFileName`. – Cee McSharpface May 11 '17 at 10:09
  • @dlatikay I included the stacktrace in my initial post ! – Hyukchan Kwon May 11 '17 at 11:37
  • well, then search for calls to `MgmtConfigurationRecord.SaveAs` in your code. Something wants to update the .config file. – Cee McSharpface May 11 '17 at 11:49
  • We do actually use the executable config file (.exe.Config) to save configurations... but why would it need to create temporary file to do that ? – Hyukchan Kwon May 11 '17 at 11:53
  • @Hyukchan related: http://stackoverflow.com/q/24635071/1132334. updated my answer accordingly. – Cee McSharpface May 11 '17 at 13:22

1 Answers1

5

No, a .NET application does not by default create any (temporary or other) files in the folder that contains the executing assembly at runtime.

Mechanisms which could do that are, among others:

  • Tracing
  • Logging
  • Artefacts of libraries like for example the ODP.NET database provider
  • Dynamic compilation of, for example, serializers

EDIT By now, there is additional information available, so we can also address your actual scenario here:

You call Configuration.Save, which attempts to update the filename.exe.config file. Now your question is why the system, instead of just overwriting the existing config file, creates a temporary file.

The reason is given by an unknown Microsoft programmer, who commented:

The current algorithm guarantees
1) The file we are saving to will always be present on the file system (ie. there will be no window during saving in which there won't be a file there)
2) It will always be available for reading from a client and it will be complete and accurate.

First, they create a temporary file, here, where the new configuration is written to. This is what you see failing when your program throws the exception.

After this, they replace the original configuration file with the temporary file (execution never gets that far in your case), here.

And is there any best practices to save configurations when we don't have write access to its folder?

You are free to redirect the configuration file to any other folder of your choice:
Relocating app.config file to a custom path
Accessing App.config in a location different from the binary

Community
  • 1
  • 1
Cee McSharpface
  • 8,493
  • 3
  • 36
  • 77
  • 1
    More broadly - .Net or Windows native apps do not create files/folders anywhere at all unless some user's code does so. Most common case (not yet listed) - lack of understanding of "current working folder" and its relation to relative file paths. – Alexei Levenkov May 09 '17 at 16:40
  • right - maybe with the exception of assembly bind (fusion) logging but that is also something that needs to be configured and is never on by default. – Cee McSharpface May 09 '17 at 16:54
  • Thank you very much everyone :) – Hyukchan Kwon May 11 '17 at 14:10