{"id":14133,"date":"2010-05-06T07:00:00","date_gmt":"2010-05-06T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2010\/05\/06\/what-are-these-strange-c-environment-variables\/"},"modified":"2010-05-06T07:00:00","modified_gmt":"2010-05-06T07:00:00","slug":"what-are-these-strange-c-environment-variables","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20100506-00\/?p=14133","title":{"rendered":"What are these strange =C: environment variables?"},"content":{"rendered":"<p>\nYou won&#8217;t see them when you execute a <code>SET<\/code> command,\nbut if you write a program that manually enumerates all the\nenvironment variables and prints them out,\nand if you launch it from a command prompt,\nthen you&#8217;ll see weird\nvariables with names like =C: and whose values correspond to\ndirectories on that drive.\nWhat are these things?\n<\/p>\n<p>\nThese variables are part of the private bookkeeping of the command\nprocessor cmd.exe.\nThat&#8217;s why I added <i>if you launch it from a command prompt<\/i>\nto the steps above, because if you run the program from Explorer&#8217;s\n<i>Run<\/i> dialog, you won&#8217;t see them.\nIf a cmd.exe is not in the chain of custody of your environment block,\nthen you won&#8217;t see the weird cmd.exe bookkeeping variables.\n<\/p>\n<p>\nOkay, so the command processor sets these things, but what are they?\nThey are a leftover from the command processor&#8217;s attempt to mimic\nthe old MS-DOS way that drives and directories were handled.\nWhereas in Win32, there is only one current directory,\nin MS-DOS, there was one current directory for each drive.\nConsider the following sequence of commands:\n<\/p>\n<pre>\nA&gt; CD \\SUBDIR\n\/\/ current directory for drive A is A:\\SUBDIR\nA&gt; B:\nB&gt; CD \\TWO\n\/\/ current directory for drive B is B:\\TWO\nB&gt; A:\nA&gt; DIR\n\/\/ shows a directory listing for A:\\SUBDIR\n<\/pre>\n<p>\nDuring this sequence of commands, we start with A: as the\ncurrent drive and set its current directory to A:\\SUBDIR.\nNext, we set the current drive to B: and set\nB:\\TWO as its current directory.\nFinally, we set the current drive back to A:,\nand when we ask for a listing,\nwe get the contents of A:\\SUBDIR because that is the\ncurrent directory on the current drive.\n<\/p>\n<p>\nWin32 does not have the concept of a separate current directory\nfor each drive, but the command processor wanted to preserve\nthe old MS-DOS behavior because people were accustomed to it\n(and batch files relied upon it).\nThe solution was to store this &#8220;per-drive current directory&#8221;\nin the environment, using a weird-o environment variable name\nso it wouldn&#8217;t conflict with normal environment variables.\n<\/p>\n<p>\nIf you repeated the above commands in cmd.exe, the output\nis the same, but it is accomplished in a very different way.\n<\/p>\n<pre>\nA&gt; CD \\SUBDIR\n\/\/ Environment variable =A: set to A:\\SUBDIR\n\/\/ Current Win32 directory set to A:\\SUBDIR\nA&gt; B:\nB&gt; CD \\TWO\n\/\/ Environment variable =B: set to B:\\TWO\n\/\/ current Win32 directory set to B:\\TWO\nB&gt; A:\n\/\/ Current Win32 directory set to A:\\SUBDIR\nA&gt; DIR\n\/\/ shows a directory listing for A:\\SUBDIR\n<\/pre>\n<p>\nWhen we switch back to drive A:,\nthe command processor says,\n&#8220;Hey, what was the current directory on drive A: the last\ntime I was there?&#8221;\nIt looks into its environment and finds the =A: variable,\nwhich tells it, &#8220;Oh, it was A:\\SUBDIR&#8221;.\nAnd that&#8217;s the Win32 directory that it sets as current.\n<\/p>\n<p>\nBut why put these internal variables in the environment?\nCan&#8217;t they just be regular variables inside the cmd.exe process?\n<\/p>\n<p>\nThe variables are exported into the environment because you\nwant these &#8220;fake per-drive current directories&#8221; to be inherited\nby child processes.\nFor example, consider that you are sitting at your command prompt,\nyou run emacs, then from emacs, you shell out to another command prompt.\nYou would expect that the nested command prompt will have the same\n&#8220;per-drive current directories&#8221; that you set back in the outer\ncommand prompt.\n<\/p>\n<pre>\nC:\\SUBDIR&gt; D:\nD:\\&gt; emacs\nM-x shell\nD:\\&gt; C:\nC:\\SUBDIR&gt;\n\/\/ the \"current directory on drive C\" was inherited as expected\n<\/pre>\n<p>\nWhat should you do about these variables, then?\n<\/p>\n<p>\nNothing. Just let them be and do their jobs.\nI&#8217;m just mentioning them here so you won&#8217;t freak out when you see them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You won&#8217;t see them when you execute a SET command, but if you write a program that manually enumerates all the environment variables and prints them out, and if you launch it from a command prompt, then you&#8217;ll see weird variables with names like =C: and whose values correspond to directories on that drive. What [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-14133","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>You won&#8217;t see them when you execute a SET command, but if you write a program that manually enumerates all the environment variables and prints them out, and if you launch it from a command prompt, then you&#8217;ll see weird variables with names like =C: and whose values correspond to directories on that drive. What [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/14133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=14133"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/14133\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=14133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=14133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=14133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}