Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有办法列出所有可用的窗口';开车?_Python_Windows - Fatal编程技术网

Python 有没有办法列出所有可用的窗口';开车?

Python 有没有办法列出所有可用的窗口';开车?,python,windows,Python,Windows,Python中有没有办法列出Windows系统中当前使用的所有驱动器号 (我的谷歌fu似乎让我失望了) AC++等效程序: 改编自: 不使用任何外部库,如果这对您很重要: import string from ctypes import windll def get_drives(): drives = [] bitmask = windll.kernel32.GetLogicalDrives() for letter in string.uppercase:

Python中有没有办法列出Windows系统中当前使用的所有驱动器号

(我的谷歌fu似乎让我失望了)

A
C++
等效程序:

改编自:
不使用任何外部库,如果这对您很重要:

import string
from ctypes import windll

def get_drives():
    drives = []
    bitmask = windll.kernel32.GetLogicalDrives()
    for letter in string.uppercase:
        if bitmask & 1:
            drives.append(letter)
        bitmask >>= 1

    return drives

if __name__ == '__main__':
    print get_drives()     # On my PC, this prints ['A', 'C', 'D', 'F', 'H']

这些看起来是更好的答案。这是我的粗制滥造

import os, re
re.findall(r"[A-Z]+:.*$",os.popen("mountvol /").read(),re.MULTILINE)
在他的回答上重复一点;这并不是真的更好,但你可以让windows来制作字母表中的实际字母

>>> import ctypes
>>> buff_size = ctypes.windll.kernel32.GetLogicalDriveStringsW(0,None)
>>> buff = ctypes.create_string_buffer(buff_size*2)
>>> ctypes.windll.kernel32.GetLogicalDriveStringsW(buff_size,buff)
8
>>> filter(None, buff.raw.decode('utf-16-le').split(u'\0'))
[u'C:\\', u'D:\\']
其中包括可能有帮助的内容。不过,我没有windows机器来测试它,所以我不确定您是否需要“名称”、“系统名称”、“卷名”或其他名称

import win32com.client 
strComputer = "." 
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2") 
colItems = objSWbemServices.ExecQuery("Select * from Win32_LogicalDisk") 
for objItem in colItems: 
    print "Access: ", objItem.Access 
    print "Availability: ", objItem.Availability 
    print "Block Size: ", objItem.BlockSize 
    print "Caption: ", objItem.Caption 
    print "Compressed: ", objItem.Compressed 
    print "Config Manager Error Code: ", objItem.ConfigManagerErrorCode 
    print "Config Manager User Config: ", objItem.ConfigManagerUserConfig 
    print "Creation Class Name: ", objItem.CreationClassName 
    print "Description: ", objItem.Description 
    print "Device ID: ", objItem.DeviceID 
    print "Drive Type: ", objItem.DriveType 
    print "Error Cleared: ", objItem.ErrorCleared 
    print "Error Description: ", objItem.ErrorDescription 
    print "Error Methodology: ", objItem.ErrorMethodology 
    print "File System: ", objItem.FileSystem 
    print "Free Space: ", objItem.FreeSpace 
    print "Install Date: ", objItem.InstallDate 
    print "Last Error Code: ", objItem.LastErrorCode 
    print "Maximum Component Length: ", objItem.MaximumComponentLength 
    print "Media Type: ", objItem.MediaType 
    print "Name: ", objItem.Name 
    print "Number Of Blocks: ", objItem.NumberOfBlocks 
    print "PNP Device ID: ", objItem.PNPDeviceID 
    z = objItem.PowerManagementCapabilities 
    if z is None: 
        a = 1 
    else: 
        for x in z: 
            print "Power Management Capabilities: ", x 
    print "Power Management Supported: ", objItem.PowerManagementSupported 
    print "Provider Name: ", objItem.ProviderName 
    print "Purpose: ", objItem.Purpose 
    print "Quotas Disabled: ", objItem.QuotasDisabled 
    print "Quotas Incomplete: ", objItem.QuotasIncomplete 
    print "Quotas Rebuilding: ", objItem.QuotasRebuilding 
    print "Size: ", objItem.Size 
    print "Status: ", objItem.Status 
    print "Status Info: ", objItem.StatusInfo 
    print "Supports Disk Quotas: ", objItem.SupportsDiskQuotas 
    print "Supports File-Based Compression: ", objItem.SupportsFileBasedCompression 
    print "System Creation Class Name: ", objItem.SystemCreationClassName 
    print "System Name: ", objItem.SystemName 
    print "Volume Dirty: ", objItem.VolumeDirty 
    print "Volume Name: ", objItem.VolumeName 
    print "Volume Serial Number: ", objItem.VolumeSerialNumber 

由于我的笔记本电脑领域没有安装win32api,因此我使用wmic使用此解决方案:

import subprocess
import string

#define alphabet
alphabet = []
for i in string.ascii_uppercase:
    alphabet.append(i + ':')

