窗口浏览器打开时冻结

时间:2020-10-19 04:05:34

标签: vb.net

我需要打开文件的特定文件夹,并且要使用:

file = Directory.GetFiles(filepath,Filename,
                          SearchOption.AllDirectories).FirstOrDefault()

   Process.Start("explorer.exe", "/select," & file.ToString)

此代码立即打开已经完全加载的文件夹,但似乎没有启用,请注意我无法在其中执行任何操作。表格不冻结。 谢谢

2 个答案:

答案 0 :(得分:2)

我将分两部分给您一个答案...

首先,如果GetFiles()调用花费很长时间并冻结了表单(这似乎不是当前的问题),则应执行以下操作:

  • 请改用EnumerateFiles(),因为在这种情况下,FirstOrDefault()将在找到匹配文件后立即返回,而不像GetFiles()会在调用{{1 }}。

  • 将对调用FirstOrDefault()的调用包装在EnumerateFiles()中,以在工作线程上执行该调用,以防搜索花费太长时间:

    Task.Run()

第二,不要使用' Or: ' Private Async Sub SomeEventHandler() Private Async Function ParentMethod() As Task Dim filePath As String = Await Task.Run( Function() Return Directory.EnumerateFiles(dirPath, FileName, SearchOption.AllDirectories). FirstOrDefault() End Function) ' TODO: Use `filePath` to open the folder and select the file. End Function ,因为a)它会启动一个 new Explorer.exe进程,而不是在当前目录中打开该目录,b)它似乎导致您问题,以及c)it has some limitations

相反,请使用上面(c)点链接的答案中演示的方法。该代码在C#中,但可以轻松转换为VB。这是代码的VB版本(带有额外的重载)。

将以下类添加到您的项目中:

Process.Start("explorer.exe", "/select")

然后,您可以像这样轻松地调用它:

Imports System.IO
Imports System.Runtime.InteropServices

Public Class NativeMethods
    <DllImport("shell32.dll", SetLastError:=True)>
    Private Shared Function SHOpenFolderAndSelectItems(
            pidlFolder As IntPtr, cidl As UInteger,
            <[In], MarshalAs(UnmanagedType.LPArray)> apidl As IntPtr(),
            dwFlags As UInteger) As Integer
    End Function

    <DllImport("shell32.dll", SetLastError:=True)>
    Private Shared Sub SHParseDisplayName(
            <MarshalAs(UnmanagedType.LPWStr)> name As String,
            bindingContext As IntPtr, <Out> ByRef pidl As IntPtr,
            sfgaoIn As UInteger, <Out> ByRef psfgaoOut As UInteger)
    End Sub

    Public Shared Sub OpenFolderAndSelectFile(filePath As String)
        Dim dirPath As String = Path.GetDirectoryName(filePath)
        Dim fileName As String = Path.GetFileName(filePath)
        OpenFolderAndSelectFile(dirPath, fileName)
    End Sub

    Public Shared Sub OpenFolderAndSelectFile(dirPath As String, fileName As String)
        Dim nativeFolder As IntPtr
        Dim psfgaoOut As UInteger
        SHParseDisplayName(dirPath, IntPtr.Zero, nativeFolder, 0, psfgaoOut)

        If nativeFolder = IntPtr.Zero Then
            ' Log error, can't find folder
            Return
        End If

        Dim nativeFile As IntPtr
        SHParseDisplayName(Path.Combine(dirPath, fileName),
                           IntPtr.Zero, nativeFile, 0, psfgaoOut)

        Dim fileArray As IntPtr()
        If nativeFile = IntPtr.Zero Then
            ' Open the folder without the file selected if we can't find the file
            fileArray = New IntPtr(-1) {}
        Else
            fileArray = New IntPtr() {nativeFile}
        End If

        SHOpenFolderAndSelectItems(nativeFolder, CUInt(fileArray.Length), fileArray, 0)

        Marshal.FreeCoTaskMem(nativeFolder)
        If nativeFile <> IntPtr.Zero Then
            Marshal.FreeCoTaskMem(nativeFile)
        End If
    End Sub
End Class

一些附加说明:

  • 您应该选择有意义的变量名。 NativeMethods.OpenFolderAndSelectFile(filePath) 应该引用文件的路径。如果要引用文件夹/目录路径,请改用filePathdirPath之类的东西。

  • 您不需要在已经为folderPath类型的变量上调用.ToString()

答案 1 :(得分:0)

我将变量名 public async Task CreateFacilityFixed(CreateFacilityFixedInput input){ var FacilityFixed = ObjectMapper.Map<FacilityFixed>(input); await _FacilityFixedRepository.InsertAsync(FacilityFixed); } 更改为其他名称。也许file。毕竟File是System.IO中类的名称,而vb.net不区分大小写。您的代码对我来说很好,因为变量名更改了。也摆脱了foundFile。 @jmcilhinney在您删除的问题中使用了.ToString。我特意选择了一条路径,其中包含各种奇怪的字符,并且仍然有效。

.EnumerateFiles