user6334610
user6334610

Reputation:

C# Create temp file, write to it, print it, then delete it

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);
        }

Upvotes: 5

Views: 7253

Answers (2)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34199

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());
}

Upvotes: 9

René Vogt
René Vogt

Reputation: 43886

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.

Upvotes: 5

Related Questions