Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Windows 10中,有没有一种方法可以在不关闭文件资源管理器的情况下以编程方式关闭控制面板?_C#_Windows_Windows 10 - Fatal编程技术网

C# 在Windows 10中,有没有一种方法可以在不关闭文件资源管理器的情况下以编程方式关闭控制面板?

C# 在Windows 10中,有没有一种方法可以在不关闭文件资源管理器的情况下以编程方式关闭控制面板?,c#,windows,windows-10,C#,Windows,Windows 10,在Windows 10中,控制面板不被视为一个单独的进程。它共享可以在任务管理器中看到的文件资源管理器(Explorer)的进程名称和进程id(PID)。因此,在不终止文件资源管理器的情况下,无法以编程方式终止控制面板。是否有命令或代码来完成此操作 我尝试了两种方法 第一个是获取打开窗口的列表,并将window.LocationName与“控制面板”匹配。当我在其中一个设置(例如“System and Security”)内时,这不起作用,因为window.LocationName将更改为“Sy

在Windows 10中,控制面板不被视为一个单独的进程。它共享可以在任务管理器中看到的文件资源管理器(Explorer)的进程名称和进程id(PID)。因此,在不终止文件资源管理器的情况下,无法以编程方式终止控制面板。是否有命令或代码来完成此操作

我尝试了两种方法

第一个是获取打开窗口的列表,并将window.LocationName与“控制面板”匹配。当我在其中一个设置(例如“System and Security”)内时,这不起作用,因为window.LocationName将更改为“System and Security”。以下是代码的要点:

Shell32.Shell shell = new Shell32.Shell();
System.Collections.IEnumerable windows = shell.Windows() as System.Collections.IEnumerable;
if(windows != null) {
  foreach (SHDocVw.InternetExplorer window in windows) {
    object doc = window.Document;
    if (doc != null && doc is Shell32.ShellFolderView) {
      if(window.LocationName== "Control Panel") {
        window.Quit();
}}}}
我尝试的第二种方法是这样的:

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);


