使用C#获取已注册文件(DLL/EXE/OCX)的注册时间
嘿,我懂你现在的处境——已经搞定了文件是否注册的验证,但卡在拿不到注册的具体日期时间上,对吧?别慌,我给你整理几个实用的方法,适配不同的场景,你可以根据自己的代码环境挑着用。
Windows注册表的每个项本身都带有最后修改时间戳,如果你的应用在注册文件时会创建或修改对应的注册表项,那这个时间戳完全可以当作注册时间来用。
举个例子,假设你检查的是HKEY_CLASSES_ROOT\CLSID\{...}这类COM注册项,或者应用专属的注册路径,你可以通过系统工具或代码读取这个项的LastWriteTime属性:
如果用PowerShell,代码大概是这样:
$regPath = "HKLM:\SOFTWARE\YourApp\RegisteredFiles\YourFile.dll" $regItem = Get-Item -Path $regPath $registrationTime = $regItem.LastWriteTime Write-Host "注册时间:$registrationTime"
如果用C#,可以借助Microsoft.Win32.RegistryKey类,配合Windows原生API实现:
using Microsoft.Win32; using System; using System.Runtime.InteropServices; class RegistryTimeReader { static void Main() { string regPath = @"SOFTWARE\YourApp\RegisteredFiles\YourFile.dll"; using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regPath)) { if (key != null) { DateTime regTime = GetRegistryKeyLastWriteTime(key); Console.WriteLine($"注册时间:{regTime}"); } } } // 调用Windows原生API获取注册表项最后修改时间 [DllImport("advapi32.dll", SetLastError = true)] private static extern int RegQueryInfoKey( IntPtr hKey, StringBuilder lpClass, ref uint lpcbClass, IntPtr lpReserved, out uint lpcSubKeys, out uint lpcbMaxSubKeyLen, out uint lpcbMaxClassLen, out uint lpcValues, out uint lpcbMaxValueNameLen, out uint lpcbMaxValueLen, out uint lpcbSecurityDescriptor, out long lpftLastWriteTime); private static DateTime GetRegistryKeyLastWriteTime(RegistryKey key) { long lastWriteTime; RegQueryInfoKey(key.Handle, null, ref 0u, IntPtr.Zero, out _, out _, out _, out _, out _, out _, out _, out lastWriteTime); return DateTime.FromFileTime(lastWriteTime); } }
小提示:有些情况下,.NET的
RegistryKey不会直接暴露LastWriteTime,这时候调用原生的RegQueryInfoKeyAPI是最可靠的方式,上面的C#代码已经包含了这个逻辑。
不少应用会在注册表中专门写入一个键值对来记录文件的注册时间,比如RegistrationDate、InstalledTime这类字段。你可以先去目标注册表路径里看看有没有这类自定义的时间记录,如果有的话直接读取就行,这比读注册表项的修改时间更精准。
比如注册表项可能长这样:
[HKEY_LOCAL_MACHINE\SOFTWARE\YourApp\RegisteredFiles\YourFile.dll] "RegistrationTime"="2024-05-20 14:30:00"
这种情况下直接读取RegistrationTime的值就完事了,简单又准确。
如果上面两种方法都走不通,你可以试试检查文件本身的创建时间或最后修改时间——前提是应用在注册文件时会修改文件(比如写入注册标记),或者文件是在注册过程中被复制到目标路径的。
用PowerShell实现的话:
$filePath = "C:\Program Files\YourApp\YourFile.dll" $fileInfo = Get-Item -Path $filePath $createTime = $fileInfo.CreationTime $modifyTime = $fileInfo.LastWriteTime Write-Host "文件创建时间:$createTime`n最后修改时间:$modifyTime"
假设你现在是循环处理预期文件列表,你可以把获取注册时间的逻辑直接嵌入循环中,比如用PowerShell写的伪代码:
# 你的预期文件列表 $expectedFiles = @("File1.dll", "File2.exe", "File3.ocx") # 注册表中注册文件的基础路径 $regBasePath = "HKLM:\SOFTWARE\YourApp\RegisteredFiles" foreach ($file in $expectedFiles) { $regPath = Join-Path -Path $regBasePath -ChildPath $file if (Test-Path -Path $regPath) { # 验证文件已注册 Write-Host "$file 已完成注册" # 获取并输出注册时间 $regItem = Get-Item -Path $regPath $regTime = $regItem.LastWriteTime Write-Host " 注册时间:$regTime" } else { Write-Host "$file 未注册,请检查安装流程" } }
内容的提问来源于stack exchange,提问作者KR Akhil

