Fabian's Mix

Mixins, .NET, and more

Archive for the ‘Windows development’ Category

Getting Visual Studio 2010 SP1 to run elevated when launching .sln files

with 16 comments

For different reasons, I want Visual Studio 2010 to always run as an administrator on my Windows Server 2008 R2 machine (that has UAC enabled). Therefore, I have the “Run as administrator” checkbox checked on the Compatibility tab of Windows Explorer’s Properties dialog for devenv.exe:

Compatibility properties devenv

This causes Windows to always show me the UAC prompt when I run Visual Studio 2010:

UAC prompt devenv

Unfortunately, it also causes double clicking solution files in Explorer to stop working.

The reason is that Visual Studio associates .sln files with a special program, called VSLauncher.exe, which inspects the solution file in order to decide what version of Visual Studio to open it with. This enables side-by-side installation of different versions of Visual Studio to run correctly. When VSLauncher.exe is executed by Windows Explorer because I double-clicked a solution file, it is run with normal privileges, and is therefore not permitted to run devenv.exe, which requires elevation. VSLauncher thus silently fails.

The obvious solution is to also check “Run as administrator” for VSLauncher.exe, which, in my case, is located in “C:\Program Files (x86)\Common Files\microsoft shared\MSEnv”.

And, of course, the obvious solution doesn’t work. Any more.

With my installation, it used to work just fine, but with installing SP1 for Visual Studio 2010, or maybe even earlier, Windows somehow started to ignore my “Run as administrator” checkbox, and VSLauncher.exe would silently fail again.

After some research, I found that the reason for Windows ignoring my compatibility setting was that VSLauncher.exe now had a manifest embedded, which contained the following fragment:

<requestedPrivileges>

   <requestedExecutionLevel level="asInvoker" uiAccess="false">

   </requestedExecutionLevel>

</requestedPrivileges>

So, VSLauncher.exe now specified that it always wanted to be run at the same execution level as its invoker. And, since of course the program must know better than the user, this caused Windows to ignore my own execution level setting.

And now, to the solution. Since Windows wouldn’t let me override what the program said it wanted, I needed to override what the program said it wanted.

To do that, I used the Manifest Tool that comes with the Windows SDK (and thus with Visual Studio):

mt -inputresource:"VSLauncher.exe" -out:VSLauncher.exe.manifest

This command extracted the manifest from VSLauncher.exe into a file called VSLauncher.exe.manifest. I then edited the manifest to request the desired execution level:

<requestedPrivileges>

   <requestedExecutionLevel level="requireAdministrator" uiAccess="false">

   </requestedExecutionLevel>

</requestedPrivileges>

Then, I could write back the manifest:

mt -outputresource:VSLauncher.exe -manifest VSLauncher.exe.manifest

With the desired result:

UAC prompt VSLauncher

One note of caution: Please make a backup copy of VSLauncher.exe before manipulating the manifest. And perform at your own risk.

This trick should also work with Windows 7, by the way.

Written by Fabian

May 3rd, 2011 at 9:53 am

Analysis of an Excel Bug (or: How much is 850 * 77.1, actually?)

without comments

Some days ago, I read about an interesting Excel bug on Jeff Atwood’s “Coding Horror” blog: Did you know that Excel 2007 initially could not tell you the correct result of the formula “=850*77.1″? The result is 65535, but Excel displays 100000 instead. Similarly, it gives wrong results for other values near to 65535; for example, the formula “=65535-2^(-37)” would result in 100001 being displayed.

Now, this is an old hat, the bug seems to have been discovered in September 2007, and it was fixed little later. But Jeff’s post gave a link to a very interesting paper with an analysis of the bug: http://www.lomont.org/Math/Papers/2007/Excel2007/Excel2007Bug.pdf. What’s interesting is that it’s not that Excel calculated the formula in a broken way, it just couldn’t display the result correctly.

Excel internally uses a IEEE 754 floating-point format to represent and calculate values (which is efficient on Intel-based PCs – most of the time), and to display those values, it needs to convert from IEEE 754 to strings. Because this is a very often-used operation in Excel, it does so by means of a hand-written assembly routine:

