21

I have to copy a psTool utility to System32 folder when my application runs.
I am on 64 bit Windows 7 and whenever, I try to copy the exe to system32 bit folder through File.Copy, the exe always gets copied to SysWow64 instead.

When I put a breakpoint on destFile, the path is shown as C:\Windows\System32 but the file does not go in there (goes to sysWow64). I have tried the Special Folder SystemX86, but the file again goes to sysWOW64.

string sourceFile = "C:\bin\Debug\somexe.exe"
string destFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), utilityName);
File.Copy(sourceFile, destFile, true);

Any suggestions what I am missing here?

EDIT

As pointed out below in the answer, there's file system redirection taking place. I am developing the app with the default settings of Visual Studio for a console application on a 64 bit OS. I am not sure what settings/switches have to be kept while compiling, so that the application works both on 32 bit and 64 bit OS.
Basically, it should just set copy the file to System32 only regardless of what bit OS it is.
Later in the program, I have to access the psTools utility through command line which is not available if I place it in SysWOW64. If I make change, to use SysWOW64's 32 bit cmd.exe, this would again be something 64 bit platform specific, which I do not want to opt.

Any solution which can have the app running both on 32-bit and 64 bit without an problems? Do I have to modify the code (how?) or do I have to modify some properties of this console application project (which properties)?

user1240679
  • 6,829
  • 17
  • 60
  • 89
  • 1
    Why are you copying it from system32 in the first place, which tool of the PsTools suite are you trying to run? – Scott Chamberlain Apr 11 '12 at 19:10
  • 1
    Copy it to `system32`, not copyitng it from. `pskill` is the name of the utility. – user1240679 Apr 12 '12 at 04:11
  • 1
    You got me on the to/from typo. However, you still have not answered the question **why** you are copying `pskill` in to the `system32` folder instead of just running it in place from somewhere else (and add it to the system `PATH` variable if necessary) – Scott Chamberlain Apr 12 '12 at 05:57
  • 1
    The best and simplest solution is to put pskill.exe somewhere that isn't subject to file system redirection, such as an application data folder. Applications aren't supposed to write into system folders anyway. – Harry Johnston Apr 12 '12 at 23:47

4 Answers4

33

You've run afoul of file system redirection.

Because %windir%\System32 is reserved exclusively for 64-bit applications, on 64-bit versions of Windows, 32-bit applications that attempt to access the %windir%\System32 directory are automatically and transparent redirected to the 32-bit %windir%\SysWOW64 directory.

First, make sure that your program actually does belong in the 64-bit system folder. Windows does this automatic redirection for a reason. 32-bit stuff does not go in the %windir%\System32 folder on 64-bit versions of Windows.

If you're certain that you want to be copying stuff into the 64-bit system directory, you have a couple of options. The easiest is probably to just compile your utility as a 64-bit application. Alternatively, you can tell the WOW64 redirector that you know what you're doing and not to perform the redirection by using %windir%\Sysnative instead of %windir%\System32.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • I am not sure how to do the above `Sysnative` thing in the above code. I tried through `run` dialog to open `%windir%\Sysnative`, but this doesn't open any directory. – user1240679 Apr 11 '12 at 09:22
  • 1
    @user: You have to access the directory from a **32-bit application**. It should go without saying that Windows Explorer is not a 32-bit application on 64-bit versions of Windows. Perhaps [these instructions](http://ovidiupl.wordpress.com/2008/07/11/useful-wow64-file-system-trick/) would be helpful? – Cody Gray - on strike Apr 11 '12 at 16:02
  • I understand that this redirection is performed when a 32-bit application tries to access System32 on 64 bit. However, I did not do anything while developing that should have made my application 32 bit. The platform target is also set to `Any CPU`. Doesn't the application behave as 32-bit on 32bit OS and 64 bit on 64bit OS, which should have solved the problem by accessing the `System32` folder only whatsoever. Very strange about naming of `System32` for 64 bit applications on 64 bit OS though. I still am not able to discern what specific I have to change in my application. :-/ – user1240679 Apr 11 '12 at 16:47
  • It's not even clear to me what you want to accomplish anymore. Update your question with some details that describe the problem. Stuff like "I'm compiling my app as `Any CPU`" would have been useful to include from the outset. It's hard to solve problems when you're left to guess about important details. And I'm not sure why the naming is so strange. `SysWOW64` contains the components needed to enable the WOW64 subsystem, which is what allows 32-bit components to run in 64-bit Windows. I guess the "32" bit of `System32` threw you off? That has to be retained for backwards compatibility. – Cody Gray - on strike Apr 11 '12 at 16:55
  • 1
    Edited to add more detail to the question. Yes, you are right about `32` pat in `system32` which looked a bit awkward to me at first. I hope the added detail will help me to answer the question. – user1240679 Apr 11 '12 at 19:06
  • Can someone **please** clarify why a **copy** or **move** command from a **64-bit** CMD.exe still redirects my file to the SysWOW64 folder instead of System32? The to be copied/moved file is a 64-bit .exe and i'm **not** issueing the command from a 32-bit CMD.exe – script'n'code Jul 01 '17 at 02:54
  • I cannot clarify that, @copyitright. I cannot even reproduce that behavior. – Cody Gray - on strike Jul 01 '17 at 11:39
7

I had the same problem. The solutions is to set the "Platform target" as x64 or AnyCPU instead of x86 in project properties in Visual Studio. In this case the path will be "C:\Windows\system32" and will not redirect to "C:\Windows\SysWOW64" You can check this by placing any file in the "C:\Windows\SysWOW64" folder and then use File.Exists command to check if file is found in that folder:

File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), sFileName));

Or

File.Exists(Path.Combine(Environment.SystemDirectory, sFileName));

enter image description here

Computer User
  • 2,839
  • 4
  • 47
  • 69
4

I use a helper property in my 32 bit applications that always return the native system32 folder. The helper property is:

public static string NativeSystemPath
{
    get
    {
        if (Environment.Is64BitOperatingSystem)
        {
            return System.IO.Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.Windows),
                "Sysnative");
        }
        return Environment.GetFolderPath(Environment.SpecialFolder.System);
    }
}
Juan Carlos Velez
  • 2,840
  • 2
  • 34
  • 48
2

As path environnement variable contains c:\windows on both windows x86/x64 versions, why not putting your tool into c:\windows : %windir%?

In my case this solve my problem.

andr
  • 15,970
  • 10
  • 45
  • 59
xponard
  • 21
  • 1