StreamWriter Insufficient Privileges With UnauthorizedAccessException - c#

I am using the following code to write a file to the Desktop.
string submittedFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
int i = 0;
StreamWriter sw = null;
sw = new StreamWriter(submittedFilePath, false);
for (i = 0; i < PSOLib.table.Columns.Count - 1; i++)
{
sw.Write(PSOLib.table.Columns[i].ColumnName + ";");
}
sw.Write(PSOLib.table.Columns[i].ColumnName);
sw.WriteLine();
foreach (DataRow row in PSOLib.table.Rows)
{
object[] array = row.ItemArray;
for (i = 0; i < array.Length - 1; i++)
{
sw.Write(array[i].ToString() + ";");
}
sw.Write(array[i].ToString());
sw.WriteLine();
}
sw.Close();
However whenever I try to invoke the method I get:
Access to the path 'C:\\Users\\User\\Desktop' is denied.
System.UnauthorizedAccessException.

You didn't specify a file for your StreamWriter, but a folder.
This should do it:
string submittedFilePath =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\myFile.txt.";

Related

C# How to display only file name in dataGridView without full path in Winforms

I want to display only filename with extenstion .pdf, but this code shows me fullpath plus filename.pdf , but I want to display only filename.pdf
Hers is my code and thank you in advance.
string installedPath = Application.StartupPath + "pdfFiles\\" + PatId.ToString() + "\\" + Regnr;
String[] files = Directory.GetFiles(installedPath);
DataTable table = new DataTable();
table.Columns.Add("File name");
for (int i = 0; i < files.Length; i++)
{
FileInfo file = new FileInfo(files[i]);
table.Rows.Add(file);
}
dgvFiles.DataSource = table;
Maybe not the most professional solution, but a string.Split should do the work
for (int i = 0; i < files.Length; i++)
{
string[] temp = files[i].Split('\\');
string fileName = temp.Last();
FileInfo file = new FileInfo(fileName);
table.Rows.Add(file);
}

CSV is not getting generated in the folder for console application

I want to generate a CSV file in my folder with the data coming from datatable. I have written the below code for that.
public static void CreateCSV(DataTable dt, string FileName)
{
try
{
string strFilePath = ConfigurationSettings.AppSettings["ExcelFilePath"].ToString() + "\\" + FileName;
if (!Directory.Exists(ConfigurationSettings.AppSettings["ExcelFilePath"].ToString()))
Directory.CreateDirectory(ConfigurationSettings.AppSettings["ExcelFilePath"].ToString());
StreamWriter sw = new StreamWriter(strFilePath, false);
DataTable dTemp = dt;
int iColCount = dTemp.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
sw.Write(dTemp.Columns[i]);
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
foreach (DataRow dr in dTemp.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
if (dr[i].ToString().Contains("\n"))
{
string x = dr[i].ToString().Replace("\n", "");
string xc = RemoveSpecialCharacters(x);
string xc1 = RemoveSpecialCharacters1(xc);
//sw.Write(x);
sw.Write(xc1.Replace(", ", ""));
}
else
{
string x = dr[i].ToString().Replace(",", "");
string xc = RemoveSpecialCharacters(x);
string xc1 = RemoveSpecialCharacters1(xc);
sw.Write(xc1.Replace(", ", ""));
}
}
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
}
sw.Close();
}
catch (Exception ex)
{
//ErrorLog.Insert(ex.Message, ex.StackTrace, "Program.cs - MailReport", null);
}
}
And the folder path which I have set in app.config file is below:
<add key="ExcelFilePath" value="ExcelData" />
but still the CSV file is not getting created. Am I missing something?
You still have a relative path not an absolute one. You need an absolute one.
Use
strFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationSettings.AppSettings["ExcelFilePath"].ToString(), FileName);
and
Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationSettings.AppSettings["ExcelFilePath"].ToString()));
to create the directory. No need to check if directory exists, CreateDirectory will only try to create it if it does not exist.

How to clear previous lines from StreamWriter?

