I am making a small change to an existing application so that users can email us the log file when things go wrong. Even though it is c# the app is using Microsoft.VisualBasic.Logging.FileLogTraceListener.
This gets setup like this:
FileLogTraceListener fileLogTraceListener = listener as FileLogTraceListener;
fileLogTraceListener.Location = LogFileLocation.TempDirectory;
My question is: Where do the log files go?
Is it the same place as Path.GetTempPath() ?
I have seen a bunch of other posts asking similar questions but I need to be sure that whatever computer / operating system this app runs on it is able to pick up the logs. I take it there is no way to look inside the FileLogTraceListener class to see what it does when working with temp?
Failing documentation, you could:
Use Reflector to look at the source
Use Process Monitor from SysInternals to see what IO your process is doing.
Write a test app that makes two files, one with Path.GetTempPath() and one with VB Logger.
It is the same place as Path.getTempPath(). Reflector showed me this:
private string get_LogFileName()
{
string tempPath;
switch (this.Location)
{
case LogFileLocation.TempDirectory:
tempPath = Path.GetTempPath();
break;
+1 to Nate Bross - reflector helped to find the answer
Related
I know there are many topics similar to this, but I've been unable to find a solution after looking through dozens of results.
I have a Project "Foo", and my controller is at "Foo\Controllers\Bar.cs, and in that C# file, I want to read from a file, located at "Foo\Data\Stuff.txt". It's so simple, but nothing I've tried works, mainly because things like Directory.GetCurrentDirectory() and all similar built-in functions reference the executing directory (in my case, "C:\Program Files (x86)\IIS Express").
What am I doing wrong? Or if I missed an identical question, please direct me there, this seems to small an issue to have spent so much time on. Thanks!
With command Server.MapPath("Foo\Data\Stuff.txt") you will find the phisical path where the file is stored
It sounds like you might be looking for System.Reflection.Assembly.GetExecutingAssembly().CodeBase, which allows you to find exactly where your running .exe is located; regardless of whether you're in the debugger or not.
Here's an example that uses "CodeBase" to find the path, then reads the Windows version info from the .exe:
// GetWindowsVersion: Fetch Winver info from specified file
public static string GetWindowsFileVersion()
{
String codeBaseUri =
System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
String codeBase =
new Uri(codeBaseUri).LocalPath;
System.Diagnostics.FileVersionInfo info = FileVersionInfo.GetVersionInfo(codeBase);
return info.FileVersion.ToString();
}
So I recently updated my application to support a new feature. In the past if the configuration file was deleted by the user it wasn't a big deal. This new feature requires it to exist, and one of the requirements is that, the file exists in the application's installation directory.
I have notice when the file is deleted ( depending on variables I have not figured out ) I get a .NET notification that the configuration file is missing or corrupt. Currently my program then crashes ( I still have to figure out how to duplicate this behavior ) which is the reason for this question.
I am familar with ConfigurationManager. I am having trouble writting the file once the default values are loaded. Forcing a Save for some reason does not seem to recreate the file, at least not in the installation directory, which is a requirement.
I am looking for guidence on how to handle this corner case in an elegant manner. I would post code, honestly its just all failed attempts, which while my attempts do generate a file the contents are not the settings I am looking for.
I am willing to post anything that might be able to help.
Stop using the built-in config support and just use write/read to a file called something.exe.config using the standard XML classes and if that gets deleted, just re-create it from values hard-coded in the executable.
The config file support is supposed to make things easier, if you need to do stuff where it makes things difficult, don't use it.
Something like
var wcfm = new WebConfigurationFileMap();
Configuration newConfig = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
newConfig.Save();
doesn't work?
You dont. Under normal conditions the program can not write into it's install directory - this is a standard windows security issue and the reason why app application data should reside ni external (from the exe's point) driectories.
If an admin deletes the config file, crash, ask for reinstall. There is nothing you can RELIABLY do, as you can not assume you can write into the folder at runtime. A message followed by an event log entry is the best approach here. Users are not supposed to delete parts of the application.
I have some code that I wrote to basically clear out the directory every time the program runs through this point. I didn't want to bother enumerating files. If this is a bad way to do this, please tell me.
My main question, however, is about how to deal with the following: one of the files in the folder appears to be in use when it is most certainly not. The program runs on a ButtonClick event, and it exploded the first four or five times, but it worked after I confirmed that nobody was using the file on the server. There is only one person besides myself that would have been using it, and he confirmed that there was nothing running on his side that would be touching the file. Any ideas for what would cause this error/how to avoid it/how to handle it?
I am also having trouble reproducing the error...
string directory = #"\\server\directory\folder\";
DirectoryInfo di = new DirectoryInfo(directory);
if (di.Exists)
di.Delete(true);
Directory.CreateDirectory(directory);
If you are using Windows XP, this may help : http://msdn.microsoft.com/en-us/library/dd997370.aspx#remove_open_handles
Just an extract from the top of this page :
"If you are running Windows XP or earlier, a delete operation on a file or directory that follows an enumeration could fail if there is an open handle that remains on one of the enumerated directories or files."
You may also use a software like Unlocker to identify the process locking your file.
If the file is in use, then someone is most certainly using it. :)
If you can access the server the files reside on, you can use a tool such as Process Explorer to find out which process has opened the file.
From searching I can see this has been asked time and time again, but not adequately enough, so here goes. I'm a hobbyist developer with no budget. A program I've been developing has been in need of regular bugfixes, and me and users are getting tired of having to manually update.
Me, because my current solution of updating a text file through FTP and my download links on the website, and then hoping users will see the "there's an update message", and finally getting them to then be bothered to manually download the update, well quite frankly, is abysmal.
Users, because, well, "Are you ever going to implement auto-update?" "Will there ever be an auto-update feature?" And if I happen to screw up the update process, pitchforks start arriving.
Over the past I have looked into:
WinSparkle - No in-app updates, and the DLL is 500 KB. My current solution is a few KBs in the executable and has no in-app updates.
.NET Application Update Component - Unfortunately I can't comprehend the documentation.
Eduardo Olivera's AutoUpdate - This doesn't appear to support anything other than working with files that aren't in use.
wyUpdate - wyBuild isn't free, and while the wyUpdate specification is available, it's simply too complex and time-consuming to go through.
AppLife Update - Ditto the last sentence.
ClickOnce - Workarounds for implementing launching on startup are massive, horrendous and not worth it for such a simple feature. Publishing is a pain; manual FTP and replace of all files is required for servers without FrontPage Extensions.
It's quite disappointing that the situation on Windows is like this when you've got really nice and simple implementations for Mac OS X like Sparkle.
Implement it yourself! It will be fun. Create a separate application that only contains update logic i.e., fetch the files online, download them, replace local files, and show that visually to the user.
So your main application could check for updates, and if they exist it would prompt the user with the possibility to update. If the user wants to, it will run the update program, close itself (so the update can happen) and presto.
The only things you need are readily avaliable in C#, FTP access and IO.
Edit: I know it's not something terribly easy, but it's a perfect chance to learn:
How to (properly) download files, in an abstracted way that can be extended to ftp, http, etc.
How to (properly) do a simple task over many files - copying or overwriting them (this implies error handling).
Practice (because there's no "proper" way) to layer and encapsulate a piece of software.
How to deal with the OS/other software (antivirus/firewall/etc) not cooperating.
These are all things we all need to know well - If it takes some weeks to code an updater it means you were needing some weeks of learning. If you don't need to learn, time to hone your skills! If you don't know if you need, time to find out! :)
Note: I know I do need to learn better file and network I/O
Should've updated this ages ago, oops!
But anyway, I've been using SparkleDotNET for a while now and it's been working absolutely wonderfully. There's a few little bugs here and there but I've already helped get some of them squashed, and hopefully I'll be able to get rid of the others too :)
For those who have the time to run the publish functionality of Visual Studio, and whose app is relatively self-contained, and doesn't require anything like launching on startup, I'd recommend ClickOnce for sure. MetroTwit uses it and it's got a nice in-app updater interface, so it seems flexible (at least to a certain degree). For launching on startup, it's possible to do so, but methods to do so are quite hacky and don't work that well.
You can try Autoupdater.NET from GitHub I developed it my self and it works very well in my applications. You just have to add one line in your code and it's done. Also, it is open source so you can modify and use as you want.
You even can not to develop an external application but implement it as your application's module, e.g. into namespace Update, and use dynamic assembly builder to generate an exe, start it and exit app main, start it again when update will be finished.
Some more info.
There is also DDay update which is open source and is used by one of my customers. We/they are primarily interested in it in the context of a windows service at it works reasonably well for that.
For a more powerful solution, you may want to look at Google Omaha. It's what Chrome uses. You can get both in-app and automatic updates in the background when your application isn't running.
Try with MD5-Update it is absolutely free and easy no configuration need in your app only add library and publish the files.
https://github.com/jrz-soft-mx/MD5-Update/
1. Your need a web server with PHP for publish your files please include updt.exe.
2. Add index.php for make list of update files. aviable on github repository https://github.com/jrz-soft-mx/MD5-Update/blob/main/Tools/Tools.zip o create new app with this code.
<?php
$_dat = array();
$_dir=new RecursiveDirectoryIterator(".");
foreach (new RecursiveIteratorIterator($_dir) as $_itm) {
$_fil = str_replace(".".DIRECTORY_SEPARATOR, "", $_itm);
if(!is_dir($_fil) && $_fil != "index.php"){
$_dat[]=array('StrFil' => "$_fil", 'StrMd5' => strtoupper(md5_file($_fil)), 'lonSiz' => filesize($_fil));
}
}
echo json_encode($_dat, JSON_UNESCAPED_UNICODE);
?>
3. Add nuget repository at your proyect
PM> Install-Package MD5.Update
4. Call the library when your app stars, with your update folder url, update all files and download your new app on updt folder, for replace your app need updt.exe
string strUrl = "http://yourdomain.com/app/";
if (MD5Update.MD5Update.Check(strUrl, true))
{
Process.Start(AppDomain.CurrentDomain.BaseDirectory + #"updt.exe", AppDomain.CurrentDomain.FriendlyName + " " + Process.GetCurrentProcess().ProcessName);
Application.Exit();
}
5. updt.exe for replace the current app with the new app updt folder to app. aviable on github repository https://github.com/jrz-soft-mx/MD5-Update/blob/main/Tools/Tools.zip o create new app with this code.
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
List<string> lisArg = Environment.GetCommandLineArgs().ToList();
if (lisArg.Count < 2)
{
MessageBox.Show("Please provide App Excutable Name and Procees name");
Application.Exit();
return;
}
string strAppName = lisArg[1];
string strAppProcees = lisArg[2];
Process[] lisPro = Process.GetProcessesByName(strAppProcees);
foreach (Process Pro in lisPro)
{
if (Pro.Id != Process.GetCurrentProcess().Id)
{
Pro.Kill();
Thread.Sleep(1000);
}
}
string strAppMain = AppDomain.CurrentDomain.BaseDirectory + strAppName;
string strAppUpdate = AppDomain.CurrentDomain.BaseDirectory + #"updt\" + strAppName;
if (!File.Exists(strAppMain))
{
MessageBox.Show("App Excutable dosent exists");
Application.Exit();
return;
}
if (!File.Exists(strAppUpdate))
{
MessageBox.Show("App Excutable Updated dosent exists");
Application.Exit();
return;
}
File.Copy(strAppUpdate, strAppMain, true);
long fileSize = 0;
FileInfo currentFile = new FileInfo(strAppMain);
while (fileSize < currentFile.Length)
{
fileSize = currentFile.Length;
Thread.Sleep(1000);
currentFile.Refresh();
}
Process.Start(strAppMain);
}
catch (Exception Ex)
{
MessageBox.Show("An error ocurred");
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + #"updt_" + DateTime.Now.ToString("yyyyMMddTHHmmss") + " .txt", Ex.ToString());
Application.Exit();
}
all guys are right specially look at the abatishchev reply.but i think some thing other need that guy forgot it. try to develop your project "modular".put them your code in class library as you can.so during the fix operation replace one of them.think a bout database fix.some time you need to add a column to your database table.what do you do for these cases?
a have developed an update project.in that , i have three kind of fixes.
1- BUG in program operation and need to replace a DDL file
2- Bug in program and need to update currently program executive file
3- bug or change the database and need to execute a sql server query
in a table on web host i put the version history and every time that my app start check for new version.if any update exist check for its type and download it and do the suitable action depend on the update kind and parameters
good luck dude
If i make the call File myFile = new File('myfile.txt'); where is does this get saved to?
It's relative to the process's current directory. What that is will depend on how your application has been started, and what else you've done - for example, some things like the choose file dialog can change the current working directory.
EDIT: If you're after a temporary file, Path.GetTempFileName() is probably what you're after. You can get the temp folder with Path.GetTempPath().
That won't compile.
EDIT: However, if you're after where creating a text file using StreamWriter or File.Create("text.txt"), etc, then I defer to the other answers above; where it will be where the application is running from. Be aware as others mentioned that if you're working out of debug it will be in the debug folder, etc.
NORMALLY it gets saved to the same directory the executable is running in. I've seen exceptions. (I can't remember the specifics, but it threw me for a loop. I seem to recall it being when it's run as a scheduled task, or if it's run from a shortcut.
The only reliable way to know where it is going to save if you are using the code snippet you provided is to check the value of System.Environment.CurrentDirectory. Better yet, explicitly state the path where you want it to save.
Edit - added
I know this is a bit late in modifying this question, but I found a better answer to the problem of ensuring that you always save the file to the correct location, relative to the executable. The accepted answer there is worth up-votes, and is probably relevant to your question.
See here: Should I use AppDomain.CurrentDomain.BaseDirectory or System.Environment.CurrentDirectory?