Python 如果尚未打开,请在资源管理器中打开文件夹

Python 如果尚未打开,请在资源管理器中打开文件夹,python,vba,python-2.7,explorer,Python,Vba,Python 2.7,Explorer,我知道如何通过以下方式使用python在资源管理器中打开文件夹: subprocess.Popen(r'explorer/select,“C:\path\of\folder”) 但是,我不知道如何防止我的程序打开文件夹,如果它已经在资源管理器中“打开”。有没有办法在Python中实现这一点(或者可能通过VBA脚本)?我想您的问题主要是由于用户使用应用程序重新打开或重新单击所致 部分实现的一种方法可以是: 您可以将打开的资源管理器的pid(进程id)存储在一个变量中:subprocess.Pope

我知道如何通过以下方式使用python在资源管理器中打开文件夹:

subprocess.Popen(r'explorer/select,“C:\path\of\folder”)


但是,我不知道如何防止我的程序打开文件夹,如果它已经在资源管理器中“打开”。有没有办法在Python中实现这一点(或者可能通过VBA脚本)?

我想您的问题主要是由于用户使用应用程序重新打开或重新单击所致

部分实现的一种方法可以是:

您可以将打开的资源管理器的pid(进程id)存储在一个变量中:
subprocess.Popen(r'explorer/select,“C:\path\of\folder”)


然后,当再次尝试打开时,如果设置了pid。检查该进程是否仍处于活动状态。如果是,则不要打开它,也许可以找到一种方法来关注打开的窗口。

我想您的问题主要是由于用户使用应用程序重新打开或重新单击

部分实现的一种方法可以是:

您可以将打开的资源管理器的pid(进程id)存储在一个变量中:
subprocess.Popen(r'explorer/select,“C:\path\of\folder”)


然后,当再次尝试打开时,如果设置了pid。检查该进程是否仍处于活动状态。如果是,那么就不要打开它,也许可以找到一种方法来关注打开的寡妇。

我不确定你要做什么,但也许类似这样的事情会有所帮助:

import os
for root, dirs, files in os.walk(Folder_Root, topdown=False):
    for name in dirs:
        full_path = os.path.join(root, name)
        #use Popen to open the folder here

因此,请通读文件夹_Root下的所有目录,并用Popen打开每个目录。每个文件夹只打开一次。只需将文件夹_Root替换为实际路径即可

我不确定你想要什么,但也许这样做会有所帮助:

import os
for root, dirs, files in os.walk(Folder_Root, topdown=False):
    for name in dirs:
        full_path = os.path.join(root, name)
        #use Popen to open the folder here

因此,请通读文件夹_Root下的所有目录,并用Popen打开每个目录。每个文件夹只打开一次。只需将文件夹_Root替换为实际路径即可

我发现了一个有趣的线程,其中使用VBS脚本找到了列出打开文件夹的工作解决方案,但我不知道如何使用VBS,因此我无法解决除错误以外的
标识符并使其正常工作

守则本身是:

Imports System.Runtime.InteropServices
导入系统文本

公开课表格1 私有常量WM_GETTEXT为整数=&HD Private Const WM_GETTEXTLENGTH作为整数=&HE

<DllImport("user32.dll", EntryPoint:="FindWindowExW")> _
Private Shared Function FindWindowExW(ByVal hwndParent As System.IntPtr, ByVal hwndChildAfter As System.IntPtr, <InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpszClass As String, <InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpszWindow As String) As System.IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    ListBox1.Items.Clear()
    Dim hWinList As New List(Of IntPtr)

    'Get Each Explorer Windows Handle
    Dim hWnd As IntPtr = FindWindowExW(IntPtr.Zero, IntPtr.Zero, "CabinetWClass", Nothing)
    While Not hWnd.Equals(IntPtr.Zero)
        hWinList.Add(hWnd)
        hWnd = FindWindowExW(IntPtr.Zero, hWnd, "CabinetWClass", Nothing)
    End While

    'Loop threw each explorer window in the list and get the text from the Address combobox
    If hWinList.Count > 0 Then
        For Each hChld As IntPtr In hWinList
            Dim hChild1 As IntPtr = FindWindowExW(hChld, IntPtr.Zero, "WorkerW", Nothing)
            Dim hChild2 As IntPtr = FindWindowExW(hChild1, IntPtr.Zero, "ReBarWindow32", Nothing)
            Dim hChild3 As IntPtr = FindWindowExW(hChild2, IntPtr.Zero, "ComboBoxEx32", Nothing)
            Dim len As Integer = SendMessage(hChild3, WM_GETTEXTLENGTH, 0, Nothing)
            Dim sb As New StringBuilder(len + 1)
            SendMessage(hChild3, WM_GETTEXT, len + 1, sb)
            ListBox1.Items.Add(sb.ToString)
        Next
    End If

End Sub
_
私有共享函数FindWindowExW(ByVal hwndParent作为System.IntPtr,ByVal hwndChildAfter作为System.IntPtr,ByVal lpszClass作为字符串,ByVal lpszWindow作为字符串)作为System.IntPtr
端函数
_
私有共享函数SendMessage(ByVal hWnd作为IntPtr,ByVal Msg作为UInteger,ByVal wParam作为Integer,ByVal lParam作为StringBuilder)作为Integer
端函数
私有子按钮1\u单击(ByVal sender作为System.Object,ByVal e作为System.EventArgs)处理按钮1。单击
ListBox1.Items.Clear()
Dim hWinList作为新列表(IntPtr)
'获取每个资源管理器窗口句柄
Dim hWnd As IntPtr=FindWindowExW(IntPtr.Zero,IntPtr.Zero,“CabinetWClass”,无)
而不是hWnd.Equals(IntPtr.Zero)
hWinList.Add(hWnd)
hWnd=FindWindowExW(IntPtr.Zero,hWnd,“CabinetWClass”,无)
结束时
'循环抛出列表中的每个资源管理器窗口,并从地址组合框中获取文本
如果hWinList.Count>0,则
对于hWinList中作为IntPtr的每个hChld
尺寸hChild1为IntPtr=FindWindowExW(hChld,IntPtr.Zero,“WorkerW”,无)
尺寸hChild2为IntPtr=FindWindowExW(hChild1,IntPtr.Zero,“ReBarWindow32”,无)
Dim hChild3作为IntPtr=FindWindowExW(hChild2,IntPtr.Zero,“ComboBoxEx32”,无)
Dim len As Integer=SendMessage(hChild3,WM_GETTEXTLENGTH,0,Nothing)
将某人调整为新的StringBuilder(len+1)
SendMessage(hChild3,WM_GETTEXT,len+1,sb)
ListBox1.Items.Add(sb.ToString)
下一个
如果结束
端接头

结束类

我发现了一个有趣的线程,其中使用VBS脚本找到了列出打开文件夹的工作解决方案,但我不知道如何使用VBS,因此我无法解决除
错误以外的
标识符并使其正常工作

守则本身是:

Imports System.Runtime.InteropServices
导入系统文本

公开课表格1 私有常量WM_GETTEXT为整数=&HD Private Const WM_GETTEXTLENGTH作为整数=&HE

<DllImport("user32.dll", EntryPoint:="FindWindowExW")> _
Private Shared Function FindWindowExW(ByVal hwndParent As System.IntPtr, ByVal hwndChildAfter As System.IntPtr, <InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpszClass As String, <InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpszWindow As String) As System.IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    ListBox1.Items.Clear()
    Dim hWinList As New List(Of IntPtr)

    'Get Each Explorer Windows Handle
    Dim hWnd As IntPtr = FindWindowExW(IntPtr.Zero, IntPtr.Zero, "CabinetWClass", Nothing)
    While Not hWnd.Equals(IntPtr.Zero)
        hWinList.Add(hWnd)
        hWnd = FindWindowExW(IntPtr.Zero, hWnd, "CabinetWClass", Nothing)
    End While

    'Loop threw each explorer window in the list and get the text from the Address combobox
    If hWinList.Count > 0 Then
        For Each hChld As IntPtr In hWinList
            Dim hChild1 As IntPtr = FindWindowExW(hChld, IntPtr.Zero, "WorkerW", Nothing)
            Dim hChild2 As IntPtr = FindWindowExW(hChild1, IntPtr.Zero, "ReBarWindow32", Nothing)
            Dim hChild3 As IntPtr = FindWindowExW(hChild2, IntPtr.Zero, "ComboBoxEx32", Nothing)
            Dim len As Integer = SendMessage(hChild3, WM_GETTEXTLENGTH, 0, Nothing)
            Dim sb As New StringBuilder(len + 1)
            SendMessage(hChild3, WM_GETTEXT, len + 1, sb)
            ListBox1.Items.Add(sb.ToString)
        Next
    End If

End Sub
_
私有共享函数FindWindowExW(ByVal hwndParent作为System.IntPtr,ByVal hwndChildAfter作为System.IntPtr,ByVal lpszClass作为字符串,ByVal lpszWindow作为字符串)作为System.IntPtr
端函数
_
私有共享函数SendMessage(ByVal hWnd作为IntPtr,ByVal Msg作为UInteger,ByVal wParam作为Integer,ByVal lParam作为StringBuilder)作为Integer
端函数
私有子按钮1\u单击(ByVal sender作为System.Object,ByVal e作为System.EventArgs)处理按钮1。单击
ListBox1.Items.Clear()
Dim hWinList作为新列表(IntPtr)
'获取每个资源管理器窗口句柄
Dim hWnd As IntPtr=FindWindowExW(IntPtr.Zero,IntPtr.Zero,“CabinetWClass”,无)
而不是hWnd.Equals(IntPtr.Zero)
hWinList.Add(hWnd)
hWnd=FindWindowExW(IntPtr.Zero,hWnd,“CabinetWClass”,无)
结束时
'循环抛出列表中的每个资源管理器窗口,并从地址组合框中获取文本
如果hWinList.Count>0,则
对于hWinList中作为IntPtr的每个hChld
尺寸hChild1为IntPtr=FindWindowExW(hChld,IntPtr.Zero,“WorkerW”,无)
尺寸hChild2为IntPtr=FindWindowExW(hChild1,IntPtr.Zero,“ReBarWindow32”,无)
Dim hChild3作为IntPtr=FindWindowExW(hChild2,IntPtr.Zero,“ComboBoxEx32”,无)
Dim len As Integer=SendMessage(hChild3,WM_GETTEXTLENGTH,0,Nothing)
将某人调整为新的StringBuilder(len+1)
SendMessage(hChild3,WM_GETTEXT,len+1,sb)
ListBox1.Items.Add(sb.ToString)
下一个
如果结束
端接头

End Class

这是一个很好的问题,但与python没有太大关系。我正在尝试用python实现它