首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >处理注册表中的TypeGuessRows

处理注册表中的TypeGuessRows
EN

Stack Overflow用户
提问于 2021-05-17 17:30:06
回答 1查看 1.5K关注 0票数 1

我有一个VB.net应用程序,它需要读写Excel工作簿,使用OLEDB和数据库驱动程序。随着时间的推移,我在StackOverflow上学到了大量的东西,这使我能够让一切都按应有的方式工作。这些主题涵盖了从连接字符串到“魔术”TypeGuessRows设置/255个字符限制(现在位于注册表中)的所有内容。随着时间的推移,由于多年来微软的发展,这个问题本身已经发生了变化,所以我不会引用这些(数百?数千人?)这里的帖子。只需说一句,我就能把它拼凑在一起,让它发挥作用。

供参考:我的连接字符串如下所示:

代码语言:javascript
运行
复制
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='@DBQ';Extended Properties='Excel 12.0 Xml;HDR=YES';"

其中'@DBQ‘在运行时被所选Excel工作簿的适当路径名替换。注意,它不包含TypeGuessRows (因为它已经移到注册表了),而且IMEX=(不管什么)也不起作用,所以它不会出现。其结果是,只要TYPEGUESSROWS在注册表中设置为零,一切都运行得很好。

使用regedit在所有事件中手动搜索和设置TypeGuessRows=0 (我在StackOverflow上了解到的事情之一),这已经成功并完全避免了255-char截断。

问题是,每当有Windows更新时,它就会被设置为默认值8。没有警告或通知;只有当我开始看到“截断到255个字符”的症状再次出现时,我才知道这一点。因此,我必须返回并再次使用RegEdit。

显而易见的解决方案是,应用程序自己做这个设置,但这似乎需要操纵安全功能,这是我宁愿完全避免的事情,因为它似乎比我现在想要处理的更复杂。

因此,我想,“为什么不直接扫描适当的注册表项,如果它们不是零就报告”,然后向用户发出一条消息,以便使用regedit对其进行排序。

我编写了以下函数,它查看我找到的所有包含TypeGuessRows的各种注册表项:

代码语言:javascript
运行
复制
    Public Function CheckRegistry() As Integer
    Dim Val1 As Integer = 0, Val2 As Integer = 0
    Dim KeysToCheck As String() = New String() {
       "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Jet\4.0\Engines\Excel",
       "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Jet\4.0\Engines\Lotus",
       "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel",
       "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Excel"
        }
    '
    '   try two methods for checking the registry values.
    '
    '   method 1 uses the My.Computer class
    '
    For Each Key As String In KeysToCheck
        Dim aVal As Object = My.Computer.Registry.GetValue(Key, "TypeGuessRows", CType("BOGUS", Object))
        If IsNothing(aVal) Then                         ' did we hit Nothing?
            Continue For                                ' have to skip it
        ElseIf aVal.Equals(CType("BOGUS", Object)) Then ' did we hit one not exist?
            Val1 = -9999                                ' set a crazy value
        End If
        Val1 += CInt(aVal)                              ' otherwise, get its value and add to total
    Next
    '
    '   method 2 uses the RegistryKey class
    '
    Dim aKey As Microsoft.Win32.RegistryKey
    For Each Key As String In KeysToCheck
        Dim LM As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine   ' point to HKLM
        Key = Key.TrimStart("HKEY_LOCAL_MACHINE\".ToCharArray)                          ' peel off the start (a convenience)
        aKey = LM.OpenSubKey(Key, Microsoft.Win32.RegistryKeyPermissionCheck.ReadSubTree)   ' try to read the subkey
        If IsNothing(aKey) Then Continue For                                            ' did we hit Nothing?  have to skip it
        'If CInt(aKey.GetValue("TypeGuessRows", 0)) <> 0 Then aKey.SetValue("TypeGuessRows", 0)
        Val2 += CInt(aKey.GetValue("TypeGuessRows", 0))                                 ' otherwise, get its value and add to total
    Next
    Return Val1 + Val2                                  ' return the sum of both methods
End Function

这是很好的工作,除了最后一个,一个“...ClickToRun.”用钥匙的名字。无论如何,这总是以零形式返回,所以检查它的尝试失败了。即使在第一种方法中,我特别要求它返回一个“假”对象,但它总是作为空值返回。

问题是通过Windows更新的是这个键。到目前为止,我还从未见过其他三人中的任何一个被重置。

如果我“遍历此键的树”(即,尝试查看"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office"),,它可以正常工作,直到我到达ClickToRun分支,此时它将什么也不返回。

我想我有两个问题:

  1. 是否有办法读取此密钥,使其不作为空值返回?
  2. 能提供一个指南(希望不会太混乱/复杂),以使安全设置正确,以便允许"ReadWriteSubTree“进行权限检查?注:如果我现在尝试,我得到了安全例外,告诉我,应用程序没有适当的许可。这就是为什么aKey.SetValue行被注释掉的原因。

进一步信息:这台机器是Win 10 Pro,64位,安装了适当的驱动程序.该应用程序被设置为“启用ClickToRun安全设置”和“完全信任应用程序”。我已经在app.manifest中使用了这些设置和适当的条目,但是到目前为止,这只会在其他地方造成(很多)其他的悲伤和困难。所以我才不想搞砸。

任何帮助都会很感激的。

EN

回答 1

Stack Overflow用户

发布于 2021-05-18 03:25:14

睡了一觉,再想一想,特别是这里的一些暗示

Reading 64bit Registry from a 32bit application我至少能够读取注册表项。问题是,我试图从我的32位应用程序中“读取”64位注册表项。

现在,我可以做我真正想做的事情,即检测TypeGuessRows问题何时再次出现,并警告用户对此做些什么。

以下是修改后的代码:

代码语言:javascript
运行
复制
    Public Function CheckRegistry() As Integer
    Dim CheckVal As Integer = 0
    Dim KeysToCheck As String() = New String() {
       "SOFTWARE\WOW6432Node\Microsoft\Jet\4.0\Engines\Excel",
       "SOFTWARE\WOW6432Node\Microsoft\Jet\4.0\Engines\Lotus",
       "SOFTWARE\WOW6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel",
       "SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Excel"
        }

    Dim LMachine As Microsoft.Win32.RegistryKey =
        Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine,
        Microsoft.Win32.RegistryView.Registry64)

    Dim LKey As Microsoft.Win32.RegistryKey
    For Each Key As String In KeysToCheck
        Try
            LKey = LMachine.OpenSubKey(Key, Microsoft.Win32.RegistryKeyPermissionCheck.ReadSubTree)
            CheckVal += CInt(LKey.GetValue("TypeGuessRows", 0))
        Catch ex As Exception
            LMachine.Close()
            Return -9999
        End Try
    Next
    LMachine.Close()
    Return CheckVal
End Function

在测试中,它可以成功地检查显示的所有四个键。试捕从来没有被发射过,但我还是为了安全而离开了那里。

我希望其他人可能会发现这是有用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67574449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档