1.

Solve : Batch file copies to wrong folder on x64?

Answer»

I have a batch file that I converted to exe. It has a line that copies a file like this:

copy filename.dat %SYSTEMROOT%\system32

On windows 7 32-bit, it works fine, but on x64 it copies to the sysWOW64 folder for some reason even though I explicitly specify system32. It causes the file to not work because only system32 is in the path variable and sysWOW64 is not, so it can't be accessed from anywhere. I need to figure out how to force it to copy to system32 (i don't want to mess with the path). I can make it work by manually copying it with explorer, but I need the program to do it.You will need to "mess with the path"...
And check if you are using the 64 or 32 bit cmd.exe. (You did know there are two?) The 32 bit one redirects system32 to SYSWOW64  - read the Wiki about wow64 at http://en.wikipedia.org/wiki/WoW64
 
64 bit... %windir%\system32\cmd.exe
32 bit... %windir%\syswow64\cmd.exe

http://bc-programming.com/blogs/2009/12/windows-x64-fileregistry-redirection/

Basically, your batch file is now being run always as a 32-bit program because the executable is 32-bit and thus it will always be susceptible to redirection. (so either don't convert to a exe, or write a bunch of workaround script to check what the system's bit width is).Thanks BC. Your blog is very helpful. Here is what I wrote from the information on your blog. Will this work (I don't have a system with 7 64 to test it right now)?

Code: [Select]if %PROCESSOR_ARCHITECTURE%==x86 (
copy file.dat %systemroot%\system32
) else (
copy file.dat %systemroot%\sysnative
)
Am I missing something here? The OP has written a batch file and "compiled" it to make a 32 bit executable (WELL, a 32 bit WRAPPER which unwraps the batch and makes cmd.exe (on a 64 bit system, the 32 bit cmd.exe) run it. So he is living in a 32 bit world with a 32 bit sky, and 32 bit birds singing in 32 bit trees. In that 32 bit world, file system direction ensures that the right "system32" folder is "seen" by apps, birds, trees, etc.

In other words this line

Quote

copy filename.dat %systemroot%\system32

is executed correctly.

Why is there any need to penetrate the 64 bit system?

 Because on the x64 system, this line. . .

copy filename.dat %systemroot%\system32

Copies to sysWOW64 and not the real system32 where I need it to. Quote
Because on the x64 system, this line. . .

copy filename.dat %systemroot%\system32

Copies to sysWOW64

YES, I know it does!

Quote from: Linux711 on January 31, 2012, 12:55:13 PM
not the real system32 where I need it to.

Why do you "need" it to?
Because the PATH environment variable only points to system32 and not sysWOW32, so when I enter it into command prompt from anywhere, it doesn't work if it's in sysWOW64. Plus my program is designed to operate from system32, not anywhere else. At this point, you probably want to know what it's for. It is a program that adds an item to the right-click menu of any file. It allows you to delete any file even if it's protected by trusted installer. That's one of the things in 7 that makes my angry because I like to do a lot of system modding and I can't when everything is blocked from deletion by the admin.
if /i "%programfiles%"=="%programfiles(x86)%" (
    REM This is a 32 bit command prompt
    %systemroot%\sysnative\cmd.exe /c copy filename.dat %systemroot%\system32
) else (
    REM This is a 64 bit command prompt
    copy filename.dat %systemroot%\system32
)


Updated comments to be a bit clearer


if /i "%programfiles%"=="%programfiles(x86)%" (
    REM On a 64 bit system this is a 32 bit command prompt
    %systemroot%\sysnative\cmd.exe /c copy filename.dat %systemroot%\system32
) else (
    REM On a 64 bit system this is a 64 bit command prompt
    REM On a 32 bit system this is the only command prompt
    copy filename.dat %systemroot%\system32
)

Updated comments to be a bit clearer (again)


if /i "%programfiles%"=="%programfiles(x86)%" (
    REM On a 64 bit system this is a 32 bit command prompt
    REM So invoke the 64 bit cmd.exe to do the copy
    %systemroot%\sysnative\cmd.exe /c copy filename.dat %systemroot%\system32
) else (
    REM On a 64 bit system this is a 64 bit command prompt
    REM On a 32 bit system this is the only command prompt
    copy filename.dat %systemroot%\system32
)

Thanks for the help. Can't try it right now bc I'm not near my x64 comp. I tested my code and it didn't work so I'm hoping yours will. If it doesn't, I am just going to change my whole program to run in the windows folder instead of system32. I think that will work. Quote from: Linux711 on February 01, 2012, 10:11:24 AM
I tested my code and it didn't work so I'm hoping yours will.



Using exactly the same batch, on:

my 64 bit Windows 7 system the results were

32 bit command prompt: file was copied to C:\Windows\System32 (not C:\Windows\SysWOW64)
64 bit command prompt: likewise

On my 32 bit Windows XP system the result was the file was copied to C:\Windows\System32




My suggested solution exploits the FOLLOWING:

In a 32 bit command environment the environment variable %programfiles% has the same value as %programfiles(x86)%. In a 64 bit environment it does not. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. Thus a 32 bit command prompt can select the 64 bit version of cmd. exe. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one, and is not seen by 64 bit programs.



Discussion

No Comment Found