I'm pretty new to C# and I'm experimenting a lot, I'm trying to make my program a little more user friendly and that is where the problem starts.
At first the location of the excelfile was in a public static string and I had no problems. I've changed it to this:
public string Excellocation()
{
string xlLocation;
if (but_Browse.Text == "Zoek Excel")
{
xlLocation = #"E:\Levi\Documents\Verjaardagen.xlsx";
}
else //Only if I get into this part of my code I get the error
{
xlLocation = but_Browse.Text;
}
return xlLocation;
}
And the button I use so the user can give me a location for the excel file is:
private void but_Browse_Click(object sender, EventArgs e)
{
var FD = new System.Windows.Forms.OpenFileDialog();
if (FD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string fileToOpen = FD.FileName;
System.IO.FileInfo File = new System.IO.FileInfo(FD.FileName);
//OR
System.IO.StreamReader reader = new System.IO.StreamReader(fileToOpen);
//etc
but_Browse.Text = fileToOpen;
this.but_Browse.AutoSize = true;
But_Import.Visible = true;
}
}
Reading the Excel-file is no problem, my program finds it and processes it, if and only if the user changed the location by using the "Browse button" I get a message from Windows that there is already an excel file with that name and if I want to replace it, If I click away that message, my code gives an error on the line that tries to save the excel file
xlWorkbook.Save();
xlWorkbook.Close(true);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
xlWorkbook.Save() gives me this error:
System.Runtime.InteropServices.COMException occurred
HResult=0x800A03EC Message=Verjaardagen.xlsx can not be saved,
because it's read-only.
I have no idea why I don't get an error with the default location while I do get an error if use my button to give me that same location.
Does anyone know what i'm doing wrong?
Thanks in advance
So the problem is that the file is read only when you try to write to it after going through but_Browse_Click? Are you closing the StreamReader? Try using
reader.close();
in but_Browse_Click.
Perhaps a better way would be:
using (StreamReader reader = new StreamReader(fileToOpen))
{
//all code involving the reader in here
}
This automatically closes on completion.
Related
hey guys I am trying to send an attachment file but the attachment dialog is not opening
but instead it is rather telling me 'input string was not in a correct formart
private void proto_Type_AI_Blackhead_God(object sender, RoutedEventArgs e)
{
try
{
OpenFileDialog attachment = new OpenFileDialog();
attachment.InitialDirectory = Environment.SpecialFolder.MyDocuments.ToString();
attachment.Filter = "xml File (*.jpg;*.bmp;*.gif)|*.jpg;*.bmp;*.gif;|Pdf files|*.pdf;|Xml files|*.xml";
if (attachment.ShowDialog() == DialogResult.Value)
{
filename = attachment.FileName;
filename = attachment.SafeFileName;
}
else
{
MessageBox.Show("seriously bad");
}
attachment = null;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I'm surprised that you got this code compiled.
First of all, OpenFileDialog.ShowDialog() returns bool?, so have it properly checked (for HasValue initally and then the value of Value).
Then, why do you overwrite filename variable? I assume filename is some global variable here.
Further, having that fixed I had no problems running the code, filter string is perfectly correct semantically. Logically, jpegs, bmps and gifs are not XML files.
I am converting a .txt file to a pdf and need to display the pdf to the user. For that, I have created a temporary .pdf file and created a process to open the file. This works fine when there is adobe acrobat installed. This fails when there is no default application. For my case, the pdf is opened in internet explorer and I get No process is associated with this object exception. Is there any other way to find out when the file is being closed so that I can delete it later on.
My code is like this.
HtmlToPdf htmlToPdf = new HtmlToPdf(pdfPrintOptions);
string tmpFileName = "zx" + DateTime.Now.Ticks + "x.pdf";
//Iron pdf does not handle in-memory pdf viewing
//convert it to pdf
htmlToPdf.RenderHTMLFileAsPdf(fileWithPath).SaveAs(tmpFileName);
// TempFileCollection tmpFileCollection = new TempFileCollection();
//Use windows process to open the file
Process pdfViewerProcess = new Process
{
EnableRaisingEvents = true, StartInfo = {FileName = tmpFileName}
};
pdfViewerProcess.Start();
pdfViewerProcess.WaitForExit(); **Failing in this line**
//Delete temporary file after the viewing windows is closed
if (File.Exists(tmpFileName))
{
File.Delete(tmpFileName);
}
Similar questions do not seem to provide a workaround for this problem. Any help will be appreciated. Thanks.
You have to define tmpFileName in global variable and use Event Exited like this:
try{
Process myProcess = new Process();
myProcess.StartInfo.FileName = tmpFileName;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(myProcess_Exited);
myProcess.Start();
}
catch (Exception ex){
//Handle ERROR
return;
}
// Method Handle Exited event.
private void myProcess_Exited(object sender, System.EventArgs e){
if (File.Exists(tmpFileName))
{
File.Delete(tmpFileName);
}
}
Hope it can help you
Update my answers:
If it still not working. Try this answers
I would just save the PDF file in the TEMP folder.
Either in Windows User TEMP folder or your App can create a TEMP folder. If you create a TEMP folder just delete every file when your app closed.
string filePath = Path.GetTempPath() + "yourfile.pdf";
//Writer your file to Path
//File.WriteAllBytes(filePath, content);
Process.Start(filePath);
I am trying to write a file on button click event but getting an unauthorized error when trying to do so.
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
{
string path = #"c:\program files\MyTest.txt";
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("Hello");
}
}
// Open the file to read from.
using (StreamReader sr = File.OpenText(path))
{
string s = "";
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
}
Getting the error by:
using (StreamWriter sw = File.CreateText(path))
Not sure what i am doing wrong? Could someone please help?
Thanks
By default in Windows a user or a programm started by a user can't write files to every location on a Windows pc.
Maybe try saving your file to a different location.
If that doesn't cut it for you, then you may need to look into running your programm at an elevated permission level
If you just want to save a file for your application the tippical place to do so would be the AppData Folder. The tipcal way of getting its path goes somthing like this:
string path=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+"/MyApplicationFolder";
You should change your path to authorize folder like :
string path=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
I have been making a text editor in c#, and recently added the functionality to silently save the file (without SaveFileDialog). The file appears to save properly, however, when trying to open the file, i get the error System.ArgumentException - File format is not valid. It opens fine if the file has not been saved silently.
The code:
The save method:
public void save(RichTextBoxPrintCtrl.RichTextBoxPrintCtrl rtbIn, string fileNameIn)
{
string fileName = "";
if (getFileFromMap(fileNameIn) != "")
{
// The file already exists in the Map so save it
fileName = getFileFromMap(fileNameIn);
StreamWriter writer = new StreamWriter(fileName);
writer.Write(rtbIn.Text);
writer.Close();
}
else
{
// The file does not exist in the Map so
// Send it to SaveAs with the rtb and the initial fileName passed in
saveAs(rtbIn, fileNameIn);
}
}
SaveAs:
public string saveAs(RichTextBoxPrintCtrl.RichTextBoxPrintCtrl rtbIn, string fileName)
{
saveDialog.FileName = fileName;
saveDialog.Title = "Save As";
if (saveDialog.ShowDialog() == DialogResult.OK)
{
if (saveDialog.FileName.Length > 0)
{
if (saveDialog.FileName.EndsWith(".rtf"))
{
rtbIn.SaveFile(saveDialog.FileName, RichTextBoxStreamType.RichText);
}
else
{
rtbIn.SaveFile(saveDialog.FileName, RichTextBoxStreamType.PlainText);
}
addFileToMap(fileName, saveDialog.FileName);
return Path.GetFileName(saveDialog.FileName);
}
else { return ""; }
}
else { return ""; }
}
and Open:
public string open(RichTextBoxPrintCtrl.RichTextBoxPrintCtrl rtbIn)
{
if (openDialog.ShowDialog() == DialogResult.OK)
{
if (openDialog.FileName.Length > 0)
{
string fileName = Path.GetFileName(openDialog.FileName);
if (fileName.EndsWith(".rtf"))
{
rtbIn.LoadFile(openDialog.FileName, RichTextBoxStreamType.RichText);
}
else
{
rtbIn.LoadFile(openDialog.FileName, RichTextBoxStreamType.PlainText);
}
addFileToMap(openDialog.FileName, openDialog.FileName);
return fileName;
}
else { return ""; }
}
else { return ""; }
}
Other information:
The filenames are stored in a Dictionary because the editor has tabs.
RichTextBoxPrintCtrl is a custom RichTextBox that supports printing, it doesn't change anything relating to opening
The methods above are in a separate class which is why they require the richtextbox to be passed in.
If you need any other code, just let me know.
Any advice would be appreciated! Thanks in advance :)
EDIT:
Fixed, couldn't use StreamWriter.
Well, the issue seems to be that you are not saving the file in the same way.
When you perform a saveAs, you are calling rtb.SaveFile. In your silent save you are directly trying to save the rtb.Text to the file but that is probably not the correct format rtb.OpenFile is expecting.
I am no expert whatsoever in RichTextBox but spotting the difference when on method works and another similar one doesn't normally helps.
To expand a little more, Text returns only the plain text (no content formatting information). Your method save is saving as plain text any file, even if its a .rtf. Your Open method on the other hand will try to open an .rtf file as a formatted text, this can be causing the issues you are having.
I have a Windows Forms app that is able to launch a console for debuggin. In the app, through a menu click, I read a CSV file and write it to the console. The function that does this is below.
protected void menuRead_Click(object sender, EventArgs e)
{
// ... functionality to load CSV files
System.IO.Stream inputDataFile = null;
OpenFileDialog fd = new OpenFileDialog();
fd.InitialDirectory = "c:\\";
fd.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
fd.FilterIndex = 1;
fd.RestoreDirectory = true;
if (fd.ShowDialog() == DialogResult.OK)
{
try
{
if ((inputDataFile = fd.OpenFile()) != null)
{
inputData_exists = true;
// ... read input data from CSV file
using (CsvFileReader reader = new CsvFileReader(inputDataFile))
{
CsvRow row = new CsvRow();
while (reader.ReadRow(row))
{
foreach (string s in row)
{
Console.Write(s);
Console.Write(" ");
}
Console.WriteLine();
}
// ... close the input data stream
inputDataFile.Close();
}
}
}
catch (Exception err)
{
//Inform the user if can't read the file
MessageBox.Show(err.Message);
}
}
}
Everything works fine except the following:
The csv file has about 1200 lines of code. When this code is executed, the OpenFileDialog() window only closes partially before the csv file contents begin to get written to the console window. So, I can see the data writing to the console window, and I have a small rectangular portion of the dialog window showing on my form. Is there any way to ensure the dialog is closed before the data is written to the console? Should I open anew thread to communicate with the console? Any advise or help woulf be greatly appreciated. Thank you.
You need to give some time for your control "OpenFileDialog" to repaint itself during dispose of the control, the easiest way for WinForm is to use Application.DoEvents()
if (fd.ShowDialog() == DialogResult.OK)
{
Application.DoEvents();
...
...
}
Your issue comes from the fact you display the console and your ShowDialog call. Get the result of the of Dialog then open your console application. You can also read the file on another thread I suppose.
You may use a lot of approaches here.
The simplest one:
Use StringBuilder and than put all data at once.
Because output to console may be quite slowly.
StringBuilder consoleBuffer = new StringBuilder();
using (CsvFileReader reader = new CsvFileReader(inputDataFile))
{
CsvRow row = new CsvRow();
while (reader.ReadRow(row))
{
foreach (string s in row)
{
consoleBuffer.Append(s);
consoleBuffer.Append(" ");
}
consoleBuffer.Append(Environment.NewLine);
}
Console.WriteLine(consoleBuffer.ToString());
// ... close the input data stream
inputDataFile.Close();
}