GetWindowsDirectory() API 返回错误 (vba\vb6)
Posted
技术标签:
【中文标题】GetWindowsDirectory() API 返回错误 (vba\\vb6)【英文标题】:GetWindowsDirectory() API returns wrong (vba\vb6)GetWindowsDirectory() API 返回错误 (vba\vb6) 【发布时间】:2015-06-16 07:56:55 【问题描述】:在我的 Windows-Terminal 用户上,我试图让两个应用程序指向同一个 Windows 目录,一个用 VBA 编写,一个用 VB6 编写。
当从 VB6 调用 GetWindowsDirectory() API 时,它会返回正确的路径
C:\documents and settings\%user%\Windows
从VBA宏调用时,返回
C:\Windows
请注意,GetSystemWindowsDirectory() 的结果相同
可能是 VBA 代码不知道它是一个终端站,我调用了 GetSystemMetrics(SM_REMOTESESSION)
API 返回 1,这意味着它知道它是一个终端。
在 VB6 和 VBA 中使用完全相同的代码
Windows 2003R2,Office 版本是 2010 64bit(当我输入这个时,我想知道它是否相关,知道 vb6 是 32bit ...)
有什么想法吗?
编辑:如下 IInspectable 所述,vba 和 vb6 之间的区别在于 vb6 不像 Office 那样具有终端服务意识。
【问题讨论】:
"This function is provided primarily for compatibility with legacy applications."。你想做什么?用FOLDERID_Windows
代替SHGetKnownFolderPath
。
我的意思是“你期望什么”?什么是“同一个 Windows 目录”?你是说windows的安装目录吗?请参阅上面的更新评论。
GetWindowsDirectory: "如果应用程序是终端服务感知的(在图像标题中设置了 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 标志),此函数返回的路径系统 Windows 目录,就像 GetSystemWindowsDirectory 函数一样。否则,它会为用户检索私有 Windows 目录的路径。"
@CodeCaster SHGetKnownFolderPath 返回 **C:\Windows ** .. CreateObject("Shell.Application").Namespace(ssfWINDOWS).Self.Path
“有什么想法吗?” 不应该在 SO 上提出问题。我将您最初的问题解释为:“为什么结果不同?” 和answered。也不建议更新问题以提出不同的问题。如果您还有其他问题,请改用ask a new question。
【参考方案1】:
您所观察到的行为已记录在案。查看GetWindowsDirectory的备注部分:
终端服务:如果应用程序在终端服务环境中运行,每个用户都有一个私有的 Windows 目录。系统还有一个共享的 Windows 目录。如果应用程序是终端服务感知的(在图像标题中设置了 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 标志),则此函数返回系统 Windows 目录的路径,就像 GetSystemWindowsDirectory 函数一样。否则,它会为用户检索私有 Windows 目录的路径。
带有/HEADERS 选项的DUMPBIN 工具可用于验证是否为二进制文件设置了IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 标志。
dumpbin /HEADERS WINWORD.EXE
产生以下输出(Microsoft Office 2013 32 位):
OPTIONAL HEADER VALUES
10B magic # (PE32)
...
2 subsystem (Windows GUI)
8140 DLL characteristics
Dynamic base
NX compatible
Terminal Server Aware
...
换句话说:Microsoft Office 支持终端服务,从托管在 Microsoft Office 中的 VBA 脚本调用 GetWindowsDirectory
将返回系统的共享 Windows 目录。
如果您使用 DUMPBIN 检查您的 VB6 应用程序,您会发现它不支持终端服务,调用 GetWindowsDirectory
将为用户返回私有 Windows 目录。
其他资源: /TSAWARE (Create Terminal Server Aware Application)
【讨论】:
完美解释。谢谢你。是否有绕过或其他建议如何在 VBA 的边界内从办公应用程序中检索实际的 win 文件夹? @polisha989:我不知道有一种方法可以强制GetWindowsDirectory
返回旧版(即非终端服务感知)结果。从您的 VBA 脚本调用 SHGetKnownFolderPath 和 FOLDERID_Windows 时会得到什么?
获取 C:\Windows,这不是我想要的。以上是关于GetWindowsDirectory() API 返回错误 (vba\vb6)的主要内容,如果未能解决你的问题,请参考以下文章