不要使用命令行新建explorer进程的方式打开文件夹或文件

打开windows后,系统默认启动一个explorer进程。然后还可以使用命令行启动新的explorer。

命令行启动explorer一般用于打开网页或文件夹,也用于以默认程序打开文件。但是新建explorer打开文件夹或文件时,这个进程不会自动退出,也不能在父进程强制关闭。多次操作后,一些低配的电脑就会卡死。explorer用于打开网页时,测试用的浏览器为360浏览器时,退出浏览器后半分钟,explorer会自动退出。目前的测试认为explorer只适合打开网页。

如果是为了打开网页,新建的explorer仍然无法在父进程中强制关闭。稍具规模的程序最好是能自带一个免安装的浏览器,用自带的浏览器去启动网页,以实现进程可控。

eclipse和早期的一些下载工具有新建explorer的操作。现在的迅雷、360下载、edge打开下载目录已经不再需要新建explorer进程了。

如果要在自己的程序中打开文件夹,可以考虑使用explorer++开源工具。或向专业人员咨询如何在不新建explorer进程的情况下打开文件夹。

一种打开文件夹而不用新建explorer进程的方法是调用ShellExecute函数。比如:

HINSTANCE ins = ShellExecute(NULL,//hwnd句柄,因为在Java中调用,没有hwnd,所以只能填NULL
            "explore", // 对于文件夹,这里可以使用"explore"或"open"两种操作。使用"explore"会自动展开左边的文件夹树状图定位到此文件夹,使用"open"则不会。
            "d:/lab",//这个是要打开的文件夹
            NULL,//这个是执行参数,对于打开文件夹的操作,该处随便填字符串,因为没有效果
            NULL,//工作路径,对于打开文件夹的操作,这里随便填字符串,没有效果
            SW_NORMAL);//SW_前缀的宏,一般使用SW_NORMAL或SW_MAXIMIZE,对应还原和最大化。

第2个形参的简介:

"open":寻找已经打开的资源管理器窗口,如果找到,就将此容器前置,如果没找到,就新建窗口。不会改变文件夹树状图。

"explore":总是新建窗口,即使已经有了一样路径的窗口,也还是会新建。新建的窗口的文件夹树状图会自动展开并定位到此路径的位置。

但是这个函数不能在打开的文件夹内选中某个文件。函数是Win32 API函数,在<window.h>中。如果使用其它编程语言,则需要做对应的连接,最终调用此函数。

文件定位我是用的AWT的Robot类。先取出文件夹下的所有子文件和文件夹,使用File.listFiles()方法可以取得所有下级路径,但它并不是按文件夹在前、文件在后的方式排序的。还需要用Colloctions.sort方法进行一次排序。

import pers.laserpen.util.file.FileSearcher;
import pers.laserpen.util.java.StaticJavaUtils;
import pers.laserpen.util.process.NativeProcessUtils;
import pers.laserpen.util.process.NativeProcessUtils.ShellExecuteOperator;
import pers.laserpen.util.process.NativeProcessUtils.ShellExecuteShowWindow;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class TestShellExecute {
	public static void main(String[] args) throws AWTException {
		StaticJavaUtils.loadAllJniLibaries(new File("./lib/jni"));

		FileSearcher fs = new FileSearcher(new File("."));
		File f = fs.searchNextFile("*.png");
		if (f == null) {
			System.err.println("not any png");
			return;
		}
		System.out.println(f);
        // 调用win32 API函数ShellExecute。由于JNI的hwnd只能填NULL,我在JNI中把hwnd参数省略了。
		String res = NativeProcessUtils.shellExecute(
				ShellExecuteOperator.open,//不会自动扩展文件夹树状图
				f.getParentFile(),//打开这个文件的目录
				null,//在JNI中处理成NULL
				null,//在JNI中处理成NULL
				ShellExecuteShowWindow.SW_NORMAL);//常规尺寸打开

        // 取得所有子路径,文件夹和文件混在一起
		List<File> fileList = Arrays.asList(f.getParentFile().listFiles());
        // 排序,这个排序方法不完美,只适用于路径名中不含多位数字的路径
		Collections.sort(fileList, (a, b) -> {
			if(a.isDirectory()) {
				if(b.isDirectory()) {
					return a.compareTo(b);
				}else {
					return -1;
				}
			}else {
				if(b.isDirectory()) {
					return 1;
				}else {
					return a.compareTo(b);
				}
			}
		});
		System.out.println(fileList);
        // 假设你用了正确的排序方法,那么这个index就是windows资源管理器界面上的顺序
		int index = fileList.indexOf(f);
        // 按这么多次下方向键,其实index为0的时候就会失效,只是做个试验,就不搞那么完整了
		Robot robot = new Robot();
		robot.delay(100);
		for (int i = 0; i < index; ++i) {
			robot.keyPress(KeyEvent.VK_DOWN);
			robot.keyRelease(KeyEvent.VK_DOWN);
		}
        
		System.out.println(res);
	}
}

需要Java和C联用。如果使用其它编程语言,也会有联用的问题。所以不适合C/C++以外的新手使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值