When using a C# console app, all the commands I input get buffered during the life of the session (ie. until I close the Console).
I would now like to be able to back up this buffer and retrieve it next time I relaunch my console app.
I have read a few threads on SOF and got some pointer to "SetConsoleHistoryInfo", but I am not sure that is the way to go, nor how to use it for that matter.
Has anyone ever done something similar?
You could read each command you input and save it into a .txt file. If you are writing directly to the console you can save the string from the Console.ReadLine() function into a variable and then write it to the historical file.
The next time you run your program, have a method that checks the .txt file and retrieves the commands in whatever format you desire (array, line by line etc.)
This gives you flexibility as to how you manage the .txt file as well, you can keep the historical commands from every time your program has run or just the previous execution.
Related
I work on an app where user can type in some text. Text is saved to XML file, I try to make the file save “on the fly” as user is typing so it saves instantly. However if data is typed quick, I get an error of “file currently in use”. How to overcome this issue?
The reason for the error is that you are trying to write a file while the previous write operation is incomplete and the file is still open for write.
Now, if you absolutely must make a write on every character change - I would put in a queue in place, so when XML content is changed - instead of writing to a file right away - agg a message to a queue. Then have the code that monitors that queue and only writes the next chnage once the previous write has finished.
You can try to put a flag to control if the file is already open or not. If this is open, you keep the text and don't write on XML, but if it is not you just write.
This is a concurrency problem, you can acess the website: https://www.oreilly.com/library/view/concurrency-in-c/9781491906675/ch01.html to get more options.
I am looking for an idea on how I can launch a C# process based on something happening on a Windows server. My first challange is to determine when to start the first process. It needs to monitor a SFTP folder to see if a certain file type has been delivered. My initial thought was to have the task scheduler start a Perl script, have the script look to see if the file exists and then start the process. But once it has started the process, I don't want it to look for the file till the next day.
The second issue is that the first process moves files to another folder and then a third party application will start converting these files from PDFs to TEXT. The second process needs to start when this is done. I am not sure how to make this happen.
Thoughts??????
Write a windows service which uses a filewatcher to monitor for new files. https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
That can then use File.Move to move the file out and into the alternate directory for further processing. https://msdn.microsoft.com/en-us/library/system.io.file.move(v=vs.110).aspx
I would use a Task for this and a task.continuewith to kick off the next 'stage' of your workflow, etc. Might also want to do a file COPY first, then a file delete (instead of a move, that way if something screws up during the copy you still have your original to work with).
I need to read a text based log file to check for certain contents (the completion of a backup job). Obviously, the file is written to when the job completes.
My question is, how can I (or how SHOULD I write the code to) read the file, taking into account the file may be locked, or locked by my process when it needs to be read, without causing any reliability concerns.
Assuming the writing process has at least specified System.IO.FileShare.Read when opening the file, you should be able to read the text file while it is still being written to.
In addition to the answer by #BrokenGlass:
Only open the file for reading. If you try to open it for Read/Write access, it's more likely (almost certain) to fail - you may not be able to open it, and/or you may stop the other process being able to write to it.
Close the file when you aren't reading it to minimise the chance that you might cause problems for any other processes.
If the writing process denies read access while it is writing to the file, you may have to write some form of "retry loop", which allows your application to wait (keep retrying) until the file becomes readable. Just try to open the file (and catch errors) - if it fails, Sleep() for a bit and then try again. (However, if you're monitoring a log file, you will probbably want to keep checking it for more data anyway)
When a file is being written to, it is locked for all other processes that try to open the file in Write-mode. Read-mode will always be available.
However, if your writing process saves changes while you have already opened the file in your reading process, the changes will not be reflected there until you refresh (Close-Open) the file again.
I am working on an app that will keep a running index of work in accomplished.
I could write once at the end of a work session, but I don't want to risk losing data if something blows up. Therefore, I rewrite to disk (XML) every time a new entry or a correction is made by the user.
private void WriteIndexFile()
{
XmlDocument IndexDoc
// Build document here
XmlTextWriter tw = new XmlTextWriter(_filePath, Encoding.UTF8);
tw.Formatting = Formatting.Indented;
IndexDoc.Save(tw);
}
It is possible for the writes to be triggered in rapid succession. If this happens, it tries to open the file for writing before the prior write is complete. (While it would not be normal, I suppose it is possible that the file gets opened for use by another program.)
How can I check if the file can be re-written?
Edit for clarification: This is part of an automated lab data collection system. The users will click a button to capture data (saved in separate files), and identify the sub-task the the data package is for. Typically, it will be 3-10 minutes between clicks.
If they make an error, they need to be able to go back and correct it, so it's not an append-only usage.
Finally, the files will be read by other automated tools and manually by humans. (XML/XSLT)
The size will be limited as each work session (worker shift or less) will have a new index file generated.
Further question: As the overwhelming consensus is to not use XML and write in an append-only mode, how would I solve the requirement of going back and correcting earlier entries?
I am considering having a "dirty" flag, and save a few minutes after the flag is set and upon closing the work session. If multiple edits happen in that time, only one write will occur - no more rapid user - also have a retry/cancel dialog if the save fails. Thoughts?
XML is a poor choice in your case because new content has to be inserted before the closing tag. Use Text istead and simply open the file for append and write the new content at the end of the file, see How to: Open and Append to a Log File.
You can also look into a simple logging framework like log4net and use that instead of handling the low level file stuff urself.
If all you want is a simple log of all operations, XML may be the wrong choice here as it is difficult to append to an XML document without rewriting the whole file, which will become slower and slower as the file grows.
I'd suggest instead File.AppendText or even better: keeping the file open for the duration of the aplication's life time and using WriteLine.
(Oh, and as others have pointed out, you need to lock to ensure that only one thread writes to the file at a time. This is still true even with this solution.)
There are also logging frameworks that already solve this problem, such as log4net. Have you considered using an existing logging framework instead of rolling your own?
I have a logger that uses System.Collections.Queue. Basically it waits until something is queued then trys to write it. While writing items, which could be slow, more items could be added to the queue.
This will also help in just grouping messages rather than trying to keep up. It is running on a separate thread.
private AutoResetEvent ResetEvent { get; set; }
LogMessage(string fullMessage)
{
this.logQueue.Enqueue(fullMessage);
// Trigger the Reset Event to send the
this.ResetEvent.Set();
}
private void ProcessQueueMessages()
{
while (this.Running)
{
// This will process all the items in the queue.
while (this.logQueue.Count > 0)
{
// This method will just log the top item on the queue
this.LogQueueItem();
}
// Once the queue is empty will wait for a
// another message to queueed before running again.
// Rather than sleeping and checking if the queue is full,
// saves from doing a System.Threading.Thread.Sleep(1000); stuff
this.ResetEvent.WaitOne();
}
}
I handle write failures but not dequeueing until it wrote to the file with no errors. Then I just keep attempting until it finally can write. This has saved me because somebody removed permissions from one of our apps during it process. Permission was given back with out shutting down our app, and we didn't lose a single log statement.
Consider using a flat text file. I have a process that I wrote that uses an XML log... it was a poor choice. You can't just write out the state as you run without having to constantly rewrite the file to make sure the tags are correct. If it was flat entries written to a file you could have an automatic timeline that could give you details of what happened without trying to figure out if it was the XML writer/tag set that blew up and you don't have to worry about your logs bloating out as much.
I agree with others suggesting you avoid XML. Also, I would suggest you have one component (a "monitor") that is responsible for all access to the file. That component will have the job of handling multiple simultaneous requests and making the disk writes happen one after another.
I have a log file that continually logs short lines. I need to develop a service that reacts (or polls, or listens to) to new lines added to that file, a sort of unix' tail program, so that my service is always up to date reguarding the file.
I don't think that opening a read stream and keeping it opened is a good idea. Maybe I should use the FileSystemWatcher class.
Long story short, I need to parse in real time every new line added to this file.
Any idea help or indication is really appreciated.
EDIT
As I've been not very clear. I do not need any program, I am writing a program. For reading (then processing) every new line added to the file. I mean that what I'm looking for is a methodology (or: how to implement this?) for continually tailing a file that keeps on been written.
I have to develop a Windows service that "listens" to this file and does operations on every new line.
So, if in a given moment the file is:
12.31.07 - jdoe [log on] 347
12.32.08 - ssmith [log on] 479
12.32.08 - mpeterson [log off] 532
12.32.09 - apacino [log on] 123
in the very moment that the line
12.32.11 - pchorr [log on] 127
is added to the log file by the logging program (that I have not access to), I need my Windows service to "react" to the line addiction, intercept the new line (12.32.11 - pchorr [log on] 127) and process it. And so on.
Now, I don't know how to do this. I should poll the file every n seconds, store the last read line in memory and process only the newly added lines. The problem with this is that is very slow, plus I'd be reading a very large file every time.
Or maybe I could use FileSystemWatcher, but I haven't found any example of using it for similar purposes.
So, what would you suggest to get the work done? Thanks.
I would recommend using FileSystemWatcher to be notified of changes to the file or files you're concerned about. From there, I would cache information such as the size of the file between events and add some logic to only respond to full lines, etc. You can use the Seek() method of the FileStream class to jump to a particular point in the file and read only from there. Given these features, it shouldn't be too hard to hand-roll this functionality if that's what you need.
Simple solution would be use , sample code provided in http://www.codeproject.com/Articles/7568/Tail-NET article. It is just one function copy/paste into your code.
It is important to note that Microsoft (since vista/svr08) no longer updates file metadata when a file is updated (such as a log file being updated by a service).
For example, the metadata for a file such as modified date, will not be updated until the file is closed by the service/program which is updating the log file.
Therefore FileSystemWatcher will NOT catch log file updates as you might expect.
https://blogs.technet.microsoft.com/asiasupp/2010/12/14/file-date-modified-property-are-not-updating-while-modifying-a-file-without-closing-it/
You haven't really explained whether you need a tail-like program for Windows i.e. http://www.baremetalsoft.com/baretail/ or if you want a windows version of tail (use cygwin) or if you're looking for some sort of log monitoring API....