mirror of
https://github.com/amir1376/ab-download-manager.git
synced 2025-02-20 11:43:24 +08:00
improve open folder logic in windows
This commit is contained in:
parent
a654bb846b
commit
b27fc4ec8f
@ -10,4 +10,5 @@ dependencies {
|
||||
api(libs.semver)
|
||||
api(libs.arrow.optics)
|
||||
api("ir.amirab.util:platform:1")
|
||||
implementation(libs.jna.platform)
|
||||
}
|
@ -1,5 +1,10 @@
|
||||
package ir.amirab.util.osfileutil
|
||||
|
||||
import com.sun.jna.Native
|
||||
import com.sun.jna.Pointer
|
||||
import com.sun.jna.platform.win32.*
|
||||
import com.sun.jna.win32.StdCallLibrary
|
||||
import com.sun.jna.win32.W32APIOptions
|
||||
import ir.amirab.util.execAndWait
|
||||
import java.io.File
|
||||
|
||||
@ -9,10 +14,74 @@ internal class WindowsFileUtils : FileUtilsBase() {
|
||||
}
|
||||
|
||||
override fun openFolderOfFileInternal(file: File): Boolean {
|
||||
val nativeSuccess = showFileInFolderViaNative(file.path)
|
||||
if (nativeSuccess) {
|
||||
return true
|
||||
}
|
||||
//fallback to use explorer
|
||||
return execAndWait(arrayOf("cmd", "/c", "explorer.exe", "/select,", file.path))
|
||||
}
|
||||
|
||||
override fun openFolderInternal(folder: File): Boolean {
|
||||
val nativeSuccess = openFolderViaNative(folder.path)
|
||||
if (nativeSuccess) {
|
||||
return true
|
||||
}
|
||||
//fallback to use explorer
|
||||
return execAndWait(arrayOf("cmd", "/c", "explorer.exe", folder.path))
|
||||
}
|
||||
|
||||
private fun showFileInFolderViaNative(
|
||||
file: String,
|
||||
): Boolean {
|
||||
Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_APARTMENTTHREADED)
|
||||
val path = Shell32Ex.INSTANCE.ILCreateFromPath(File(file).parent)
|
||||
val selectedFiles = arrayOf(Shell32Ex.INSTANCE.ILCreateFromPath(file))
|
||||
val cidl = WinDef.UINT(selectedFiles.size.toLong())
|
||||
try {
|
||||
val res = Shell32Ex.INSTANCE.SHOpenFolderAndSelectItems(
|
||||
pIdlFolder = path,
|
||||
cIdl = cidl,
|
||||
apIdl = selectedFiles,
|
||||
dwFlags = WinDef.DWORD(0)
|
||||
)
|
||||
return WinError.S_OK == res
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
} finally {
|
||||
Shell32Ex.INSTANCE.ILFree(path)
|
||||
selectedFiles.forEach {
|
||||
Shell32Ex.INSTANCE.ILFree(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun openFolderViaNative(folder: String): Boolean {
|
||||
try {
|
||||
val result = Shell32.INSTANCE.ShellExecute(
|
||||
null, "explore", folder, null, null, WinUser.SW_NORMAL,
|
||||
).toInt()
|
||||
return result > 32
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private interface Shell32Ex : StdCallLibrary {
|
||||
fun ILCreateFromPath(path: String?): Pointer?
|
||||
fun ILFree(pIdl: Pointer?)
|
||||
fun SHOpenFolderAndSelectItems(
|
||||
pIdlFolder: Pointer?,
|
||||
cIdl: WinDef.UINT?,
|
||||
apIdl: Array<Pointer?>?,
|
||||
dwFlags: WinDef.DWORD?,
|
||||
): WinNT.HRESULT?
|
||||
|
||||
companion object {
|
||||
val INSTANCE: Shell32Ex = Native.load("shell32", Shell32Ex::class.java, W32APIOptions.DEFAULT_OPTIONS)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user