Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Windows Development
  4. GRRRR!! 32 bit / 64 bit file mappings...

GRRRR!! 32 bit / 64 bit file mappings...

Scheduled Pinned Locked Moved Windows Development
helpquestionasp-netdebuggingtools
15 Posts 6 Posters 41 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K kalberts

    Of course I do not intentionally want to put files into \Windows\System32! But my utility is agnostic with respect to the file name specified on the call line. If the user sits in \Windows\System32\ and specifies plain filename, with no path, the utility accepts that - it does not make any specific check for \Windows\System32 saying "I think you shouldn't write to this directory". That is the responsibility of the user. There are other directories where I really don't want to leave .bat files, such as C:\ For all practical purposes it doesn't matter: The desktop user really calls a small script that generates the file, executes it, and deletes it. The problem with \Windows\System32 is that the file generated under \Windows\System32 cannot be deleted (from the script) under that name, because it isn't there, it is in a different place, under a different name from the name it was created with! When the user sits in \Windows\System32 and explicitly asks for writing a .bat file there, and it is automatically deleted immediately after running, then I do not see the big problem: The user has write access, then I will do what he asks for. In locations where the user has no write privleges, the utility fails - I'd be happy to see that in \Windows\System32. The problem is that you can create the file, but you can't delete it without knowing all the inner workings and give special treatment to a bunch of directory names that appears to be quite normal. There are a number of such virtual directories in Windows, essentially for accessing user profile data. In those cases, line 1 and line 2 in a given script file sees the same real file when using identical names. That is not the case here: A .net application sees a different file from what cmd.exe sees. That is what creates the problems.

    L Offline
    L Offline
    Lost User
    wrote on last edited by
    #5

    Sorry but I don't understand why this is the user's fault. If it's your utility then it is your responsibility to ensure it is installed in the correct location.

    K 1 Reply Last reply
    0
    • Richard DeemingR Richard Deeming

      It's called file system redirection[^], and it's part of the long and complicated history of maintaining backward compatibility with old programs. Windows Confidential: History—the Long Way Through[^] If you're absolutely sure that you want to write to the System32 folder, you can apparently use the alias %windir%\Sysnative to tell the redirector not to mess with the path.


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      K Offline
      K Offline
      kalberts
      wrote on last edited by
      #6

      Sure there are explanations, and frequently good ones. It can make sense to give a 64 bit application a different file than the one you give to a 32 bit application, especially if we talk about executable code. This logic may be the very best for the intended use. My utility will write the file wherever the user tells it to write - it treats any file name as a plain string and does NOT have a list of directories given special treatment. I have no particular interest in writing to System32 - but if the user asks me to (in the command line parameter), I will do so. If the write fails, I'll report it. If it succeeds (which it does), and the file can be read back by the utility from System32, I would expect that the user's script could also read it back from System32. It can't. That's the frustrating point. The user doesn't have an expressed wish to write to System32 - that's just were he ends up when starting cmd.exe. So he says: "Place the file here; it will be deleted in a second anyway". He doesn't want to know that he must specify ..\Sysnative to write them to his current working directory, named System32. The other alternative, that the next line in his script runs the file, which was written to System32, from ..\SysWOW64, is not significantly better. The user should not need to be concerned about the utility runing under dotNET! Trying to explain such things to users is not likely to make you a lot of new friends among them... The end result is that if I want my utility to work (or even to give an error message / error return) for all users, even those running it from special directories, my utility will have to mess with the path, and be aware of all the paths that need to be messed with. One funny detail I discovered after beginning to understand what happens: Start cmd.exe from \Windows\System32. Start cmd.exe from \Windwos\SysWOW64, and tell it to CD ..\System32. With the two command shells running from the same directory, give both a DIR command. The two directory lists, produced by the same command in the same current directory are neverhteless quite different. The directory name might fool you to think that \Windows\System32\cmd.exe is a 32 bit program. It is not. It is a 64 bit program, while the one in SysWOW64 is a 32 bit program. I guess that if we had a 64 bit implementation of dotNet, it would go to the same locations as e.g. Explorer does, so they would see the same set of files. As far as I know, dotNet is a 32 bit implementation (correct me if I am wrong). But

      Richard DeemingR 1 Reply Last reply
      0
      • L Lost User

        Sorry but I don't understand why this is the user's fault. If it's your utility then it is your responsibility to ensure it is installed in the correct location.

        K Offline
        K Offline
        kalberts
        wrote on last edited by
        #7

        Nobody says it's the user's fault. The user specifies a file name, my utility writes to the file named by the user, and successfully reads it back, under the name given by the user. Everything is OK so far. Then the user tries to read it (i.e. execute the script) using the file name he gave to the utility, and which worked fine within the utility. But then the file isn't there! Even if the user specifies the fully rooted name, both when giving it to the utility, and when trying to execute the generated script, the file isn't there. But it was when the utility wrote it (and later read it back), under that very same name. Whose fault is that? The user's fault? The utility's fault? They both use the same name, even fully rooted, but the file nevertheless "disappears". This has nothing to do with where the utility is installed (that's in a completely different directory). The situation described solely depends on a data file written to C:\Windows\System32\. If the writing is done by a dotNet program, or any other 32 bit program, the data file is written to C:\Windows\SysWOW64, and is not seen in C:\Windows\System32\ by neither Explorer, cmd.exe nor any other 64 bit program, but appears to have disappeared. (Unless you fully understand what is going on - but even seasoned system programmers may be weak in that respect.) If the user makes a "CD \" before running the utility, everything works fine. Or if he specifies a file name that is NOT in C:\Windows\System32. This is not easy to make users see as reasonable or "right". Plain users really shoudn't be messing around in C:\Windows\System32\ at all - but in an out-of-the box Windows installation, that is exactly where the user is sent when he opens a command window. That is really the one to blame! If the default working directory for cmd.exe had been C:\ rather than C:\Widows\System32, there wouldn't have been a problem. Well, obviously: If some system guy really has work to do in \Windows\System32, the problem would still be the same for that guy. But if he has a reason to fiddle with System32, then he is most likely competent to understand why the system behaves that way. The ordinary user is not.

        R L 2 Replies Last reply
        0
        • K kalberts

          Nobody says it's the user's fault. The user specifies a file name, my utility writes to the file named by the user, and successfully reads it back, under the name given by the user. Everything is OK so far. Then the user tries to read it (i.e. execute the script) using the file name he gave to the utility, and which worked fine within the utility. But then the file isn't there! Even if the user specifies the fully rooted name, both when giving it to the utility, and when trying to execute the generated script, the file isn't there. But it was when the utility wrote it (and later read it back), under that very same name. Whose fault is that? The user's fault? The utility's fault? They both use the same name, even fully rooted, but the file nevertheless "disappears". This has nothing to do with where the utility is installed (that's in a completely different directory). The situation described solely depends on a data file written to C:\Windows\System32\. If the writing is done by a dotNet program, or any other 32 bit program, the data file is written to C:\Windows\SysWOW64, and is not seen in C:\Windows\System32\ by neither Explorer, cmd.exe nor any other 64 bit program, but appears to have disappeared. (Unless you fully understand what is going on - but even seasoned system programmers may be weak in that respect.) If the user makes a "CD \" before running the utility, everything works fine. Or if he specifies a file name that is NOT in C:\Windows\System32. This is not easy to make users see as reasonable or "right". Plain users really shoudn't be messing around in C:\Windows\System32\ at all - but in an out-of-the box Windows installation, that is exactly where the user is sent when he opens a command window. That is really the one to blame! If the default working directory for cmd.exe had been C:\ rather than C:\Widows\System32, there wouldn't have been a problem. Well, obviously: If some system guy really has work to do in \Windows\System32, the problem would still be the same for that guy. But if he has a reason to fiddle with System32, then he is most likely competent to understand why the system behaves that way. The ordinary user is not.

          R Offline
          R Offline
          RedDk
          wrote on last edited by
          #8

          Top off all this grief about redirection with a look at what happens when "double encoding" takes place (as Windows deciphers webpage locations) ... and your day will really become a train wreck! ;)

          1 Reply Last reply
          0
          • K kalberts

            Nobody says it's the user's fault. The user specifies a file name, my utility writes to the file named by the user, and successfully reads it back, under the name given by the user. Everything is OK so far. Then the user tries to read it (i.e. execute the script) using the file name he gave to the utility, and which worked fine within the utility. But then the file isn't there! Even if the user specifies the fully rooted name, both when giving it to the utility, and when trying to execute the generated script, the file isn't there. But it was when the utility wrote it (and later read it back), under that very same name. Whose fault is that? The user's fault? The utility's fault? They both use the same name, even fully rooted, but the file nevertheless "disappears". This has nothing to do with where the utility is installed (that's in a completely different directory). The situation described solely depends on a data file written to C:\Windows\System32\. If the writing is done by a dotNet program, or any other 32 bit program, the data file is written to C:\Windows\SysWOW64, and is not seen in C:\Windows\System32\ by neither Explorer, cmd.exe nor any other 64 bit program, but appears to have disappeared. (Unless you fully understand what is going on - but even seasoned system programmers may be weak in that respect.) If the user makes a "CD \" before running the utility, everything works fine. Or if he specifies a file name that is NOT in C:\Windows\System32. This is not easy to make users see as reasonable or "right". Plain users really shoudn't be messing around in C:\Windows\System32\ at all - but in an out-of-the box Windows installation, that is exactly where the user is sent when he opens a command window. That is really the one to blame! If the default working directory for cmd.exe had been C:\ rather than C:\Widows\System32, there wouldn't have been a problem. Well, obviously: If some system guy really has work to do in \Windows\System32, the problem would still be the same for that guy. But if he has a reason to fiddle with System32, then he is most likely competent to understand why the system behaves that way. The ordinary user is not.

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #9

            Like I said before, you should really not be writing into Windows\System32. There are plenty of locations which would save you all this aggravation, and indeed the estimable OrignalGriff has an article which may be of some use: Where should I store my data?[^], and yes I know it's about data.

            K 1 Reply Last reply
            0
            • K kalberts

              Sure there are explanations, and frequently good ones. It can make sense to give a 64 bit application a different file than the one you give to a 32 bit application, especially if we talk about executable code. This logic may be the very best for the intended use. My utility will write the file wherever the user tells it to write - it treats any file name as a plain string and does NOT have a list of directories given special treatment. I have no particular interest in writing to System32 - but if the user asks me to (in the command line parameter), I will do so. If the write fails, I'll report it. If it succeeds (which it does), and the file can be read back by the utility from System32, I would expect that the user's script could also read it back from System32. It can't. That's the frustrating point. The user doesn't have an expressed wish to write to System32 - that's just were he ends up when starting cmd.exe. So he says: "Place the file here; it will be deleted in a second anyway". He doesn't want to know that he must specify ..\Sysnative to write them to his current working directory, named System32. The other alternative, that the next line in his script runs the file, which was written to System32, from ..\SysWOW64, is not significantly better. The user should not need to be concerned about the utility runing under dotNET! Trying to explain such things to users is not likely to make you a lot of new friends among them... The end result is that if I want my utility to work (or even to give an error message / error return) for all users, even those running it from special directories, my utility will have to mess with the path, and be aware of all the paths that need to be messed with. One funny detail I discovered after beginning to understand what happens: Start cmd.exe from \Windows\System32. Start cmd.exe from \Windwos\SysWOW64, and tell it to CD ..\System32. With the two command shells running from the same directory, give both a DIR command. The two directory lists, produced by the same command in the same current directory are neverhteless quite different. The directory name might fool you to think that \Windows\System32\cmd.exe is a 32 bit program. It is not. It is a 64 bit program, while the one in SysWOW64 is a 32 bit program. I guess that if we had a 64 bit implementation of dotNet, it would go to the same locations as e.g. Explorer does, so they would see the same set of files. As far as I know, dotNet is a 32 bit implementation (correct me if I am wrong). But

              Richard DeemingR Offline
              Richard DeemingR Offline
              Richard Deeming
              wrote on last edited by
              #10

              Member 7989122 wrote:

              The user should not need to be concerned about the utility runing under dotNET!

              The fact that it's running under .NET is irrelevant; it's simply that it's a 32-bit application running on a 64-bit OS.

              Member 7989122 wrote:

              As far as I know, dotNet is a 32 bit implementation (correct me if I am wrong).

              Consider yourself corrected! :) There are both 32-bit and 64-bit versions of .NET, and assemblies can either be compiled to target a specific platform or left as "Any". How to: Configure Projects to Target Platforms | Microsoft Docs[^] The default for all projects used to be "Any", but I believe that was changed to "x86" for console applications in VS2010.


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

              K 1 Reply Last reply
              0
              • L Lost User

                Like I said before, you should really not be writing into Windows\System32. There are plenty of locations which would save you all this aggravation, and indeed the estimable OrignalGriff has an article which may be of some use: Where should I store my data?[^], and yes I know it's about data.

                K Offline
                K Offline
                kalberts
                wrote on last edited by
                #11

                Sounds simple and easy. So what do you suggest that I do, when the user opens a command window and asks the utility to genereate the file setenv.bat? Should I say: "Sorry, I can't do what you ask of me - even though you have write permission to that directory?" I am not making the choice where to store the data. The user is. The user is, inadvertently because that is where cmd.exe by default sends him, in System32. The user has write access. The file is deleted after a second in any case, after the script is run. You shouldn't store .bat files, not even for a second, in C:\ either. If the user nevertheless asks for it, it works, without. Should the utilty say, when the user says "Use C:\", in a similar manner say "Sorry, I am not willing to do that for you; you shouln't be puttng files there"? It is so simple to say "You shouldn't do that". When the user says "Do it!" you may blame the user, or you may blame the utility doing what it is being asked to. Or you may say: OK, if the user asks to use that directory, and permissions are OK, then the user asked for it, the user got it! You may go out on a mission to explain (or maybe "excuse") to all users of the world the underlaying reasons for why their files disappear into that black SysWOW64 hole, so that every user understands that where cnd.exe by default sends them, is to a place where they shouldn't be, and shouldn't touch anything unless they are computer experts. Then you have cleansed your hands and can say: We have told you not to be in that place where we sent you! So get out of there! This is logical, da*mit! Get out of there, now! Arguing like that to users make you sound like a Unix guru... :-)

                L 1 Reply Last reply
                0
                • Richard DeemingR Richard Deeming

                  Member 7989122 wrote:

                  The user should not need to be concerned about the utility runing under dotNET!

                  The fact that it's running under .NET is irrelevant; it's simply that it's a 32-bit application running on a 64-bit OS.

                  Member 7989122 wrote:

                  As far as I know, dotNet is a 32 bit implementation (correct me if I am wrong).

                  Consider yourself corrected! :) There are both 32-bit and 64-bit versions of .NET, and assemblies can either be compiled to target a specific platform or left as "Any". How to: Configure Projects to Target Platforms | Microsoft Docs[^] The default for all projects used to be "Any", but I believe that was changed to "x86" for console applications in VS2010.


                  "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                  K Offline
                  K Offline
                  kalberts
                  wrote on last edited by
                  #12

                  Ok, I wasn't aware of the 64 bit dotNET. Thanks for the correction. Obviously that isn't the default choice. Or at least was not under Windows7, which still is used on most of our machines. I will be looking into the possibility of switching to 64-bit dotNet. My gut feeling is that it might require a little more work, for 100+ PCs, than you can accomplish before lunch. And that there may be more than one compatibility/porting issue to be solved. Still, that is the way to go in the long run.

                  1 Reply Last reply
                  0
                  • K kalberts

                    Sounds simple and easy. So what do you suggest that I do, when the user opens a command window and asks the utility to genereate the file setenv.bat? Should I say: "Sorry, I can't do what you ask of me - even though you have write permission to that directory?" I am not making the choice where to store the data. The user is. The user is, inadvertently because that is where cmd.exe by default sends him, in System32. The user has write access. The file is deleted after a second in any case, after the script is run. You shouldn't store .bat files, not even for a second, in C:\ either. If the user nevertheless asks for it, it works, without. Should the utilty say, when the user says "Use C:\", in a similar manner say "Sorry, I am not willing to do that for you; you shouln't be puttng files there"? It is so simple to say "You shouldn't do that". When the user says "Do it!" you may blame the user, or you may blame the utility doing what it is being asked to. Or you may say: OK, if the user asks to use that directory, and permissions are OK, then the user asked for it, the user got it! You may go out on a mission to explain (or maybe "excuse") to all users of the world the underlaying reasons for why their files disappear into that black SysWOW64 hole, so that every user understands that where cnd.exe by default sends them, is to a place where they shouldn't be, and shouldn't touch anything unless they are computer experts. Then you have cleansed your hands and can say: We have told you not to be in that place where we sent you! So get out of there! This is logical, da*mit! Get out of there, now! Arguing like that to users make you sound like a Unix guru... :-)

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #13

                    Just make sure you generate your .bat file somewhere that is not going to cause problems, as suggested in OriginalGriff's Tip. It's no good saying the error is caused by the user's lack of knowledge, it is your responsibility to protect the user from him/herself.

                    1 Reply Last reply
                    0
                    • K kalberts

                      This is not a question - I just need to get some frustration out. And as a warning to other people about the problem. I have this utility generating a batch file for setting environment variable values. (The need arises because under the Bamboo build system, any environment setting is lost from one job step to the next; each job step must set the environment variables anew - but this is of minor importance to the problem). PATH and SET commands are written to a file named on the command line - I usually name it setenv.bat - and then executed in every job step. Only that some users, running this utility on their desktop machines, ended up with crazy environment settings, not at all those that the utility shold have generated. But the debugger showed the correct commands to be written to the file. The .bat file appeared to, in mysterious ways, being modified between being written and being executed on the next command line. The problem occured on PCs running cmd.exe in the default working directory, that of cmd.exe itself - C:\Windows\System32. (Most users change the CWD of cmd.exe to C:\ or some project directory, but those who rarely use CLI systems may not care to.) Running the utility from any other directory worked fine, but not from C:\Windows\System32. setenv.bat was not written to the directory; it never appeared. I suspected access right problems, but creating the file caused no error/exception. Maybe the physical file was not accessed (causing the exception) until the file was flushed? So I flushed the file explicitly before closing it. Still no exception. After closing I checked for File.Exists("C:\Windows\System32\setenv.bat"). True - file exists. I tried to open it: Once again - successful. I could read the correctly written contents. The file was completely absent from C:\Windows\System32\, yet I could create it, write to it, close it, open it again and read C:\Windows\System32\setenv.bat... What the... ??? So I searched the entire file system for the file setenv.bat. The first occurence explained how the crazy, incorrect settings could be made: Some completely unreated job had left a setenv.bat file in a directory on the path. Then there was a second setenv.bat occurence: In C:\Windows\SysWOW64, with a last written time stamp revealing that is was our guy. I haven't yet sat down to learn the relationhship between System32 and SysWOW64 (but I sure will do now!). Appearently, System32 is interpreted as one core set of files, plus some extra - but the extras depend on who is asking. W

                      T Offline
                      T Offline
                      Terry Perez
                      wrote on last edited by
                      #14

                      What is windows RT mean?

                      OriginalGriffO 1 Reply Last reply
                      0
                      • T Terry Perez

                        What is windows RT mean?

                        OriginalGriffO Offline
                        OriginalGriffO Offline
                        OriginalGriff
                        wrote on last edited by
                        #15

                        Windows RT - Wikipedia[^]

                        Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                        "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                        "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups