Question

I'm trying to write a console application to delete files from Windows\System32 using the .net File.Delete. The application runs on Windows 7, and it fails since it allegedly cannot find the files.

I researched and found that it is a security restriction of the framework, but I also found in answers to similar questions here that if I add a manifest file to my solution, and edit it such that it includes

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

then whenever I start the application I'll be prompted for my user name and passowrd to "prove" that I'm the administrator, and then the application WILL find the files in System32 and delete them as expected.

This doesn't happen. I'm not prompted for the u\p and the program fails. I tried debug\release\32-bit\64-bit.

Any advice?

Full manifest:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity version="1.0.0.0" name="EclCleaner.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>
Was it helpful?

Solution

As you said in your own answer, Windows will automatically and transparently redirect requests to the folder Windows\System32 to be Windows\WoW64 folder. This is to keep programs that use hard coded strings from loading the 64 bit dlls that are in the system32 folder which would cause the program to crash.

If you want to navigate to the 64 bit system folder from a 32 bit application you need to use the hidden folder Windows\sysnative, this points to the 64 bit system32 folder. Important note, the folder is only visable from 32 bit programs, if you try to connect to it from a 64 bit program (for example Windows Explorer) the folder will not exist.

class Program
{
    static void Main(string[] args)
    {
        //True in 32 bit, false in 64 bit.
        var tmp = Directory.Exists(@"C:\Windows\sysnative");
        Debugger.Break();
    }
}

OTHER TIPS

Embarrassing. When running on a 64-bit OS and compiling your code in X86, the .net framework redirects every request related to Windows\System32 to the WoW64 folder. Although in debug the value of the path was system32, it was actually looking at a different folder.

Using requestedExecutionLevel isn't enough if UAC has been disabled. In that case you need to detect if the user actually has admin privileges. You can do that with:

if (!IsInRole(WindowsBuiltInRole.Administrator))

If the user does not have admin privileges, you need to self-elevate. An example of how to self-elevate can be found here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top