26

I am using the TextWriter to try to write to a hidden file, and it is throwing an exception. I can't seem to figure out how to write to a hidden file.

using (TextWriter tw = new StreamWriter(filename))
{
    tw.WriteLine("foo");
    tw.Close();
}

Exception:

Unhandled Exception: System.UnauthorizedAccessException: 
Access to the path 'E:\*\media\Photos\2006-08\.picasa.ini' is denied.

How can I write to a hidden file?

Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
esac
  • 24,099
  • 38
  • 122
  • 179

6 Answers6

53

It seems that the problem is that kind of a File.Exists() check is done internally, which fails if the file is hidden (e.g. tries to do a FileMode.Create on a file which already exists).

Therefore, use FileMode.OpenOrCreate to make sure that the file is opened or created even if it is hidden, or just FileMode.Open if you do not want to create it if it doesn't exist.

When FileMode.OpenOrCreate is used though, the file will not be truncated, so you should set its length at the end to make sure that there is no leftover after the end of the text.

using (FileStream fs = new FileStream(filename, FileMode.Open)) {
  using (TextWriter tw = new StreamWriter(fs)) {
    // Write your data here...
    tw.WriteLine("foo");
    // Flush the writer in order to get a correct stream position for truncating
    tw.Flush();
    // Set the stream length to the current position in order to truncate leftover text
    fs.SetLength(fs.Position);
  }
}

If you use .NET 4.5 or later, there is a new overload which prevents the disposal of the StreamWriter to also dispose the underlying stream. The code could then be written slighly more intuitively like this:

using (FileStream fs = new FileStream(filename, FileMode.Open)) {
  using (TextWriter tw = new StreamWriter(fs, Encoding.UTF8, 1024, true)) {
    // Write your data here...
    tw.WriteLine("foo");
  }
  // Set the stream length to the current position in order to truncate leftover text
  fs.SetLength(fs.Position);
}
Lucero
  • 59,176
  • 9
  • 122
  • 152
  • 6
    Upvoted because this is the correct operation... not "unhide the file, write to it, then hide it again" process – enorl76 Dec 19 '14 at 22:00
  • 2
    Thank you for clarifying exactly WHY this happens, as I didn't see how a "hidden" attribute affected file permissions. – Dave Van den Eynde Feb 10 '15 at 10:37
  • @DaveVandenEynde, you're welcome. Unfortunately most people visiting this question don't seem to realize that changing the attributes back and forth is not really a solution but just a brittle workaround. – Lucero Feb 10 '15 at 14:51
  • tw.Close() is unnesessary – SergeyT Mar 11 '16 at 12:50
  • @SergeyT You're of course correct, but I included it in the answer because this was the OP's snippet in the question. I just modified the `StreamWriter` creation to show how to deal with the hidden file. – Lucero Mar 11 '16 at 13:37
  • @Lucero I think that your answer is not consistent with OP's. `FileMode.Create` will truncate the existing file, however `FileMode.OpenOrCreate` not. You should call something like `fs.SetLength(fs.Position)`. – TN. Sep 08 '16 at 15:28
  • @TN Good point - if the written content is shorter than the original content this will be necessary. Edited, thanks. – Lucero Sep 09 '16 at 07:07
  • @Lucero Shouldn't the fourth parameter of the `StreamWriter` in your second example be `true`? The parameter is called `leaveOpen` and we need this so the `FileStream` length can be set, right? – toXel Mar 22 '18 at 09:52
  • @toXel Good catch, fixed. – Lucero Mar 23 '18 at 11:29
22

EDIT 2: This answer solve the problem, but is not the correct way to deal with the problem. You should look for Lucero's answer.


Took this answer from: http://www.dotnetspark.com/Forum/314-accessing-hidden-files-and-write-it.aspx

1- Set File as Visible so it can be overwritten

// Get file info
FileInfo myFile= new FileInfo(Environment.CurrentDirectory + @"\hiddenFile.txt");

// Remove the hidden attribute of the file
myFile.Attributes &= ~FileAttributes.Hidden;

2- Make changes to the file

// Do foo...

3- Set back file as hidden

// Put it back as hidden
myFile.Attributes |= FileAttributes.Hidden;

EDIT: I fixed some problem on my answer as mentionned by briler

  • 3
    unsetting the hidden attribute and then resetting hidden after you've written to the file is rife with so many problems. Just use one of the FileStream overloads that handles this properly, as mentioned in @Lucero answer. – enorl76 Dec 19 '14 at 21:51
  • see the answer of @Lucero there is no need to change attributes to write to a hidden file. – SergeyT Mar 11 '16 at 12:54
11

Edit : Pierre-Luc Champigny answer was inccorect, but now fixed according to mine, I'm Leaving it behind as reference

myFile.Attributes |= FileAttributes.Normal;

doesn't remove the Hidden attribute from the file. in order to remove unhidden attribute use :

FileInfo .Attributes &= ~FileAttributes.Hidden; 

This code checks if the file exists it make it unhidden. before writing once finish it set it as hidden again. I also set the normal attribute in case the didn't exist - you do not have to use it

// if do not exists it creates it.
FileInfo FileInfo = new FileInfo(FileName);
if (true == FileInfo .Exists)
{
   // remove the hidden attribute from the file
   FileInfo .Attributes &= ~FileAttributes.Hidden; 
} //if it doesn't exist StreamWriter will create it
using (StreamWriter fileWriter = new StreamWriter(FileName))
{
   fileWriter.WriteLine("Write something");
}
 // set the file as hidden
FileInfo.Attributes |= FileAttributes.Hidden;
briler
  • 570
  • 6
  • 21
0

If that's an option for you you could try to use File.SetAttributes to remove the hidden attribute temporarily, do your work and then set it back to the previous state.

Tomas Vana
  • 18,317
  • 9
  • 53
  • 64
0

You can unhide the file before writing into it and after complete writing hide it again.

viky
  • 17,275
  • 13
  • 71
  • 90
0

Once you've opened a file, you can change its attributes (including to readonly) and continue writing to it. This is one way to prevent a file from being overwritten by other processes.

So it would seem to be possible to unhide the file, open it, then reset it to hidden, even while you've got it open.

For example, the following code works:

public void WriteToHiddenFile(string fname)
{
    TextWriter    outf;
    FileInfo      info;  

    info = new FileInfo(fname);
    info.Attributes = FileAttributes.Normal;    // Set file to unhidden
    outf = new StreamWriter(fname);             // Open file for writing
    info.Attributes = FileAttributes.Hidden;    // Set back to hidden
    outf.WriteLine("test output.");             // Write to file
    outf.Close();                               // Close file
}

Note that the file remains hidden while the process writes to it.

David R Tribble
  • 11,918
  • 5
  • 42
  • 52
  • Bad option. If something happens between unsetting the hidden attribute and resetting the hidden attribute, you've changed the state of the file unnecessarily. Simple use an overload of FileStream ctor. – enorl76 Dec 19 '14 at 21:53