Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to to write data to a log file but nothing gets written to the file.
Aim of the program is to run a continuous loop and keep looking for file, if file is valid, process it and move it. I am logging for any errors and items that are created.
Also, how can I make my log file access able while the loop is running so that I can see that values got appended.
static void Main(string[] args)
{
var logFile = File.Create(filePath + "\\log_" + DateTime.Today.ToString("MMMM") + ".txt").ToString();
while (true)
{
try
{
var moveTo = Directory.CreateDirectory(#"" + directoryPath + "Processed_" + DateTime.Today.ToString("MMMM"));
var files = Directory.GetFiles(filePath);
var todaysDate = DateTime.Now.Date;
var firstOfMonth = new DateTime(todaysDate.Year, todaysDate.Month, 1);
var monthEnd = firstOfMonth.AddMonths(1).AddDays(-1);
if (todaysDate == monthEnd)
{
File.Move(logFile, #"" + moveToNewPath + logFile);
}
foreach (var fileName in files)
{
if (fileName.Contains("myFile.csv"))
{
var fileValues = File.ReadAllLines(filePath + fileName.Substring(44)).Skip(1).Select(v => new myFile(v)).ToList();
foreach (var i in fileValues)
{
try
{
var jsonValues = ValueFromFile(i);
var response = UploadData(url, username, password, values);
this should be written to a log file ===> .File.AppendAllText(logFile, Environment.NewLine + DateTime.Now + "\t" + response);
}
catch (Exception exception)
{
File.AppendAllText(logFile, Environment.NewLine + DateTime.Now + "\t" + exception.Message.Replace("\n", " "));
}
}
File.Move(fileName, #"" + directoryPath + "\\" + moveTo + "\\" + "processedMyFile" + DateTime.Now.Date.ToString("MM-dd-yy") + ".csv");
}
}
}
catch (Exception exception)
{
File.AppendAllText(logFile, Environment.NewLine + DateTime.Now + "\t" + exception.Message.Replace("\n", " "));
}
}
}
Let's start with this line at the top of the program:
var logFile = File.Create(filePath + "\\log_" + DateTime.Today.ToString("MMMM") + ".txt").ToString();
I'm not sure what you're doing with that ToString() call hanging off the end. It almost certainly doesn't do what you think it does. But I really want to take a closer look at the documentation for the File.Create() method here. Specifically, this excerpt:
The FileStream object created by this method has a default FileShare value of None; no other process or code can access the created file until the original file handle is closed.
Uh oh. That means the File.AppendAllText() call later on will be out of luck. But let's look at the AppendAllText() documentation. Specifically this:
The method creates the file if it doesn’t exist
Meaning you can just remove the problem line at the top. You neither need nor want it. Or maybe you just want to create the file name there, like this:
var logFile = Path.Combine(filePath, "log_" + DateTime.Today.ToString("MMMM") + ".txt");
As a bonus, I'd explore changing this code to use System.Diagnostics.Trace in conjunction with FileTraceListener and maybe a ConsoleTraceListener attached.
static string moveToNewPath = "...";
static string filePath = "...";
static string logFormat = "\n{0:s}\t{1}";
static string logFile = "";
static string directoryPath = "...";
static void LogMessage(string FilePath, string Message)
{
File.AppendAllText(Path.Combine(filePath, logFile),
string.Format(logFormat, DateTime.Now, Message.Replace("\n", " ")));
}
static void Main(string[] args)
{
logFile = "log_" + DateTime.Today.ToString("MMMM") + ".txt";
//Rotate log file on last day of month
try
{
var todaysDate = DateTime.Now.Date;
var firstOfMonth = new DateTime(todaysDate.Year, todaysDate.Month, 1);
var monthEnd = firstOfMonth.AddMonths(1).AddDays(-1);
if (todaysDate == monthEnd)
{
File.Move(Path.Combe(filePath, logFile), Path.Combine(moveToNewPath, logFile));
}
}
catch (Exception ex)
{
LogMessage(ex.Message);
}
while (true)
{
// !!!!!!!!!!!!!!
//Log rotate code used to be here... but... you need something to be sure this only happens once per day.
// I STRONGLY suspect this code should be setup to run as
// a SCHEDULED TASK set to run once per day or maybe once per hour, rather than an always-on background program.
// !!!!!!!!!!!!!!!!
try
{
var moveTo = Path.Combine(directoryPath, "Processed_" + DateTime.Today.ToString("MMMM"));
Directory.CreateDirectory(moveTo);
var files = Directory.GetFiles(filePath).Where(f => f.EndsWith("myFile.csv"));
foreach (var fileName in files)
{
var fileValues = File.ReadAllLines(filePath + fileName.Substring(44)).Skip(1).Select(v => new myFile(v));
foreach (var i in fileValues)
{
try
{
var jsonValues = ValueFromFile(i);
var response = UploadData(url, username, password, jsonValues);
LogMessage(response);
}
catch (Exception ex)
{
LogMessage(ex.Message);
}
}
File.Move(fileName, Path.Combine(moveTo, "processedMyFile" + DateTime.Now.Date.ToString("MM-dd-yy") + ".csv"));
}
}
catch (Exception ex)
{
LogMessage(ex.Message);
}
}
}
Related
I have re-edited my question since the problem lies elsewhere.
I have this piece of code to drop the files from outlook (single or multiple) at specific win form. On windows 7 stations the copy is made, but on windows 10 cannot get the list of filename from class.
public class OutlookDataObject : System.Windows.Forms.IDataObject
Class shown on this post
This class is working on Working code for win 7 but no filename return on windwos 10. This huge class is way over my understanding.
There is a simple way to get from outlook the selected attachements to prepare them to drop ?
private void btn_Home_DragDrop(object sender, DragEventArgs e)
{
bool debug = true;
if (debug) { txt_FileInfo.AppendText("Entering drop method " + Environment.NewLine); }
folderBrowserDialog1.SelectedPath = LastSelectedFolder.GlobalVar;
if (debug)
{ txt_FileInfo.AppendText("Get last path " + Environment.NewLine); }
folderBrowserDialog1.Description = "Drop the files";
if (debug)
{ txt_FileInfo.AppendText("Show folder dialog " + Environment.NewLine); }
if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
{
return;
}
LastSelectedFolder.GlobalVar = folderBrowserDialog1.SelectedPath.ToString();
if (debug)
{ txt_FileInfo.AppendText("Path is selected " + LastSelectedFolder.GlobalVar + Environment.NewLine); }
string[] fileNames = null;
if (debug)
{ txt_FileInfo.AppendText("Prepare to transfer " + Environment.NewLine); }
if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
{
if (debug)
{ txt_FileInfo.AppendText("DataFormats.FileDrop " + Environment.NewLine); }
fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string fileName in fileNames)
{
// do what you are going to do with each filename
string destinationFile = Path.Combine(folderBrowserDialog1.SelectedPath, Path.GetFileName(fileName));
if (debug)
{ txt_FileInfo.AppendText("Destination File " + destinationFile + Environment.NewLine); }
if (Operation.CopyFile(fileName, destinationFile, ci))
{
txt_FileInfo.AppendText("File have been copied to " + destinationFile + Environment.NewLine);
}
}
}
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
if (debug)
{ txt_FileInfo.AppendText("FileGroupDescriptor " + Environment.NewLine); }
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
{
if (debug)
{ txt_FileInfo.AppendText("Files in attachement " + filenames[fileIndex] + Environment.NewLine); }
string path = Path.GetTempPath();
// put the zip file into the temp directory
string theFile = path + filenames[fileIndex].ToString();
// create the full-path name
if (debug)
{ txt_FileInfo.AppendText("Get temp Path " + theFile + Environment.NewLine); }
//
// Second step: we have the file name.
// Now we need to get the actual raw
// data for the attached file and copy it to disk so we work on it.
//
// get the actual raw file into memory
MemoryStream ms = (MemoryStream)e.Data.GetData(
"FileContents", true);
// allocate enough bytes to hold the raw data
byte[] fileBytes = new byte[ms.Length];
// set starting position at first byte and read in the raw data
ms.Position = 0;
ms.Read(fileBytes, 0, (int)ms.Length);
// create a file and save the raw zip file to it
FileStream fs = new FileStream(theFile, FileMode.Create);
fs.Write(fileBytes, 0, (int)fileBytes.Length);
fs.Close(); // close the file
FileInfo tempFile = new FileInfo(theFile);
// always good to make sure we actually created the file
if (tempFile.Exists == true)
{
// for now, just delete what we created
string fileName = tempFile.FullName;
string destinationFile = Path.Combine(folderBrowserDialog1.SelectedPath, Path.GetFileName(fileName));
if (debug)
{ txt_FileInfo.AppendText("destinationFile " + destinationFile + Environment.NewLine); }
if (debug)
{ txt_FileInfo.AppendText("Prepare to copy " + destinationFile + Environment.NewLine); }
if (Operation.CopyFile(fileName, destinationFile, ci))
{
txt_FileInfo.AppendText("File have been copied to " + destinationFile + Environment.NewLine);
}
else
{
if (debug)
{ txt_FileInfo.AppendText("Copy failed " + " Source " + fileName + " Destination " + destinationFile + Environment.NewLine); }
}
tempFile.Delete();
if (debug)
{ txt_FileInfo.AppendText("Delete temp file " + tempFile + Environment.NewLine); }
}
else
{ Trace.WriteLine("File was not created!"); }
// catch (Exception ex)
//{
// Trace.WriteLine("Error in DragDrop function: " + ex.Message);
// // don't use MessageBox here - Outlook or Explorer is waiting !
//}
}
}
}
I will replay here quote from here. For above class to work on win 8 + couple of line to be changed (from int to long)
from:
IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
to
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
from:
fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
to
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
Use this:
MemoryStream ms = (MemoryStream)dataObject.GetData("FileContents", fileIndex);
Instead of this:
MemoryStream ms = (MemoryStream)dataObject.GetData("FileContents", true);
So it parses every files.
EDIT:
Actually, it doesn't work neither unless program is compiled in Debug rather than Release... It will only work in Debug for some reason
I'm getting an error with StreamWriter that the file is in use by another process, but I believe it may be down to the speed at which I'm writing the file or more specifically the speed of it being opened/closed.
The code is as follows:
public static void writeLog(string msg)
{
StreamWriter log;
string currentMonth = DateTime.Now.ToString("MMM");
string currentYear = DateTime.Now.ToString("yyyy");
string directoryName = currentMonth + "-" + currentYear;
if (!Directory.Exists(#"C:\AutoSkill\LogFiles\" + directoryName + #"\"))
{
Directory.CreateDirectory(#"C:\AutoSkill\LogFiles\" + directoryName + #"\");
}
DateTime dt = DateTime.Now;
string date = dt.ToString("dd-MM-yy");
if (!File.Exists(#"C:\AutoSkill\LogFiles\" + directoryName + #"\" + date + ".txt"))
{
log = new StreamWriter(#"C:\AutoSkill\LogFiles\" + directoryName + #"\" + date + ".txt");
}
else
{
log = File.AppendText(#"C:\AutoSkill\LogFiles\" + directoryName + #"\" + date + ".txt");
}
try
{
log.WriteLine(msg);
}
catch (Exception err)
{
Console.WriteLine("There was an error writing to the log file.");
Console.WriteLine(err.Message);
}
log.Close();
}
So I'm closing the log each time I'm done writing to it, but I'm writing all out my output from the console screen to the file to keep track of what actually happened; sometimes the lines are only a few milliseconds apart if the action that was taken was quick or just returned null.
Am i getting this error due to speed of writing to the file? Is there a better way to handle writing a log file?
Disregard this, I'm dumb.
I've not had this problem for the last 2 years, I'm getting the error because I'm writing to the same file from a different thread, which is where the overlap is.
The file actually is in use by another process, the same one just a different thread.
I am building a program that will move a bunch of files.
if (line.Contains("INSERT INTO BACKLOGITEM_ATTACHMENT VALUES"))
{
string AttachementID = line.Split(',', ')')[1];
string FileName = AttachementsDictionary[AttachementID];
string BacklogScrumID = BacklogLookupDictionary[AttachementID];
BacklogItem Story = BacklogItemDictionary[BacklogScrumID];
Product Product = ProductDictionary[Story.ProductScrumId];
string FileToCopy = "\\\\dxScrum01v\\ScrumWorksPro\\scrumworks\\data\\attachments\\product" + Story.ProductScrumId + "\\attachement" + AttachementID;
string FileToSave = "C:\\ScrumWorksAttachementExport\\" + Product.ProductName + "\\" + Product.StoryPrefix + "-" + Story.StoryTitle + "\\" + FileName;
//Console.WriteLine(FileToCopy + " >>> " + FileToSave);
try
{
File.Copy(#FileToCopy, #FileToSave);
}
catch (Exception)
{
Console.WriteLine("Failed: " + FileToSave);
throw;
}
}
The issue is that I am getting an exception when running the program. There are times when the file does not exist.
How can I make it so that if it fails it just outputs the failure and keeps going?
Remove throw; if you dont want your application to break, you can handle the exception too
i have a cloud database server like application on my computer that i'm hosting my game on. However, every time an user tries to save data i get an UnauthorizedAccessException.
Im running it by admin and i dont have any specias right in my folder so i have no idea what's the problem.
Here's my code:
public const string root = "D:/DATABASE/";
public static void WriteData(string playername, string type, string data)
{
if (!Directory.Exists("D:/DATABASE/" + playername))
{
Directory.CreateDirectory("D:/DATABASE/" + playername);
Directory.CreateDirectory("D:/DATABASE/" + playername + "/weapons");
}
if (type != "Weapon")
{
using (StreamWriter sw = new StreamWriter("D:/DATABASE/" + playername + "/" + type + ".sav"))
{
sw.WriteLine(data);
}
}
else
{
string[] dat = data.Split('%');
using (StreamWriter sw = new StreamWriter("D:/DATABASE/" + playername + "/weapons/" + dat[0] + ".gfa"))
{
string[] lines = dat[1].Split('#');
foreach (string cline in lines)
{
sw.WriteLine(cline);
}
}
}
}
public static string ReadLoadout(string playername)
{
string output = "";
string[] items = new string[2];
using (StreamReader sr = new StreamReader(root + playername + "/loadout.gfl"))
{
items[0] = sr.ReadLine();
items[1] = sr.ReadLine();
}
int c = 0;
foreach (string citem in items)
{
if (c > 0) output += "$";
output += citem + "%" + GetCompressedWeaponFile(playername, citem);
c++;
}
return output;
}
public static string GetCompressedWeaponFile(string playerName, string weaponName)
{
string output = "";
using (StreamReader sr = new StreamReader(root + playerName + "/weapons/" + weaponName))
{
string line = " ";
int c = 0;
while (line != null)
{
line = sr.ReadLine();
if (line != null)
{
if (c > 0) output += "#";
output += line;
}
c++;
}
}
return output;
}
public static void RegisterNewUser(string username, string password, string email)
{
string udir = root + username;
Directory.CreateDirectory(udir);
Directory.CreateDirectory(udir + "/weapons");
Directory.CreateDirectory(udir + "/loadouts");
File.WriteAllText(udir + "/password.sav", password);
File.WriteAllText(udir + "/level.sav", "1");
File.WriteAllText(udir + "/money.sav", "1000");
File.WriteAllText(udir + "/email.sav", email);
File.WriteAllText(udir + "/loadout.gfl", "");
using (StreamWriter sw = new StreamWriter(root + "emails.txt", true))
{
sw.WriteLine(email);
}
Email.Send(email, "New Account Registration", string.Format(mailTemplate, username, password));
}
public static void EditLoadout(string username, string items)
{
File.WriteAllLines(root + username + "/loadout.gfl",items.Split('#'));
}
It is difficult to provide specific help without more information. Here are a few of troubleshooting suggestions:
1) Try running your code on a different machine. Specifically your development computer. Do you still have the same error? If not, then there is indeed a permission problem.
2) Have you tried checking the stack trace of the exception?
When you run the application on your own computer, try using the IDE to display the exception. Yes, the problem may ultimately be in a low-level class, but you should be able to break on the error and go back in the call stack to see which method in your code is actually throwing the error.
3) Check the actual exception, even for a system-level exception.
Chances are, if you are able to debug this in the IDE, that you will see property information that will give you a hint. Is it in a directory method or a file write method? Check additional properties. Somewhere it might give you the text of the path (assuming it's a file issue) that it failed on that that could help narrow things down too.
4) Add Exception handling to your code
This is a good rule of thumb, and you should really do this anyway to make a stronger program. Regardless of who's method you are calling (yours, someone else's, or a system method) you need to determine where it should be handled.
For example, in your code, in the RegisterNewUser() method, consider something like:
public static void RegisterNewUser(string username, string password, string email)
{
try
{
string udir = root + username;
Directory.CreateDirectory(udir);
Directory.CreateDirectory(udir + "/weapons");
Directory.CreateDirectory(udir + "/loadouts");
File.WriteAllText(udir + "/password.sav", password);
File.WriteAllText(udir + "/level.sav", "1");
File.WriteAllText(udir + "/money.sav", "1000");
File.WriteAllText(udir + "/email.sav", email);
File.WriteAllText(udir + "/loadout.gfl", "");
using (StreamWriter sw = new StreamWriter(root + "emails.txt", true))
{
sw.WriteLine(email);
}
Email.Send(email, "New Account Registration", string.Format(mailTemplate, username, password));
}
catch (Exception ex)
{
// Create a method to display or log the exception, with it's own error handler
LogAndDisplayExceptions(ex);
// Send the user a message that we failed to add them. Put this in it's own try-catch block
// ideally, for readability, in it's own method.
try
{
Email.Send(email, "Failed to register", "An error occurred while trying to add your account.");
}
catch (Exception exNested)
{
LogAndDisplayExceptions(exNested);
}
}
}
5) Add a "crash-and-burn" exception handler to "main"
In the method that is your "top method" (it's hard to tell in the snippet you provided since there are few methods that would attempt to write to the disk) you could wrap your code in a try - catch block and print the exception or write it to disk.
If you have having trouble writing the exception to disk, I would suggest creating an error file first, make sure that the user account that is running the program can write to it, and then in the catch block open the file for APPEND. This should make it easier to get to the error text.
6) When all else fails, use the Debug class or Console class to write the traditional "I made it to line x."
While this will not solve your problem, it should help you get more information that will provide more insight into where your code is causing an error.
This is main program.cs
LogError.WriteError("Application started: " + DateTime.Now + Environment.NewLine);
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CrawlerApp());
}
catch (Exception e)
{
LogError.WriteError(e);
}
LogError.WriteError("Application closed: " + DateTime.Now + Environment.NewLine);
and this is LogError class
public static class LogError
{
public static void WriteError(Exception e)
{
WriteError("Message: " + e.Message + Environment.NewLine + "Stack trace: " + e.StackTrace);
}
public static void WriteError(string error)
{
try
{
StreamWriter sw = File.AppendText("log.txt");
sw.WriteLine(DateTime.Now + Environment.NewLine);
sw.WriteLine(error + Environment.NewLine);
sw.WriteLine(Environment.NewLine);
sw.Close();
}
catch (Exception)
{
//
}
}
}
When i publish application and run it log.txt file is never created. If i run application from bin/debug folder then works. Why when i publish app logging not working. I am using win 2003 OS.
It could be an UnauthorizedAccessException.
Rather than guess at it you might want to change your catch to log to the event log rather than just swallowing it
File.AppendText only works if the file already exists: http://msdn.microsoft.com/en-us/library/system.io.file.appendtext.aspx. This link also has this sample code:
string path = #"c:\temp\MyTest.txt";
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("Hello");
sw.WriteLine("And");
sw.WriteLine("Welcome");
}
}
// This text is always added, making the file longer over time
// if it is not deleted.
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine("This");
sw.WriteLine("is Extra");
sw.WriteLine("Text");
}
you could use this code too, it works whether the file exits or not. As a plus it creates the log file based on the current DateTime in YYYYMMDD format
private static void doLog(String message)
{
//getting current date
String dateStr = "";
int day, month, year;
year = System.DateTime.Now.Year;
month = System.DateTime.Now.Month;
day = System.DateTime.Now.Day;
dateStr += year.ToString() + "";
if (month < 10) dateStr += "0";
dateStr += month.ToString() + "";
if (day < 10) dateStr += "0";
dateStr += day.ToString() + "";
//writting the message
string logFile = Environment.CurrentDirectory + #"/LOG_" + dateStr + #".txt";
System.IO.StreamWriter sw = new System.IO.StreamWriter(logFile, true);
sw.WriteLine(System.DateTime.Now.ToString() + "\t" + message);
sw.Close();
}
Your log-writing code is probably throwing an exception. Try removing the try/catch in WriteError to see what exception is being thrown.