IntPtr hWndTargetWindow = FindWindow("CabinetWClass", null);
SendMessage(hWndTargetWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
Environment.Exit(0);
因此,CabinetWClass是explorer的类名,FindWindow()返回指向上次打开的explorer窗口的指针。如果控制面板是最后一个打开的窗口,那么它将成功关闭。但是,如果在控制面板之后打开了一个文件资源管理器窗口,那么首先要关闭的是文件资源管理器,只有在它关闭之后,指针才会指向可以终止的控制面板实例。但我不想关闭“文件资源管理器”窗口

有没有办法通过编程确定控制面板窗口是否打开并终止它?
非常感谢您的帮助

您可以使用
Interop.Shell32.dll
Interop.SHDocVw.dll
实现此类功能

  • 枚举所有
    shell窗口
    ,并过滤掉除
    explorer.exe
    之外的所有对象
  • 从中,您可以看到每个
    文件夹
    都有一个
    标题
    父文件夹
  • 关键是递归查找名为“控制面板”的
    文件夹
    ,该文件夹具有“桌面”父级(
    IsControlPanelRecursive
    函数)。这涵盖了用户打开的“系统和安全”、“电源选项”等子窗口之一的问题
  • 在Win10、x64、英文版上测试

    SHDocVw.InternetExplorer explorerWindow = null;
    
    var shellWindows = new SHDocVw.ShellWindows();
    foreach (var shellWindow in shellWindows)
    {
        try
        {
            if (shellWindow == null)
                continue;
    
            explorerWindow = shellWindow as SHDocVw.InternetExplorer;
    
            if (explorerWindow == null || explorerWindow.Document == null)
                continue;
    
            if (string.IsNullOrWhiteSpace(explorerWindow.FullName))
                continue;                    
    
            var file = Path.GetFileName(explorerWindow.FullName);
    
            if (string.Compare(file, "explorer.exe", true) != 0)
                continue;
    
            var item = ((Shell32.IShellFolderViewDual2)explorerWindow.Document);
    
            if(IsControlPanelRecursive(item.Folder))
                explorerWindow.Quit();
        }
        catch (Exception e)
        {
            // ignore for now.
        }
        finally
        {
            if (explorerWindow != null)
                Marshal.ReleaseComObject(explorerWindow);
        }
    
        if (shellWindows != null)
            Marshal.ReleaseComObject(shellWindows);
    }
    
    bool IsControlPanelRecursive(Folder folder)
    {
        var f = folder;
        do
        {
            // Check if Control Panel is one of the parents
            // + Control's Panel parent is "Desktop"
            if (string.Compare(f.Title, "Control Panel", true) == 0 &&
               f.ParentFolder != null && (string.Compare(f.ParentFolder.Title, "Desktop")==0))
                return true;
            f = f.ParentFolder;
        } while (f != null);
    
        return false;
    }
    

    您可以使用
    Interop.Shell32.dll
    Interop.SHDocVw.dll
    实现此类功能

  • 枚举所有
    shell窗口
    ,并过滤掉除
    explorer.exe
    之外的所有对象
  • 从中,您可以看到每个
    文件夹
    都有一个
    标题
    父文件夹
  • 关键是递归查找名为“控制面板”的
    文件夹
    ,该文件夹具有“桌面”父级(
    IsControlPanelRecursive
    函数)。这涵盖了用户打开的“系统和安全”、“电源选项”等子窗口之一的问题
  • 在Win10、x64、英文版上测试

    SHDocVw.InternetExplorer explorerWindow = null;
    
    var shellWindows = new SHDocVw.ShellWindows();
    foreach (var shellWindow in shellWindows)
    {
        try
        {
            if (shellWindow == null)
                continue;
    
            explorerWindow = shellWindow as SHDocVw.InternetExplorer;
    
            if (explorerWindow == null || explorerWindow.Document == null)
                continue;
    
            if (string.IsNullOrWhiteSpace(explorerWindow.FullName))
                continue;                    
    
            var file = Path.GetFileName(explorerWindow.FullName);
    
            if (string.Compare(file, "explorer.exe", true) != 0)
                continue;
    
            var item = ((Shell32.IShellFolderViewDual2)explorerWindow.Document);
    
            if(IsControlPanelRecursive(item.Folder))
                explorerWindow.Quit();
        }
        catch (Exception e)
        {
            // ignore for now.
        }
        finally
        {
            if (explorerWindow != null)
                Marshal.ReleaseComObject(explorerWindow);
        }
    
        if (shellWindows != null)
            Marshal.ReleaseComObject(shellWindows);
    }
    
    bool IsControlPanelRecursive(Folder folder)
    {
        var f = folder;
        do
        {
            // Check if Control Panel is one of the parents
            // + Control's Panel parent is "Desktop"
            if (string.Compare(f.Title, "Control Panel", true) == 0 &&
               f.ParentFolder != null && (string.Compare(f.ParentFolder.Title, "Desktop")==0))
                return true;
            f = f.ParentFolder;
        } while (f != null);
    
        return false;
    }
    

    您是否可以使用获取所有窗口的句柄,然后根据文本等进行相应过滤。?若要获取关闭所需的单个句柄,可以使用@DavidZemens EnumWindows,前提是我知道窗口标题可以采用的所有可能值。控制面板包含设置和子设置的列表,每个设置都有不同的窗口标题。所以,我不能根据窗口标题进行过滤。控制面板不是一个应用程序,它是一个命名空间扩展。非资源管理器应用程序也可以显示控制面板。您是否可以使用获取所有窗口的句柄,然后根据文本/等进行相应过滤。?若要获取关闭所需的单个句柄,可以使用@DavidZemens EnumWindows,前提是我知道窗口标题可以采用的所有可能值。控制面板包含设置和子设置的列表,每个设置都有不同的窗口标题。所以,我不能根据窗口标题进行过滤。控制面板不是一个应用程序,它是一个命名空间扩展。非浏览器应用程序也可以显示控制面板。