#get letters that are mounted somewhere
mounted_letters = subprocess.Popen("wmic logicaldisk get name", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#erase mounted letters from alphabet in nested loop
for line in mounted_letters.stdout.readlines():
    if "Name" in line:
        continue
    for letter in alphabet:
        if letter in line:
            print 'Deleting letter %s from free alphabet %s' % letter
            alphabet.pop(alphabet.index(letter))

print alphabet
或者,您可以从这两个列表中获得差异,就像这个更简单的解决方案(在以挂载字母启动wmic子流程之后):


这两种解决方案的速度都差不多,但我想出于某种原因,set list会更好,对吧?

作为类似任务的一部分,我还需要抓取一个免费的驱动器号。我决定我想要的是最高的信。我先用更惯用的方式写出来,然后把它揉成一行,看看它是否仍然有意义。与列表理解一样令人敬畏的是,我喜欢这方面的集合:
unused=set(alphabet)-set(used)
而不必做
unused=[a对于a,如果a不在a中,则a在a中]
。很酷的东西

def get_used_drive_letters():
    drives = win32api.GetLogicalDriveStrings()
    drives = drives.split('\000')[:-1]
    letters = [d[0] for d in drives]
    return letters

def get_unused_drive_letters():
    alphabet = map(chr, range(ord('A'), ord('Z')+1))
    used = get_used_drive_letters()
    unused = list(set(alphabet)-set(used))
    return unused

def get_highest_unused_drive_letter():
    unused = get_unused_drive_letters()
    highest = list(reversed(sorted(unused)))[0]
    return highest
一行:

def get_drive():
    highest = sorted(list(set(map(chr, range(ord('A'), ord('Z')+1))) -
                          set(win32api.GetLogicalDriveStrings().split(':\\\000')[:-1])))[-1]

我还选择了使用map/range/ord/chr而不是使用string的字母表,因为string的某些部分已被弃用。

在Google上找到了这个解决方案,它比原来的稍有修改。看起来很像蟒蛇,不需要任何“异国情调”的进口


我写了这段代码:

import os
drives = [ chr(x) + ":" for x in range(65,91) if os.path.exists(chr(x) + ":") ]
它基于@Barmaley的答案,但具有不使用
字符串

模块,以防您不想使用它。它也适用于我的系统,不同于@SingleNegationElimination的答案。

基于@RichieHindle的更优解决方案

def get_drives():
    drives = []
    bitmask = windll.kernel32.GetLogicalDrives()
    letter = ord('A')
    while bitmask > 0:
        if bitmask & 1:
            drives.append(chr(letter) + ':\\')
        bitmask >>= 1
        letter += 1

    return drives

以下是我的高性能方法(可能更高):

没有人真正使用python的性能特性

是的,我没有遵循Windows标准路径约定(“\\”)

在我使用python的所有岁月中,我在使用路径的任何地方都没有遇到任何问题,并且在我的程序中使其成为标准。

在Windows上,您可以执行os.popen

import os
print os.popen("fsutil fsinfo drives").readlines()

如果您不想担心跨平台问题,包括跨python平台(如Pypy)的问题,并且希望在运行时更新驱动器时使用适当的性能:

>>> from os.path import exists
>>> from sys import platform
>>> drives = ''.join( l for l in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if exists('%s:/'%l) ) if platform=='win32' else ''
>>> drives
'CZ'
下面是我对这段代码的性能测试:

4000 iterations; threshold of min + 250ns:
__________________________________________________________________________________________________________code___|_______min______|_______max______|_______avg______|_efficiency
⡇⠀⠀⢀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣷⣷⣶⣼⣶⣴⣴⣤⣤⣧⣤⣤⣠⣠⣤⣤⣶⣤⣤⣄⣠⣦⣤⣠⣤⣤⣤⣤⣄⣠⣤⣠⣤⣤⣠⣤⣤⣤⣤⣤⣤⣄⣤⣤⣄⣤⣄⣤⣠⣀⣀⣤⣄⣤⢀⣀⢀⣠⣠⣀⣀⣤⣀⣠
    drives = ''.join( l for l in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if exists('%s:/'%l) ) if platform=='win32' else '' |      290.049ns |     1975.975ns |      349.911ns |  82.892%

如果您只想列出光盘上的驱动器,而不想列出映射的网络驱动器,这是另一个很好的解决方案。如果要按不同的属性进行过滤,只需打印DRP即可

import psutil
drps = psutil.disk_partitions()
drives = [dp.device for dp in drps if dp.fstype == 'NTFS']

此代码将返回驱动器名和字母列表,例如:

['Gateway(C:)'、'EOS_DIGITAL(L:)'、'Music Archive(O:)']

它只使用标准库。它基于我在上面找到的一些想法。 如果磁盘驱动器为空,则返回0,例如没有磁盘的CD rom。此代码未列出这些空驱动器

这两行记录了所有驱动器的字母:

bitmask = (bin(windll.kernel32.GetLogicalDrives())[2:])[::-1]  # strip off leading 0b and reverse
drive_letters = [ascii_uppercase[i] + ':/' for i, v in enumerate(bitmask) if v == '1']
以下是完整的例行程序:

from ctypes import windll, create_unicode_buffer, c_wchar_p, sizeof
from string import ascii_uppercase

def get_win_drive_names():
    volumeNameBuffer = create_unicode_buffer(1024)
    fileSystemNameBuffer = create_unicode_buffer(1024)
    serial_number = None
    max_component_length = None
    file_system_flags = None
    drive_names = []
    #  Get the drive letters, then use the letters to get the drive names
    bitmask = (bin(windll.kernel32.GetLogicalDrives())[2:])[::-1]  # strip off leading 0b and reverse
    drive_letters = [ascii_uppercase[i] + ':/' for i, v in enumerate(bitmask) if v == '1']

    for d in drive_letters:
        rc = windll.kernel32.GetVolumeInformationW(c_wchar_p(d), volumeNameBuffer, sizeof(volumeNameBuffer),
                                                   serial_number, max_component_length, file_system_flags,
                                                   fileSystemNameBuffer, sizeof(fileSystemNameBuffer))
        if rc:
            drive_names.append(f'{volumeNameBuffer.value}({d[:2]})')  # disk_name(C:)
    return drive_names

这是一个更简单的版本,没有安装任何附加模块或任何功能。由于驱动器号不能超过A和Z,因此您可以搜索每个字母表是否有可用的路径,如下所示:

>>> import os
>>> for drive_letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        if os.path.exists(f'{drive_letter}:'):
            print(f'{drive_letter}:')
        else:
            pass
一行:

>>> import os
>>> [f'{d}:' for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if os.path.exists(f'{d}:')]
['C:', 'D:']

这将有助于在windows操作系统中找到有效的驱动器

import os
import string
drive = string.ascii_uppercase
valid_drives = []
for each_drive in drive:
    if os.path.exist(each_drive+":\\"):
       print(each_drive)
       valid_drives.append(each_drive+":\\")
print(valid_drives)
输出将是

C
D
E
['C:\\','D:\\','E:\\']

如果您只需要每个驱动器的字母,您可以:

从win32.win32 API导入GetLogicalDriveStrings
驱动器=[GetLogicalDriveStrings()[0]中驱动器的驱动器]


string.lowercase或string.ascii\u lowercase而不是string.letters[len(string.letters)/2:]?@John:没有理由-谢谢你的建议,现在改为string.uppercase(因为对于驱动器号,我更喜欢大写字母,不知道为什么8-[c+':\\\\'表示字符串中的c.lowercase如果os.path.isdir(c+':\\'))贝瑞:如果你有没有介质的可移动媒体驱动器,那会弹出讨厌的Windows对话框……这段代码在Linux上毫无意义
GetLogicalDrives()
是一个Windows API。Linux上不存在逻辑驱动器(C:,D:,等等)的概念。我不知道Eclipse在做什么。感谢您链接到Microsoft脚本存储库。我一直觉得它是一个非常好的资源,适用于尚未广为人知的Windows程序员:-)另一个+1用于链接到Microsoft脚本存储库,我以前从未听说过。链接已失效,这里有一个从WayBackMachine保存的版本:谢谢@Enkouyami,看起来微软没有删除内容,只是移动了它。我四处寻找,找到了一个工作链接。我只是在2.6中尝试了一下,最后得到了一个额外的空字符串。仍然是一个很好的答案。为了确保不丢弃任何非空字符串,考虑使用<代码>驱动器=驱动器中的DRIVESTR。拆分(“000”)如果DRIVESTR] 这也会返回虚拟CD驱动器。我想检查路径是否有效是个好主意。我必须以管理员身份运行
pip install pypiwin32
,然后才能使用
import win32api
。我喜欢这个解决方案。方便地不必使用win32api。
UnicodeDecodeError:“charmap”编解码器无法解码586位置的字节0x81:字符映射到
@SebastianHietsch:请问一个新问题。在Windows 8、Python 3.5.2上不适用于我。获取C驱动器,但不获取Z驱动器。
mountvol/
除了在Windows 7或10上显示命令的使用信息外,似乎什么都不做……FWIW这对我来说至少失败了一次,原因未知这实际上是对驱动器的访问,所以这不是唯一的解决方案,尽管这里有Python noob!我猜是
>>> import os
>>> for drive_letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        if os.path.exists(f'{drive_letter}:'):
            print(f'{drive_letter}:')
        else:
            pass
>>> import os
>>> [f'{d}:' for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if os.path.exists(f'{d}:')]
['C:', 'D:']
import os
import string
drive = string.ascii_uppercase
valid_drives = []
for each_drive in drive:
    if os.path.exist(each_drive+":\\"):
       print(each_drive)
       valid_drives.append(each_drive+":\\")
print(valid_drives)
C
D
E
['C:\\','D:\\','E:\\']