简体   繁体   English

为什么 os.path.realpath 将 c:\windows\system32 转换为 c:/windows/syswow64?

[英]Why does os.path.realpath convert c:\windows\system32 into c:/windows/syswow64?

If we take a look to https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve source code we can see the routine is calling behind the curtainshttps://docs.python.org/3/library/os.path.html#os.path.realpath If we take a look to https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve source code we can see the routine is calling behind the curtainshttps://docs.python.org /3/library/os.path.html#os.path.realpath

I'm trying to really understand how os.path.realpath works in certain directories such as c:\windows\system32 , ie:我试图真正了解 os.path.realpath 在某些目录中的工作原理,例如c:\windows\system32 ,即:

>>> from pathlib import Path                                                    
>>> Path("c:/windows/system32")                                                 
WindowsPath('c:/windows/system32')                                              
>>> Path("c:/windows/system32").resolve()                                       
WindowsPath('C:/Windows/SysWOW64')                                              
>>> Path("c:/windows/system32").resolve(strict=True)                            
WindowsPath('C:/Windows/SysWOW64')                                              
>>> Path("c:/windows/system32").resolve()==Path("c:/windows/system32")          
False          

Or directories such as c:/windows/system32/openssh where you can get "unexpected results" such as below:或诸如c:/windows/system32/openssh类的目录,您可以在其中获得“意外结果”,如下所示:

在此处输入图像描述

>>> list(Path("c:/windows/system32/openssh").resolve().glob("*"))
[]
>>> list(Path("c:/windows/system32/openssh").glob("*"))
[]

or或者

>>> os.listdir(r"C:\Windows\System32\OpenSSH")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\Windows\\System32\\OpenSSH'

If you do dir /a you'll get如果你做dir /a你会得到

24/09/2022  10:03    <DIR>          System32

So you can see it's neither a SYMLINKD nor JUNCTION.所以你可以看到它既不是 SYMLINKD 也不是 JUNCTION。

Could you explain how os.path.realpath works in these cases?你能解释一下 os.path.realpath 在这些情况下是如何工作的吗? Why can't i list/glob the content of that c:\windows\system32\openssh folder?为什么我不能列出 / glob 那个c:\windows\system32\openssh文件夹的内容?

References: ntpath.py参考: ntpath.py

Can't yet comment so I write an answer, event that I only have a hint for you.还不能发表评论,所以我写了一个答案,我只有一个提示给你。

The WoW64 Subsystems is a complicated thing but can sometimes feel like a symlink. WoW64 子系统是一个复杂的东西,但有时感觉就像一个符号链接。 It kinda handles 32 and 64 bit compaitbility and creates "dynamic" paths depending on what you are doing.它有点处理 32 位和 64 位兼容性,并根据您的操作创建“动态”路径。 It's a bit like if you run windows in german it will show you "Bilder" instead of "Pictures" but in the background it never changes.这有点像如果你用德语运行 windows 它会向你显示“图片”而不是“图片”,但在后台它永远不会改变。

You'll find more (basic) information about it on Wikipedia WoW64 on Wikipedia您将在 Wikipedia 上的 Wikipedia WoW64 上找到有关它的更多(基本)信息

Another example would be the built-in variable %COMSPEC% that would be另一个例子是内置变量 %COMSPEC%

  • c:\windows\system32\cmd.exe on 64bit c:\windows\system32\cmd.exe on 64bit
  • C:\Windows\SysWOW64\cmd.exe on 32bit WoW C:\Windows\SysWOW64\cmd.exe 在 32 位魔兽世界

Sometimes you see teh SysWOW64 showing through, but most often all you see is system32有时您会看到 SysWOW64 显示出来,但通常您看到的只是 system32

Long story short: You will need to dig deeper into the WoW64 topic.长话短说:您需要深入挖掘 WoW64 主题。

On windows, os.path.realpath is using GetFinalPathNameByHandleW behind the curtains, for more info you can check here .在 windows 上,os.path.realpath 在幕后使用GetFinalPathNameByHandleW ,有关更多信息,您可以在此处查看