void BuildProjects()
{
String outputPath = #"D:\PIT\ProcessImprovementTool\DLL";
console = new Process();
console.StartInfo.FileName = "cmd.exe";
console.StartInfo.UseShellExecute = false;
console.StartInfo.CreateNoWindow = true;
console.StartInfo.RedirectStandardInput = true;
console.StartInfo.RedirectStandardOutput = true;
console.StartInfo.RedirectStandardError = true;
console.Exited += new EventHandler((sender, e) =>
{
Console.WriteLine("if (console.Exited) --> ExitCode: " + console.ExitCode);
BuildProjects();
});
console.OutputDataReceived += new DataReceivedEventHandler(ConsoleOutputHandler);
console.ErrorDataReceived += new DataReceivedEventHandler(ConsoleOutputHandler);
console.Start();
using (StreamWriter sw = console.StandardInput)
{
sw.AutoFlush = true;
console.StandardInput.AutoFlush = true;
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("D:\\PIT\\ProcessImprovementTool\\callVcvars32.bat");
sw.WriteLine("cls");
for (int ctr = 0; ctr < 5; ctr++)
{
sw.WriteLine("msbuild /property:OutputPath=" + outputPath + #";OutputType=Library " + lines[ctr]);
//console.BeginOutputReadLine();
sw.Flush();
}
}
if (tryout)
{
Console.WriteLine("working");
}
sw.Close();
//sw.Flush();
}
console.BeginOutputReadLine();
console.BeginErrorReadLine();
//console.WaitForExit();
counter++;
}
in the
for (int ctr = 0; ctr < 5; ctr++)
{
sw.WriteLine("msbuild /property:OutputPath=" + outputPath + #";OutputType=Library " + lines[ctr]);
//console.BeginOutputReadLine();
sw.Flush();
}
if i set the limit for ctr to 40 (ctr < 40) my application hangs, and I get that the stream is already at its limit.
Based on my research, .Flush() should do the trick. or setting AutoFlush to True, but doesn't seem to work.
so how do I clear previous stream records, or anything that would let me input more than 40 lines? (i got 100+ but not more than 150 lines to write in streamWriter).
lines variable stores the value of "build.txt".
void readFromBuild()
{
doneReading = true;
lines = System.IO.File.ReadAllLines(#"D:\PIT\ProcessImprovementTool\Build\build.txt");
//System.Console.WriteLine("Contents of WriteLines2.txt = ");
foreach (string line in lines)
{
lineCount++;
}
Console.WriteLine(lineCount);
lineCount = lineCount - limit;
}
"build.txt" contains all files to be compiled to produce DLL files.
For me, this is as good as answered. I just did it in another way, though it may not be that good.
buildProgress.Enabled = true;
buildProgress.Maximum = lineCount;
for (int ctr = 0; ctr < lineCount; ctr++)
{
String outputPath = #"Q:\";
StreamReader reader;
String outputLine;
console = new Process();
console.StartInfo.FileName = "cmd.exe";
console.StartInfo.UseShellExecute = false;
console.StartInfo.CreateNoWindow = true;
console.StartInfo.RedirectStandardInput = true;
console.StartInfo.RedirectStandardOutput = true;
console.StartInfo.RedirectStandardError = true;
console.Start();
using (StreamWriter sw = console.StandardInput)
{
sw.AutoFlush = true;
console.StandardInput.AutoFlush = true;
if (sw.BaseStream.CanWrite)
{
sw.WriteLine(#"Q:\");
sw.WriteLine("msbuild /property:OutputPath=" + outputPath + #";OutputType=Library " + lines[ctr]);
sw.Flush();
}
sw.Close();
}
reader = console.StandardOutput;
outputLine = reader.ReadToEnd();
console.WaitForExit();
//if (console.HasExited)
//{
Console.Write(outputLine);
//outputTextBox.Text += outputLine;
pathToLog = #"Q:\" + fileList[ctr];
File.Create(pathToLog).Dispose();
File.WriteAllText(pathToLog, outputLine);
buildProgress.Value = ctr;
string[] readThatLog = File.ReadAllLines(pathToLog);
foreach(string line in readThatLog)
{
if (line == "Build succeeded.")
{
outputTextBox.AppendText(lines[ctr]);
outputTextBox.AppendText(Environment.NewLine + line);
outputTextBox.AppendText(Environment.NewLine + Environment.NewLine);
}
else if (line == "Build FAILED.")
{
outputTextBox.AppendText(lines[ctr]);
outputTextBox.AppendText(Environment.NewLine + line);
outputTextBox.AppendText(Environment.NewLine + Environment.NewLine);
}
}
//}
}
buildProgress.Value = 0;
buildProgress.Enabled = false;
Console.WriteLine("\n\n\n\nDONE!!!");

Alternative to ReadLine?

I'm trying to read some files with ReadLine, but my file have some break lines that I need to catch (not all of them), and I don't know how to get them in the same array, neither in any other array with these separators... because... ReadLine reads lines, and break these lines, huh?
I can't replace these because I need to check it after the process, so I need to get the breaklines AND the content after that. That's the problem. How can I do that?
Here's my code:
public class ReadFile
{
string extension;
string filename;
System.IO.StreamReader sr;
public ReadFile(string arquivo, System.IO.StreamReader sr)
{
string ext = Path.GetExtension(arquivo);
sr = new StreamReader(arquivo, System.Text.Encoding.Default);
this.sr = sr;
this.extension = ext;
this.filename = Path.GetFileNameWithoutExtension(arquivo);
if (ext.Equals(".EXP", StringComparison.OrdinalIgnoreCase))
{
ReadEXP(arquivo);
}
else MessageBox.Show("Extensão de arquivo não suportada: "+ext);
}
public void ReadEXP(string arquivo)
{
string line = sr.ReadLine();
string[] words;
string[] Separators = new string[] { "<Segment>", "</Segment>", "<Source>", "</Source>", "<Target>", "</Target>" };
string ID = null;
string Source = null;
string Target = null;
DataBase db = new DataBase();
//db.CreateTable_EXP(filename);
db.CreateTable_EXP();
while ((line = sr.ReadLine()) != null)
{
try
{
if (line.Contains("<Segment>"))
{
ID = "";
words = line.Split(Separators, StringSplitOptions.None);
ID = words[0];
for (int i = 1; i < words.Length; i++ )
ID += words[i];
MessageBox.Show("Segment[" + words.Length + "]: " + ID);
}
if (line.Contains("<Source>"))
{
Source = "";
words = line.Split(Separators, StringSplitOptions.None);
Source = words[0];
for (int i = 1; i < words.Length; i++)
Source += words[i];
MessageBox.Show("Source[" + words.Length + "]: " + Source);
}
if (line.Contains("<Target>"))
{
Target = "";
words = line.Split(Separators, StringSplitOptions.None);
Target = words[0];
for (int i = 1; i < words.Length; i++)
Target += words[i];
MessageBox.Show("Target[" + words.Length + "]: " + Target);
db.PopulateTable_EXP(ID, Source, Target);
MessageBox.Show("ID: " + ID + "\nSource: " + Source + "\nTarget: " + Target);
}
}
catch (IndexOutOfRangeException e)
{
MessageBox.Show(e.Message.ToString());
MessageBox.Show("ID: " + ID + "\nSource: " + Source + "\nTarget: " + Target);
}
}
return;
}
If you are trying to read XML, try using the built in libaries, here is a simple example of loading a section of XML with <TopLevelTag> in it.
var xmlData = XDocument.Load(#"C:\folder\file.xml").Element("TopLevelTag");
if (xmlData == null) throw new Exception("Failed To Load XML");
Here is a tidy way to get content without it throwing an exception if missing from the XML.
var xmlBit = (string)xmlData.Element("SomeSubTag") ?? "";
If you really have to roll your own, then look at examples for CSV parsers,
where ReadBlock can be used to get the raw data including line breaks.
private char[] chunkBuffer = new char[4096];
var fileStream = new System.IO.StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
var chunkLength = fileStream.ReadBlock(chunkBuffer, 0, chunkBuffer.Length);

Getting access denied when try to delete file

I'm getting access denied whenever I try to delete a file after finishing reading it at C:\inetpub\wwwroot\Project\temp\. I Close() and Dispose() the StreamReader properly already? I also gave full permission for NETWORK SERVICE account? Can anyone help me?
reader = new StreamReader(path + fileName);
DataTable dt = new DataTable();
String line = null;
int i = 0;
while ((line = reader.ReadLine()) != null)
{
String[] data = line.Split(',');
if (data.Length > 0)
{
if (i == 0)
{
dt.Columns.Add(new DataColumn());
foreach (object item in data)
{
DataColumn c = new DataColumn(Convert.ToString(item));
if (Convert.ToString(item).Contains("DATE"))
{
c.DataType = typeof(DateTime);
}
else { c.DataType = typeof(String); }
dt.Columns.Add(c);
}
dt.Columns.Add(new DataColumn("CreatedDate", typeof(DateTime)));
i++;
}
else
{
DataRow row = dt.NewRow();
row[0] = "";
for (int j = 0; j < data.Length; j++)
{
if (dt.Columns[j + 1].DataType == typeof(DateTime))
{
row[j + 1] = Convert.ToDateTime(data[j]);
}
else
{
row[j + 1] = data[j];
}
}
row[data.Length + 1] = DateTime.Now.ToString();
dt.Rows.Add(row);
}
}
}
DataAccess dataAccess = new DataAccess(Constant.CONNECTION_STRING_NAME);
dataAccess.WriteBulkData(dt, Constant.TABLE);
reader.Close();
reader.Dispose();
File.Delete(path);
Your File.Delete method call should take path + fileName as parameter. This is because according to this link http://msdn.microsoft.com/en-us/library/system.io.file.delete.aspx path is the full path including the filename and your path variable includes only the folder name.
I also had the problem, hence me stumbling on this post to server. I added the following line of code before and after a Copy / Delete.
Delete
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
Copy
File.Copy(file, dest, true);
File.SetAttributes(dest, FileAttributes.Normal);
Link: Why is access to the path denied?
You're deleting File.Delete(path); not File.Delete(path + filename);
You are opening
reader = new StreamReader(path + fileName);
But you are closing
File.Delete(path);

Categories

Resources