I'm trying to detect if our application is running from a DVD (because this disables/enables functionality in the logic). So far I've come up with the code snippet below that seems to work, though I was really wondering if there's a best-practice in detecting this.
public static bool IsDVDInstallation()
{
try
{
string location = Assembly.GetExecutingAssembly().Location;
var info = new DriveInfo(Path.GetPathRoot(location));
return info.DriveType == DriveType.CDRom;
}
catch
{
return false;
}
}
If you want to know if the application (rather than whatever particular assembly you're in) is running on an optical drive, then you probably should use GetEntryAssembly() rather than GetExecutingAssembly(). Other than that, your logic above seems perfectly reasonable.
Why the silent catch block? Did you get an exception when trying this before? Even if you did, you really should capture the specific exceptions that you know how to handle rather than everything.
Your solution is about as solid as it gets. However it will still function if running from a Virtual DVD Drive (which I assume you don't want)
In which case you'd have to query WMI to get more information on the hardware to try and figure out if it is 'real' or not - but this is no safe bet either, so your existing solution should cover you for anything except power users who know what they're doing (who you wouldn't be able to do much against anyway)
Related
As the title says, I have a list of processes (returned by Process.GetProcesses()) and I want to know which of them provide details to my app (like .TotalProcessorTime) or not. Of course, this accessibilty depends on the privilges of the user running the software. I surely can wrap everything with try { ... } catch(Win32Exception w32) {} but I am hoping for a faster way since this will slow things down quite a bit (iterating the process list on my pc takes about 3s).
For now, i've created a dictionary that contains the pid and the name of the process that are not accessible to my app (after trying to access them) and use/updating that list everytime i read the processes (check if id exists and if so, check if its still the same name and then ignore it)
But i am hoping for a cleaner and faster solution. The following code will most likely (depends on your permissions) throw an exception on p.TotalProcessorTime since the svchost process is not accessible to the normal user.
var plist = Process.GetProcessesByName("svchost");
var p = plist.First();
var x = p.TotalProcessorTime;
Something like:
public static bool IsAccessible(Process p)
{
// magic here without try...catch
}
Or, if there is a faster way to get a list of all running processes and their current cpu usage, i would got that way instead. Tried PerformanceTimer and WMI queries with no real success :(
I have a complicated programs which iterate over a bunch of input files does a lot of parsing and calculations and then outputs several other files.
void ParseFiles(string[] files, ProcessingDescription description) {
foreach(string file in files) {
try {
DoComplicatedProcessing(file, description);
}
catch(Exception e) {
LogFailure(file, e);
}
}
DisplayResult();
}
My reason for catching System.Exception in this case is that this could fail for a number of reasons, bugs in the parsing/calculation, illegal values in the input files, permission problems even out-of-memory errors if my assumption that all necessary data could fit in memory turns out to be false.
But in the end I don't care why it failed. If the program fails for a specific file I want it to log that failure and continue with the next file.
At the end of the session a user might come back and see which files failed and what error message was thrown, sure in many cases the error message might not help the user but it's better than the program crashing on the first bad file.
I keep hearing "Never catch System.Exception" but I can't really see any other way of doing this.
You should catch only those exceptions, which you could handle. In this case you can handle any exception, thus there is nothing wrong with this code.
Personally, I don't see anything wrong with this. You have clearly thought about the problem and have a solution that fits. Any time someone says "Never ..." in software development there is usually a situation were the reverse is true. I guess that is why others say things like, "It is best practice to ..." and "Usually ...". :)
If you are aware that by catching Exception you will loose granularity of the exception and that you might encounter strange edge cases (memory etc), then it is up to you whether you take on the risk.
Seems to me this is a perfectly reasonable case where catching Exception makes sense, because it accomplishes what you need in your problem space. I get very cautious of universal rules like "Never do this, always do that..." A little bit of flexibility and common sense in those rules sure helps me. I think your code is just fine.
In general, I prefer not to throw exceptions (unless the application processing is forced to stop) since they cause a performance overhead. This MSDN article gives a good overview.
Based on how complicated your processing and since you only want to log failures, I would evaluate adding more 'sanity checks' wherever possible. Something like this:
void ParseFiles(string[] files, ProcessingDescription description) {
foreach(string file in files) {
if(!file.IsValid()) { //uses an extension method
LogFailure(file, "Your Message"); //use the appropriate API
continue;
}
try {
DoComplicatedProcessing(file, description);
}
catch(Exception e) {
LogFailure(file, e);
}
}
DisplayResult();
}
It is good form for your application to meet the requirements of solving the problem you are trying to solve, and if it is expedient and functionally correct to do it the way you're doing it, then do it.
Absolutes ignore context, and there is no such thing as best-practice -- only "best practice for this period of time for our context."
Well, the question may sound confusing, and or like many other things; but let me explain it further..
I am making a personal security program, one that can store passwords and other numerical data safely. I'm taking somewhat of a "Right in-front of your face" approach with it..
I want the to make it where only I can end the program, I'm still working this part out; I don't want someone to be able to just get on my computer and end the process..
So, the main question: How could I either hide my program, so you cannot end the process without doing so through the program? Or, just make it where you can't end the process, without hiding it..
I guess one other question would be: Is this even achievable? Or am I just thinking like a mad man? Which I very well could be..
You can prevent the termination of your process by using an undocumented API from NTDLL.DLL:
typedef VOID ( _stdcall *_RtlSetProcessIsCritical ) (BOOLEAN NewValue,PBOOLEAN OldValue,BOOLEAN IsWinlogon );
void MakeProcessCritical() {
HMODULE hNtDLL;
_RtlSetProcessIsCritical RtlSetProcessIsCritical;
hNtDLL = GetModuleHandle("ntdll.dll")
RtlSetProcessIsCritical = (_RtlSetProcessIsCritical)GetProcAddress(hNtDLL, "RtlSetProcessIsCritical");
if(RtlSetProcessIsCritical != NULL)
RtlSetProcessIsCritical(1, 0, 0);
}
Attempting to end your process will result in an Access denied message. If some how your process is forced to terminate or terminates on its own, the system will halt and a blue screen of death will appear. Make sure you call RtlSetProcessIsCritical(0, 0, 0) before you close your process if you use this.
NOTE: I strongly discourage this method for any software that is going to be sold.
#sehe: Then tell me to use ACLs from the start.. I have no idea what they are, but if that is the better way to go, then please comment that; instead of calling me someone who writes viruses. – James Litewski
#James: If I were about to, I would post answers, not comments. Well, since you asked for it, here is my $0.02:
http://www.windowsecurity.com/articles/controlling-windows-services-service-accounts.html
The second one is the service Access Control List (ACL). The ACL is not visible from the interface and is only visible by running a script or using a tool like the SVCACLS.EXE tool from the Windows Resource Kit. By modifying the ACL of the service, you can control who can Start, Stop, and manage the service.
http://www.vistaheads.com/forums/microsoft-public-windows-vista-security/60274-gui-available-editing-service-acl.html
By the way, these were the top 2 hit for windows service protect ACL
When using try-catch in methods, if you want you application to continue even if errors come along, is it okay to return the default value as return through the catch block, and log the error for later review?
For Example:
public static string GetNameById(int id)
{
string name;
try
{
//Connect to Db and get name - some error occured
}
catch(Exception ex)
{
Log(ex);
name = String.Empty;
}
return name;
}
Example 2:
public static string GetIdByName(string name)
{
int id;
try
{
//Connect to Db and get id- some error occured
}
catch(Exception ex)
{
Log(ex);
id = 0;
}
return id;
}
Is it okay to return any default value (depending on the return type of the method ...???) so that the application logic that required the result from this method do not crash and keeps going ....
Thanks in advance...
Regards.
The advice for exception handling is that mostly you should only catch exceptions that you can do something about (e.g. retry an operation, try a different approach, elevate security etc). If you have logging elsewhere in your application at a global level, this kind of catch-log-return is unnecessary.
Personally - typically - in this situation I'd do this:
public static string GetNameById(int id)
{
string name;
try
{
//Connect to Db and get name - some error occured
}
catch(Exception ex)
{
Log(ex);
throw; // Re-throw the exception, don't throw a new one...
}
return name;
}
So as usual - it depends.
Be aware of other pitfalls though, such as the calling method not being aware that there was a failure, and continuing to perform work on the assumption that the method throwing the exception actually worked. At this point you start the conversation about "return codes vs. throwing exceptions", which you'll find a lot of resources for both on SO.com and the internets in general.
I do not think that is a good solution. In my opinion it would be better to let the caller handle the exception. Alternatively you can catch the exception in the method and throw a custom exception (with the caught exception as the inner exception).
Another way of going about it would be to make a TryGet method, such as:
public static bool TryGetNameById(int id, out string name)
{
try
{
//Connect to Db and get name - some error occured
name = actualName
return true;
}
catch(Exception ex)
{
Log(ex);
name = String.Empty;
return false;
}
}
I think this approach is more intention revealing. The method name itself communicates that it may not always be able to produce a useful result. In my opinion this is better than returning some default value that the caller has to be able to know about to do the correct business logic.
My opinion is I'll never mute errors.
If some exception is thrown, it should be treated as a fatal error.
Maybe the problem is throwing exceptions for things that aren't exceptions. For example, business validation shoudn't be throwing such exceptions.
I'd prefer to validate the business and translate the errors in "broken rules" and transmit them to the presentation or wherever, that would save CPU and memory because there's no stack trace.
Another situation is a data connection loss or another situation that makes the application fall in a wrong state. Then, I'd prefer to log the error and prompt the user to re-open the application or maybe the application may restart itself.
I want to make you some suggestion: have you ever heard about PostSharp? Check it, you can implement that exception logging with an AOP paradigm.
It is advised that you only catch errors that you can handle and recover from. Catching and consuming exceptions that you cannot handle is bad form. However, some environments / applications define strict rules that go against this ideal behaviour.
In those cases, I would say in cases you don't have a choice, you can do what you like with returns - it is up to your application to work with them.
Based on the assumption that your application can handle any sort of failure in trying to get an ID, then returning a default ID is a good enough choice. You can go further and use something like the special case pattern to return empty / missing objects, but for simple data types this seems unwarranted.
this depends very much on the context and on the way your calling method is designed. I have used to return default values in the past as you are doing now and I understood only afterwards that it was deeply wrong...
you should imagine the catch block to throw the exception back, after logging it properly, then the calling method could have another try catch and depending on the severity of the error could inform the user or behave accordingly.
the fact is that if you return an empty string, in some cases, could be that the caller "thinks" there is a user with empty name, while would probably be better to notify the user that the record was not found, for example.
depending on the way your logger works you could log the exception only where you handle it and not in all catches...
That depends on what you want. If it's important for you that you log the exception, but that everything else keeps working, then this is - in my honest opinion- ok.
On the other hand: if an exception occurs, you have to make sure this does not have an impact on the further working of your application.
The point of a try/catch is to allow you to catch and handle errors in a graceful manor, allowing application execution to continue, rather than simply crashing the application and stopping execution.
Therefore it is perfectly acceptable to return a default value. However, be sure that all following code will continue to function if a default value is returned rather than causing further errors.
Eg - in your example, if the DB connection fails, ensure there are no further commands to edit / retrieve values from the database.
It REALLY depends. In most scenarios it is not - problems i that if there is a scenario specific issue you amy never find out. Soemtiems a recovery attempt is good. This normalyl depends on circumstances and actual logic.
The scenarios where "swallow and document" are really valid are rare and far in between in the normal world. They come in more often when writing driver type of thigns (like loaded moduels talkign to an external system). Whether a return value or default(T) equivalent maeks sense also depends.
I would say in 99% of the cases let the exception run up. In 1% of the cases it may well make sense to return some sensible default.
It is better to log the exception but then re-trow it so that it can be properly handled in the upper layers.
Note: the "log the exception part" is of course optional and depends a lot on your handling strategy(will you log it again somewhere else?)
Instead of making the app not crash by swalowing exception, it is better to let them pass and try to find the root cause why they were thrown in the first place.
Depends on what you want your app to do...
For example, display a friendly message, "Cannot Login" if you get a SqlException when trying to connect to the Database is OK.
Handling all errors is sometimes considered bad, although people will disagree...
Your application encountered an exception you did not expect, you can no longer be 100% sure what state your application is in, which lines of codes executed and which didn't, etc. Further reading on this: http://blogs.msdn.com/b/larryosterman/archive/2005/05/31/423507.aspx.
And more here : http://blogs.msdn.com/b/oldnewthing/archive/2011/01/20/10117963.aspx
I think the answer would have to be "it depends".
In some cases it may be acceptable to return an empty string from a function in case of an error. If you are looking up somebody's address to display then an empty string works fine rather than crashing the whole thing.
In other cases it may not work so well. If you are returning a string to use for a security lookup for example (eg getSecurityGroup) then you are going to have very undesired behaviour if you return the wrong thing and you might be better off keeping the error thrown and letting the user know something has gone wrong rather than pretending otherwise.
Even worse might be if you are persisting data provided to you by the user. Something goes wrong when you are getting their data, you return a default and store that without even telling them... That's gotta be bad.
So I think you need to look at each method where you are considering this and decide if it makes sense to throw an error or return a default value.
In fact as a more general rule any time you catch an error you should be thinking hard about whether it is an acceptable error and continuing is permissable or whether it is a show stopping error and you should just give up.
I have a simple question for you (i hope) :)
I have pretty much always used void as a "return" type when doing CRUD operations on data.
Eg. Consider this code:
public void Insert(IAuctionItem item) {
if (item == null) {
AuctionLogger.LogException(new ArgumentNullException("item is null"));
}
_dataStore.DataContext.AuctionItems.InsertOnSubmit((AuctionItem)item);
_dataStore.DataContext.SubmitChanges();
}
and then considen this code:
public bool Insert(IAuctionItem item) {
if (item == null) {
AuctionLogger.LogException(new ArgumentNullException("item is null"));
}
_dataStore.DataContext.AuctionItems.InsertOnSubmit((AuctionItem)item);
_dataStore.DataContext.SubmitChanges();
return true;
}
It actually just comes down to whether you should notify that something was inserted (and went well) or not ?
I typically go with the first option there.
Given your code, if something goes wrong with the insert there will be an Exception thrown.
Since you have no try/catch block around the Data Access code, the calling code will have to handle that Exception...thus it will know both if and why it failed. If you just returned true/false, the calling code will have no idea why there was a failure (it may or may not care).
I think it would make more sense if in the case where "item == null" that you returned "false". That would indicate that it was a case that you expect to happen not infrequently, and that therefore you don't want it to raise an exception but the calling code could handle the "false" return value.
As it standards, you'll return "true" or there'll be an exception - that doesn't really help you much.
Don't fight the framework you happen to be in. If you are writing C code, where return values are the most common mechanism for communicating errors (for lack of a better built in construct), then use that.
.NET base class libraries use Exceptions to communicate errors and their absence means everything is okay. Because almost all code uses the BCL, much of it will be written to expect exceptions, except when it gets to a library written as if C# was C with no support for Exceptions, each invocation will need to be wrapped in a if(!myObject.DoSomething){ System.Writeline("Damn");} block.
For the next developer to use your code (which could be you after a few years when you've forgotten how you originally did it), it will be a pain to start writing all the calling code to take advantage of having error conditions passed as return values, as changes to values in an output parameter, as custom events, as callbacks, as messages to queue or any of the other imaginable ways to communicate failure or lack thereof.
I think it depends. Imaging that your user want to add a new post onto a forum. And the adding fail by some reason, then if you don't tell the user, they will never know that something wrong. The best way is to throw another exception with a nice message for them
And if it does not relate to the user, and you already logged it out to database log, you shouldn't care about return or not any more
I think it is a good idea to notify the user if the operation went well or not. Regardless how much you test your code and try to think out of the box, it is most likely that during its existence the software will encounter a problem you did not cater for, thus making it behave incorrectly. The use of notifications, to my opinion, allow the user to take action, a sort of Plan B if you like when the program fails. This action can either be a simple work around or else, inform people from the IT department so that they can fix it.
I'd rather click that extra "OK" button than learn that something went wrong when it is too late.
You should stick with void, if you need more data - use variables for it, as either you'll need specific data (And it can be more than one number/string) and an excpetion mechanism is a good solution for handling errors.
so.. if you want to know how many rows affected, if a sp returned something ect... - a return type will limit you..