If we make a simple experiment to see how that routine works:如果我们做一个简单的实验来看看这个例程是如何工作的:

#include <windows.h>
#include <iostream>

#define MAXPATHLEN 1024

void os__getfinalpathname_impl(const std::wstring &path) {
    std::wcout << L"analizing: " << path << std::endl;

    HANDLE hFile;
    wchar_t buf[MAXPATHLEN];
    int result_length;

    hFile = CreateFileW(path.c_str(), 0, 0, NULL, OPEN_EXISTING,
                        FILE_FLAG_BACKUP_SEMANTICS, NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        std::wcout << L"CreateFileW:" << path << std::endl;
    }

    result_length =
        GetFinalPathNameByHandleW(hFile, buf, MAXPATHLEN, VOLUME_NAME_DOS);

    if (!result_length) {
        std::wcout << L"GetFinalPathNameByHandleW" << std::endl;
    }

    std::wcout << L"result: " << buf << std::endl;
}

void main(int argc, char *argv[]) {
    std::wcout << L"test1" << std::endl;
    os__getfinalpathname_impl(L"c:/windows/system32");
    std::wcout << L"test2" << std::endl;
    os__getfinalpathname_impl(L"c:\\windows\\system32");
}

If we compile it for a 32-bit target we'll get:如果我们为 32 位目标编译它,我们将得到:

test1
analizing: c:/windows/system32
result: \\?\C:\Windows\SysWOW64
test2
analizing: c:\windows\system32
result: \\?\C:\Windows\SysWOW64

If we compile it for a 64-bit target we'll get:如果我们为 64 位目标编译它,我们将得到:

test1
analizing: c:/windows/system32
result: \\?\C:\Windows\System32
test2
analizing: c:\windows\system32
result: \\?\C:\Windows\System32

Now, if we want to confirm the above and checking the differences in a python context, we can do that easily by just spawning a couple oneliners:现在,如果我们想确认上述内容并检查 python 上下文中的差异,我们可以通过生成几个 oneliner 轻松做到这一点:

python\3.10.6-amd64\python.exe -c "from pathlib import Path; print(Path('c:/windows/system32').resolve())"
C:\Windows\System32

python\3.10.1\python.exe -c "from pathlib import Path; print(Path('c:/windows/system32').resolve())"
C:\Windows\SysWOW64

Which makes total sense accordingly what's described in the below link https://learn.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector因此,以下链接https://learn.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector中描述的内容完全有意义

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 os.path.exists 无法识别 C:\Windows\system32\drivers 下的子目录 - os.path.exists does not recognize a subdirectory under C:\Windows\system32\drivers 为什么os.path.exists(“C:\\ windows \\ system32 \\ inetsrv \\ metaback”)返回False,即使它存在? - Why would os.path.exists(“C:\\windows\\system32\\inetsrv\\metaback”) return False even when it exists? Python:从 system32 或 SysWOW64 删除文件夹的脚本 - Python: Script to delete folders from system32 or SysWOW64 在64位Windows上的C:\\ Windows \\ System32中的py2exe - py2exe in C:\Windows\System32 on 64-bit Windows os.path.realpath(__file__) 不返回预期路径 - os.path.realpath(__file__) does not return the expected path 为什么 os.path.realpath 不能正常工作 - Why os.path.realpath doesn't work properly 在 python 中执行 os.rmdir("C:\Windows\System32") 会发生什么? - What will happen on executing os.rmdir("C:\Windows\System32") in python? 终端进程启动失败:shell 可执行文件“C:\Windows\System32”的路径不是符号链接文件 - The terminal process failed to launch: Path to shell executable "C:\Windows\System32" is not a file of a symlink dll与c:\\ windows \\ system32不同的目录 - dll in a different directory than c:\windows\system32 无法打开自我C:\\ Windows \\ system32 \\ file.exe或存档C:\\ Windows \\ system32 \\ file.pkg - Cannot open self C:\Windows\system32\file.exe or archive C:\Windows\system32\file.pkg
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM