我需要打开文件的特定文件夹,并且要使用:
file = Directory.GetFiles(filepath,Filename,
SearchOption.AllDirectories).FirstOrDefault()
Process.Start("explorer.exe", "/select," & file.ToString)
此代码立即打开已经完全加载的文件夹,但似乎没有启用,请注意我无法在其中执行任何操作。表格不冻结。 谢谢
答案 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)
应该引用文件的路径。如果要引用文件夹/目录路径,请改用filePath
或dirPath
之类的东西。
您不需要在已经为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