复制Windows取消隐藏文件夹和文件功能

时间:2015-08-26 19:19:36

标签: vb.net windows show-hide

我正在重新访问我在VB.Net中为我的帮助台团队编写的工具,并希望添加一些复选框来复制Windows用来显示隐藏文件和文件夹的相同功能隐藏,以及受保护的操作系统文件。

我知道我可以通过编辑注册表项并重新启动explorer.exe来执行此操作,但这会关闭所有打开的资源管理器Windows,我不希望这样。

有没有人知道Windows是如何通过单击复选框以及如何在VB.net中对其进行编码来实现此目的的?

对此的任何意见都提前了解。

编辑:所以看起来我找到了一个刷新方法,可以刷新Windows资源管理器/文件资源管理器,可以应用于 Drarig的答案,但我无法将其转换为VB.net因为最初的例子是C#。

'Original at http://stackoverflow.com/questions/2488727/refresh-windows-explorer-in-win7

Private Sub refreshExplorer(ByVal explorerType As String)
    Dim CLSID_ShellApplication As Guid = Guid.Parse("13709620-C279-11CE-A49E-444553540000")
    Dim shellApplicationType As Type = Type.GetTypeFromCLSID(CLSID_ShellApplication, True)
    Dim shellApplication As Object = Activator.CreateInstance(shellApplicationType)
    Dim windows As Object = shellApplicationType.InvokeMember("Windows", Reflection.BindingFlags.InvokeMethod, Nothing, shellApplication, New Object() {})
    Dim windowsType As Type = windows.GetType()
    Dim count As Object = windowsType.InvokeMember("Count", Reflection.BindingFlags.GetProperty, Nothing, windows, Nothing)

    For i As Integer = 0 To CType(count, Integer)
        Dim item As Object = windowsType.InvokeMember("Item", Reflection.BindingFlags.InvokeMethod, Nothing, windows, New Object() {i})
        Dim itemType As Type = item.GetType()

        'Only fresh Windows explorer Windows
        Dim itemName As String = CType(itemType.InvokeMember("Name", Reflection.BindingFlags.GetProperty, Nothing, item, Nothing), String)
        If itemName = explorerType Then
            itemType.InvokeMember("Refresh", Reflection.BindingFlags.InvokeMethod, Nothing, item, Nothing)
        End If
    Next
End Sub

当我将 itemType设置为Type = item.GetType() 对象引用未设置为对象的实例 >上面。我无法弄清楚哪个对象没有被创建。当我单步执行代码时, windowsType 包含 windows 的对象。有没有人对此有任何想法?一旦解决了这个问题,我就可以将它应用到下面的Drarig解决方案中。

2 个答案:

答案 0 :(得分:1)

好吧,我希望我能尽早得到你,但最近很忙于工作。今天我花了一点时间来弄清楚这一点,因为我喜欢挖掘我之前没有做过的事情。这是一个新项目的全班;没有时间把它包装在一个单独的课堂上。我相信这会得到你所需要的。它比我想象的更难获得正确的句柄然后发送命令,但我得到了它。我希望你觉得它很有用。

P.S。你可以遗漏一些东西,特别是用于加载的布尔值,这样我就可以在加载时拉回当前值,并选中/取消选中Imports Microsoft.Win32 Imports System.Reflection Imports System.Runtime.InteropServices Public Class Form1 <Flags()> _ Public Enum KeyboardFlag As UInteger KEYBOARDF_5 = &H74 End Enum <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Private Shared Function GetWindow(ByVal hl As Long, ByVal vm As Long) As IntPtr End Function <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Private Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Boolean End Function <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr End Function Private blnLoading As Boolean = False Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged Form1.HideFilesExtension(Me.CheckBox1.Checked) If Not blnLoading Then NotifyFileAssociationChanged() RefreshExplorer() End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim name As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey(name, False) blnLoading = True Me.CheckBox1.Checked = CBool(key.GetValue("Hidden")) key.Close() blnLoading = False End Sub Private Shared Sub HideFilesExtension(ByVal Hide As Boolean) Dim name As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey(name, True) key.SetValue("Hidden", If(Hide, 1, 0)) key.Close() End Sub Public Shared Sub RefreshExplorer() Dim clsid As New Guid("13709620-C279-11CE-A49E-444553540000") Dim typeFromCLSID As Type = Type.GetTypeFromCLSID(clsid, True) Dim objectValue As Object = Activator.CreateInstance(typeFromCLSID) Dim obj4 As Object = typeFromCLSID.InvokeMember("Windows", BindingFlags.InvokeMethod, Nothing, objectValue, New Object(0 - 1) {}) Dim type1 As Type = obj4.GetType Dim obj2 As Object = type1.InvokeMember("Count", BindingFlags.GetProperty, Nothing, obj4, Nothing) If (CInt(obj2) <> 0) Then Dim num2 As Integer = (CInt(obj2) - 1) Dim i As Integer = 0 Do While (i <= num2) Dim obj5 As Object = type1.InvokeMember("Item", BindingFlags.InvokeMethod, Nothing, obj4, New Object() {i}) Dim type3 As Type = obj5.GetType Dim str As String = CStr(type3.InvokeMember("Name", BindingFlags.GetProperty, Nothing, obj5, Nothing)) If (str = "File Explorer") Then type3.InvokeMember("Refresh", BindingFlags.InvokeMethod, Nothing, obj5, Nothing) End If i += 1 Loop End If End Sub Public Shared Sub NotifyFileAssociationChanged() 'Find the actual window... Dim hwnd As IntPtr = FindWindow("Progman", "Program Manager") 'Get the window handle and refresh option... Dim j = GetWindow(hwnd, 3) 'Finally post the message... PostMessage(j, 256, KeyboardFlag.KEYBOARDF_5, 3) End Sub End Class

注意:这是在Windows 7,8和10

上试用和测试的
filter.size

答案 1 :(得分:-1)

除了探索者的清新之外,这里还有解决方案。 我已经翻译了代码,但是我无法在不重新启动的情况下找到如何刷新资源管理器/桌面。

Const keyName As String = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Const Hidden As String = "Hidden"
Const SHidden As String = "ShowSuperHidden"

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim St As Integer = GetRegValue(Hidden)

    If St = 2 Then
        SetRegValue(Hidden, 1)
        SetRegValue(SHidden, 1)
    Else
        SetRegValue(Hidden, 2)
        SetRegValue(SHidden, 0)
    End If
End Sub

Private Function GetRegValue(valueName As String) As Integer
    Return CInt(My.Computer.Registry.GetValue(keyName, valueName, 0))
End Function

Private Sub SetRegValue(valueName As String, value As Integer)
    My.Computer.Registry.SetValue(keyName, valueName, value, Microsoft.Win32.RegistryValueKind.DWord)
End Sub

我有一些想法来刷新桌面:

  • 将密钥发送到正在运行的进程。我试过这个(source):

    Dim pp As Process() = Process.GetProcessesByName("explorer")
    
    If pp.Length > 0 Then
        For Each p In pp
            AppActivate(p.Id)
            SendKeys.SendWait("{F5}")
        Next
    End If
    
    • 使用SHChangeNotifysource),
    • 进行刷新
    • 刷新广播WM_SETTINGCHANGE消息(source),

我认为您将被迫手动刷新或重新启动资源管理器。