使用Java打开文件的属性窗口

时间:2016-09-14 10:28:45

标签: java windows file properties

这只是关于Windows中Java的问题。

我需要一个调用此窗口的方法:

enter image description here

所以基本上这个方法应该是这样的:

public void openProperties(File file){ // or String fileName

}

声明:opernProperties(new File(test.txt));应该打开上面的窗口。

所以只是为了澄清,我不想阅读和管理这些属性。我只是想打开属性窗口。

2 个答案:

答案 0 :(得分:2)

我能够使用以下内容显示文件属性窗口:

这应该显示属性窗口,延迟为3秒。请注意,如果你不希望它在3秒后自动关闭,则会谈到将窗口传递给hwnd成员

public static void main(String[] args) throws InterruptedException {
        ShellAPI.SHELLEXECUTEINFO shellExecuteInfo = new ShellAPI.SHELLEXECUTEINFO();
        shellExecuteInfo.lpFile = "C:\\setup.log";
        shellExecuteInfo.nShow = User32.SW_SHOW;
        shellExecuteInfo.fMask = 0x0000000C;
        shellExecuteInfo.lpVerb = "properties";
        if (Shell32.INSTANCE.ShellExecuteEx(shellExecuteInfo)){
            Thread.sleep(3000);
        }
    }

答案 1 :(得分:0)

Windows API 调用 SHObjectProperties 还将启动 Windows 文件属性对话框。您可以从 JNA、JNI 调用或尝试这个使用 JDK Panama / Foreign Memory Early Access JDK17 的孵化器版本的示例:

// %JAVAHOME%\bin\java --enable-native-access=ALL-UNNAMED --add-modules jdk.incubator.foreign -cp your.jar ShowProperties C:\Temp

import static jdk.incubator.foreign.CLinker.*;
import jdk.incubator.foreign.*;
import java.lang.invoke.*;
public class ShowProperties {
    private static final CLinker CLINKER = CLinker.getInstance();
    private static final SymbolLookup LOADER = SymbolLookup.loaderLookup();
    static {
        System.loadLibrary("shell32");
        System.loadLibrary("kernel32");
    }
    static MemorySegment toCString(String s, Charset charset, SegmentAllocator allocator) {
        var bytes = s.getBytes(charset);
        // Put it in a MemorySegment with extra termination \0
        MemorySegment fixed = allocator.allocate(bytes.length + 4);
        fixed.copyFrom(MemorySegment.ofArray(bytes));
        return fixed;
    }
    // https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shobjectproperties
    private static final MethodHandle SHObjectProperties = CLINKER.downcallHandle(
            LOADER.lookup("SHObjectProperties").get()
            , MethodType.methodType(int.class, MemoryAddress.class, int.class, MemoryAddress.class, MemoryAddress.class)
            , FunctionDescriptor.of(C_LONG,    C_POINTER,           C_INT,     C_POINTER,           C_POINTER));

    private static void showProperties(List<Path> paths) throws Throwable {
        try(ResourceScope scope = ResourceScope.newConfinedScope())  {
            SegmentAllocator allocator = SegmentAllocator.arenaAllocator(scope);
            for (Path path : paths) {
                MemorySegment pszObjectName = toCString(path.toString(), StandardCharsets.UTF_16LE, allocator);
                int hres = (int)SHObjectProperties.invokeExact(/*hWnd*/MemoryAddress.NULL.address(), /*SHOP_FILEPATH*/2, pszObjectName.address(), /*pszPropertyPage*/MemoryAddress.NULL.address());
                System.out.println("SHObjectProperties path="+path +" hres="+hres);
            }
        }
    }

    public static void main(String[] args) throws Throwable {
        List<Path> paths = Arrays.stream(args).map(Path::of).map(Path::toAbsolutePath).collect(Collectors.toList());
        showProperties(paths);

        // Properties dialogs close when the this app exits
        Thread.sleep(15000);
    }
}