5

I'm trying to create a temp file, write to it, print it, then delete it. Here's my code:

string filePathReceipt = Path.GetTempFileName();

try {
    using (FileStream fs = new FileStream(filePathReceipt, FileMode.Open)) {
        File.WriteAllText(filePathReceipt, dataToBeWritten.ToString());
    }
}
catch (Exception ex) {
    MessageBox.Show(ex.Message);
}

//Printing receipt: start
ProcessStartInfo psi = new ProcessStartInfo(filePathReceipt);
psi.Verb = "PRINT";

try {
    Process.Start(psi);
}
catch (Exception ex) {
    MessageBox.Show(ex.Message);
}
//Printing receipt: end

if (File.Exists(filePathReceipt)) {
    //Delete the file after it has been printed
    File.Delete(filePathReceipt);
}

I get the Exception Message saying:

Can't write to it because it's used by another process.

EDIT #2: I found that this works: string filePathReceipt = AppDomain.CurrentDomain.BaseDirectory + @"receipt.txt";

While this generates an Exception: string filePathReceipt = Path.GetTempFileName();

Full, current code:

        //string filePathReceipt = AppDomain.CurrentDomain.BaseDirectory + @"receipt.txt";
        string filePathReceipt = Path.GetTempFileName();

        File.WriteAllText(filePathReceipt, dataToBeWritten.ToString());

        ProcessStartInfo psi = new ProcessStartInfo(filePathReceipt);
        psi.Verb = "PRINT";

        try {
            using (Process p = Process.Start(psi))
                p.WaitForExit();
        }
        catch (Exception ex) {
            MessageBox.Show(ex.Message);
        }


        if (File.Exists(filePathReceipt)) {
            //Delete the file after it has been printed
            File.Delete(filePathReceipt);
        }

2 Answers2

8

You are mixing two concepts: FileStream and File.WriteAllText.
You open a file stream and then use File.WriteAllText which tries to open file and fails to do that.

Replace:

using (FileStream fs = new FileStream(filePathReceipt, FileMode.Open)) {
  File.WriteAllText(filePathReceipt, dataToBeWritten.ToString());
}

with either:

File.WriteAllText(filePathReceipt, dataToBeWritten.ToString());

or

// pay attention: it is FileMode.Create, not FileMode.Open
using (FileStream fs = new FileStream(filePathReceipt, FileMode.Create)) 
using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
{
  sw.Write(dataToBeWritten.ToString());
}
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
  • Spotted perfectly. File is used by the `FileStream` so `File.WriteAllText` method throws exception. – mrogal.ski Mar 28 '17 at 11:01
  • I did as you told me. I got a new Exception instead, saying something about "No program is associated with the file for that purpose" (roughly translated). –  Mar 28 '17 at 11:02
  • Happily, file is being created :) Now, about printing: @Phrosen Are you sure that you use correct `Verb`? Try `Print` or `PrintTo` instead. – Yeldar Kurmangaliyev Mar 28 '17 at 11:05
  • 1
    @Phrosen that's a windows error. Your temp file has an extension that windows does not know a program using the verb "PRINT" for. – René Vogt Mar 28 '17 at 11:06
  • I tried both "Print" and "PrintTo", both generated the same exception as "PRINT". I don't have a printer, so maybe that could be a problem? I tried the same code for printing on a file that I had already created, and that seemed to work, though. (By seemed to work I mean: Windows detected no printer, and instead tried to save the file as .pdf) –  Mar 28 '17 at 11:08
5

In addition to Yeldar's answer...

You need to wait for the printing process to finish. You cannot delete the file in the millisecond after you started that process.

The direct way to wait for that process is:

try {
    using (Process p = Process.Start(psi))
        p.WaitForExit();
}
catch (Exception ex) {
    MessageBox.Show(ex.Message);
}

Another way is to use the Process' events:

using(Process p = new Process())
{
    p.StartInfo = psi;
    p.EnableRaisingEvents = true;
    p.HasExited += OnProcessExited;
}

and handle the file in an OnProcessExited event handler.

Community
  • 1
  • 1
René Vogt
  • 43,056
  • 14
  • 77
  • 99