Just because a method is called Refresh doesn’t mean that it refreshes what you want

Here's a question from a customer:

I made some changes related to my shell extension [details omitted], but the changes don't show up in the Explorer window when I refresh it. Any suggestions on how to solve this problem?

When we asked how they were refreshing the Explorer window, we were expecting something like pressing F5 or calling SHChangeNotify with SHCNE_UPDATEDIR, or maybe calling IShellView::Refresh or possibly even calling WebBrowser.Refresh from script. But we definitely didn't expect this response:

I'm invoking the Process.Refresh() method from the System.Diagnostics namespace.

Just because a method is called Refresh doesn't mean that it refreshes what you want. I think this is somebody who just saw a method name, perhaps inspired by IntelliSense and— Boom! You have it!—assumed it did what was needed without actually reading the documentation to check. But you don't even need to read the documentation to know that Process.Refresh has no chance of working.

Since it's a method on the Process class, the method is applicable to all processes. But certainly there is no generic way to tell a process to refresh. This magical Refresh method would have to know how to refresh Explorer windows, Firefox web pages, iTunes mp3 tags... And what would it even mean to refresh, say, a Notepad window? Does that mean to throw away all changes and reload the original document?

How do you know that there is no generic way to tell a process to refresh? Well, for one thing, a single process like Explorer can be viewing multiple objects that can be refreshed; which one are you refreshing? Second, when you write your own program, how do you implement refresh? Do you respond to some standard system Refresh message? Or do you just add a Refresh option to your program's main menu and give it some arbitrary command ID? If there's not even a standard way to refresh your program's window, then how can there be a standard way to refresh all program windows?

In this specific case, the Process.Refresh method refreshes the Process object's internal cache of process properties. It doesn't actually do anything to the process itself. How could it?

It's like thinking that the Matrix.Rotate method rotates the entries in a matrix.


Actually, I'm scared by this customer's question for another reason: The fact that they even mentioned Process.Refresh suggests to me that they wrote their shell extension in managed code, which we already know is strongly disrecommended.

Comments (21)
  1. int19h says:

    On the other hand, there are such gems as Control.Refresh() vs Contorl.Update(). Not to say they both don’t serve useful purposes, but somewhat more descriptive (and distinctive!) names would be less confusing.

  2. SRS says:

    Has your customer raised a bug report against Process.Refresh() yet?

  3. Matt says:

    Isn’t it true that as of .NET4 multiple versions of the CLR will be able to be loaded per process so writing things like shell extensions in managed code will be less of an issue?

  4. Dave says:

    Matt, to paraphrase the title of this post: Just because something is doable doesn’t mean that it should be done.

  5. Yuhong Bao says:

    "Matt, to paraphrase the title of this post: Just because something is doable doesn’t mean that it should be done."

    Besides, .NET 4 is not even released yet.

  6. John says:

    *facepalm*  Honestly, there should be a minimal level of competency one should have to meet before being allowed to work with anything more complicated than a screwdriver (alas, there are people who would be challenged even by that).  Unfortunately, half of the world is dumber than the average person.

  7. David says:

    I know this is drifting off-topic, but since the .NET 4 framework supposedly will be able to coexist with .NET 2 in the same process, doesn’t that mean that I can write a shell extension *today* in .NET 2? (Assuming, of course, that I completely ignore the existance of .NET 1, but that will still be an issue when .NET 4 comes.)

    So, seriously, should we really be careful not to write extensions to native hosts in managed code anymore?

    [This “.NET 4 framework” thing is news to me. But I like that parenthetical. “Assuming, of course, that I completely ignore the reason why shell extensions shouldn’t be written in managed code.” -Raymond]
  8. Jonathan says:

    Actually, I’m surprised that it’s even possible to write in-proc managed shell extensions.

  9. Yuhong Bao says:

    "Actually, I’m surprised that it’s even _possible_ to write in-proc managed shell extensions."

    You can inject the CLR into *any* process by using COM interop or IJW, and the native code will not even know that it has happened.

  10. alex.r. says:

    John: Well, actually it’s the median person. But hey, nice try, here’s a screwdriver.

    I like to think that there are kids out there, or even retired folk signers, who are teaching themselves programming. Sure they could read the documentation, but they have to know that it exists in the first place.

  11. Dan says:

    alex: I think most people know by now what the "Help" menu item on most program menubars is for, and the slightly more hard-core know what F1 does.

  12. Cheong says:

    Dan: Agreed. But also note that even the "experienced" computer users don’t have a habit of consulting "Help" before using them. (Actually, below the "line" that people recognize that they don’t know enough if they never read the documentation, the more experience they have with computer, the more likely they’ll completely ignore menu.)

  13. I'm being rude so I'm not using my normal name says:

    The median person IS the average person, because the median is an average.  The biggest problem is saying "the average" like there’s only one average.  But even saying "the mean" glosses over the difference between arithmetic, geometric, and other means.

    Regardless, if we assume a gaussian distribution of intelligence (and we often do), then the statement works even the mode and arithmetic mean (and geometric mean depending on how you define it).

    I’m being ABSURDLY pedantic here, but only because your own dismissive pedantry ("nice try, here’s a screwdriver") irked me so much.  People scanning for any potential flaw or nitpick in anything ever said instead of, you know, communicating.

  14. alex.r. says:

    I’m being rude so I’m not using my normal name:

    My point was: you can’t judge a person on a single event, everybody makes mistakes.

    It was a response to John’s comment about how dumb the person who wrote that code must be.

  15. eff Five says:

    Just for fun, I categorized the comments to this post in one of four areas (some comments are in more than one category) My post doesn’t count

    Primary topic "Process.Refresh": 3

    Compentancy of Customer/Users in general : 4

    Averages: 5

    Comments on secondary topic "managed shell extensions" 6

    So the average was managed shell extension.

    To be clear I mean the mode, I do not mean the mean. :P

    From http://www.merriam-webster.com/dictionary/average

    1 a: a single value (as a mean, mode, or median) that summarizes or represents the general significance of a set of unequal valuesb: MEAN 1b2 a: an estimation of or approximation to an arithmetic mean b: a level (as of intelligence) typical of a group, class, or series<above the average>

  16. GreenReaper says:

    Of course, with your post and mine, the average is now averages.

  17. If the distribution is approximately normal, then the median, mean, and mode are approximately equal.

    For most populations and measures of intelligence, the distribution is approximately normal.

  18. alex.r. says:

    Ok, ok, I think everyone even mildly interested in the subject got it. Yes, the median is an average but the average is not necessarily the median — except for some distributions.

    Now I know the feeling of people missing the point entirely and concentrating on peripheral details.

    … the irony.

    People commenting on blogs are definitely not normally distributed.

    To bring this conversation back to Refresh — I’m just going to clarify my initial reaction by saying that it was not totally unreasonable for the user to assume that there was a standardized mechanism for refreshing all the windows of a process.

    There is after all a similar mechanism for repainting.

    Sure, relying on unproven assumptions is not a good strategy when programming, but this is something that’s learned with experience.

    It’s not necessarily a sign of irrecoverable incompetence. After a short while users will be able to not only realize they’re making assumptions, but experiment or read the appropriate documentation to validate/invalidate them.

  19. ton says:

    "The median person IS the average person, because the median is an average."

    Actually, the median is the middle element in a sorted set. This *is* not the same as an average.


  20. Friday says:

    .Net is a cancer that will consume the planet in the end.

Comments are closed.