views:

50

answers:

1

I have an odd bug where my code returns a file not found exception but the file seems to be exactly where it should be. My project has some code to run a system cmdlet and look for the results of the cmdlet in an XML output file. We tell the cmdlet to put this output XML in a custom subdir of the system TEMP dir, e.g., C:\WINDOWS\TEMP\SomeFolder\output.xml. We then use the .NET XmlDocument class to open and parse the XML file.

On WinXP, this works. On my dev box, this works. On a clean Win7 test machine, it does not.

My first thought was that I'm running into Vista/Win7 File Virtualization, but our application manifest specifies that our app run as Admin -- and from what I've read, that should bypass file virtualization.

The other wrinkle is that our code likes to use UNC file paths, even if the file is local to the machine. (We have a requirement that the code in question may need to run the cmdlet on a remote machine, and therefore the output XML could be on a remote machine too.) So we try to open the XML file via \MATT-WIN7\C$\WINDOWS\TEMP\SomeFolder.xml rather than C:\WINDOWS\TEMP\SomeFolder\output.xml.

But I removed the UNC path code temporarily and a simple call to File.Exists() still says the XML file is not there, when Windows Explorer shows the file sitting exactly where I think it should be.

Is there some nuance of file virtualization that I have not read about yet?

My workaround is to move the output xml file somewhere else, but that will potentially break the "portability" of our code when it needs to run on a remote machine, because using the %TEMP% location is a location that can be resolved for remote computers pretty easily (via remote registry call to find the system environment variable).

I would prefer to leave the file where it is, and fix our code so it actually finds the file!

+4  A: 

There is a user-specific override for the %TEMP% environment variable that points to %USERPROFILE%\AppData\Local\Temp, not to %SYSTEMROOT%\Temp. Make sure your code is looking in the temp folder you expect it to look at.

Update: Based on your comments, it seems that the problem is that your app is not actually being elevated on the test machine, but is elevated on your dev machine. I suspect the following:

  • you either have UAC disabled on your dev machine or you are running VS as administrator. Big no-no on both. :-)
  • your binary is not code-signed and is not in one of the two trusted locations - %SystemRoot%\system32 or %ProgramFiles%. For security reasons UAC does not even prompt the user for elevation for apps that have elevation manifest, but are not code-signed or in a trusted location.

You can create a self-signed certificate to code-sign your binary and add that certificate to the test machines, to get the UAC prompt. Once you've confirmed that your app is properly being elevated, your code to access the system %TEMP% folder should work correctly.

Franci Penov
I don't think this is the problem. Just as a sanity test, I dropped a copy of the output file from a previous run into that %USERPROFILE%\AppData\Local\Temp folder, and the code still didn't find it. I've got logging spitting out the paths that we're trying to use, and it seems like we just can't see the file sitting in C:\WINDOWS\TEMP for whatever reason.
Matt
Also, running our app under XP SP3 compatibility mode fixes the issue -- so I definitely think it's a virtualization issue that I just don't fully understand yet.
Matt
If you're looking at C:\Windows\Temp and you're not seeing the file, that means your app is not running properly elevated.
Franci Penov
Hum... the manifest is specifying this:<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />Where should I be looking to better understand the issue?
Matt
Are you actually seeing the UAC prompt when launching your app?
Franci Penov
You can read more about UAC at http://msdn.microsoft.com/en-us/library/aa905330.aspx and http://msdn.microsoft.com/en-us/library/bb756929.aspx. In any case, if you are elevating your app propely, you should see the UAC prompt (unless you've disabled UAC at all)
Franci Penov
No, I'm not getting the UAC prompt on the test Win7 machine. I had *assumed* that UAC was disabled, but it's active. The manifest is being embedded in the .exe using VS2008 project settings, and I verified that the manifest appears in the output .exe using the resource viewer, but clearly something isn't right...
Matt
It turns out this was a timing problem, not an elevation problem. I had a bug where this code was running just instants before the file was being save to the expected location. Sorry. :(
Matt