The code seems to be written directly in assembly, since it has no C/C++ style stack frame or register usage. Also, the usage of some rare assembly instructions also points to it being hand coded assembly. This was likely done for performance – converting floating-point values to text needs to be high performance for Excel.

This routine was updated from using 16 bit registers to using 32 bit registers in Excel 2007. And in the process of doing so, the bug was introduced:

In brief: a digit loop takes a value N, a pointer to a table of divisors {10000,1000,100,10,1}, and uses the table to output decimal digits. A pointer is initialized to point to the largest table value needed based on the number of digits being output. When N=65535 and the pointer to the table is correct, this outputs 6,5,5,3,5. The bug causes the table pointer to point one past the 10000 entry to a 65535 entry.

Thus, when N=65536 (with the needed small error to cause the table mismatch), the first digit output is 65536/65535 = 1, with a remainder of 1. Then the divisor loop walks the table for 10000, 1000, 100, 10, and finally 1, outputting ‘0’ for each division, and a 1 in the units place. Thus the output is the erroneous 100001, instead of 65536.

The whole analysis involved disassembly and debugging of excel (as well as some intuition), so if you like that kind of problem solving, read the paper.

Previous versions of Excel gave the correct results, so this bug was the cause of much fun being made of Microsoft and the Excel team:

And let’s face it — do you really want the bright sparks who work there now, and manage to break lots of perfectly good working code — rewriting the core calculating engine in Excel? Better keep them busy adding and removing dancing paper clips all day long.

This is from Joel Spolsky, who no doubt would have been perfectly able to write a performing IEEE 754 formatting routine in assembly language without any bugs.

But maybe his point (after filtering out the slander) is something else: If you have an algorithm as complex as that, and it works alright, you’d better think twice – no, thrice! – before rewriting it. That’s a valid point to make, and probably a good lesson to learn. Can we learn anything else from this story?

For me, another point is the following: When you have a complex algorithmic problem, use a library if possible. Only write it yourself if you have very good reasons to do so, and be prepared that your implementation may not be correct. Using a library has the advantage of lots of other people using and testing the code, so chances are that bugs will be found and fixed before you ship your product.

And of course, there is always the lesson about publicity: If you work on a product as popular as Excel, prepare for being made fun of. A lot. (Especially if you work for Microsoft.)

Written by Fabian

May 20th, 2009 at 8:01 am

How come Word is back after Setup.exe restarts my PC?

without comments

Some time ago, when I started using Windows Vista and didn’t have the Windows Update Settings tuned to never restart without my consent, it happened that I was working in Word (and maybe ignoring some Windows Update process in the background), when suddenly my PC shut down. “What the heck?” was my first reaction to this (as I usually try to avoid using evil curse(d) words), and “I didn’t save” was the second one. (The third one was, “That damned program didn’t even ask me whether I wanted to save!”) But strangely, some angel heard my muttering and, after I had logged in again, automatically brought back Word with all my unsaved data.

If you’re using Vista or Server 2008, you might also have noticed that some programs, for example Microsoft Word 2007, Internet Explorer 7, and Visual Studio 2008, silently shut down when an installer needs to restart the system, and get restarted with their sessions restored when the system is up again. That’s a very nice user interface feature, I think, so I decided to research how to do it. And it turned out it wasn’t hard at all, as Daniel Moth explains: Vista (and thus Server 2008) contains a new Restart Manager, which enables this feature and is used automatically by Windows Installer 4.

To enable your application to restore its sessions, you simply listen for WM_QUERYENDSESSION with an lParam of ENDSESSION_CLOSEAPP (save your state there) and register your application for restart using RegisterApplicationRestart (which is part of the automatic recovery functions, see the MSDN for the P/invoke signatures). If you have a console application, you can also use a CTRL_C_EVENT handler (or the Console.CancelKeyPress event) to save your state, but in this case, you have to call RegisterApplicationRestart before you get that notification. See the MDSN for more comprehensive guidelines.

And that’s it, your application is ready for a clean Windows Update experience.

Written by Fabian

January 5th, 2009 at 8:58 am