我正在尝试使用Haskell以版本无关的方式获取Window的Local AppData文件夹的位置,而且我在这样做时遇到了一些麻烦。 我已经尝试使用System.Win32.Registry库,我可以得到下面的代码(经过一些试验和错误),但我无法弄清楚如何使用regQueryValueEx或任何其他函数来获取我需要的价值。
import System.Win32.Types import System.Win32.Registry userShellFolders :: IO HKEY userShellFolders = regOpenKeyEx hKEY_CURRENT_USER "Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\" kEY_QUERY_VALUE
我也尝试在System.Directory模块中查看getAppUserDataDirectory函数的源代码,但是这也没有帮助我。
链接setargv.obj时是否可以在Windows上引用/转义命令行参数?
如何在Windows中使用C ++获取系统文件夹path(C: Windows C: Program Files)?
Sass使用Ruby – '“”C: Program“不被识别为内部或外部命令
关于system()有什么不好的地方?
在Windows上安装librdkafka以支持Python开发
batch file中的逗号分隔双引号stringFOR / F不起作用
PyDBG进程恢复不起作用
在Windows中使用套接字的Python数据包嗅探器
如果你想要可移植性,你不应该直接访问注册表。 有一个API函数来获得特殊的文件夹:SHGetFolderPath。 你可以这样称呼它:
{-# LANGUAGE ForeignFunctionInterface #-} import System.Win32.Types import Graphics.Win32.GDI.Types import Foreign.C.String import Foreign.Marshal.Array foreign import stdcall unsafe "SHGetFolderPathW" cSHGetFolderPathW :: HWND -> INT -> HANDLE -> DWORD -> CWString -> IO LONG maxPath = 260 cSIDL_LOCAL_APPDATA = 0x001c -- //see file ShlObj.h in MS Platform SDK for other CSIDL constants getShellFolder :: INT -> IO String getShellFolder csidl = allocaArray0 maxPath $ path -> do cSHGetFolderPathW nullHANDLE csidl nullHANDLE 0 path peekCWString path main = getShellFolder cSIDL_LOCAL_APPDATA >>= putStrLn
要以有用的格式从注册表中读取值,需要一些代码来在Haskell和C类型之间进行转换。 而那个问题的值通常是类型REG_EXPAND_SZ也没有帮助。 所以这不是很好,但是这对我有用:
{-# LANGUAGE ForeignFunctionInterface #-} import System.Win32.Types import System.Win32.Registry import Foreign.Ptr (castPtr) import Foreign.Marshal.Alloc (allocaBytes) import Foreign.C.String (peekCWString,withCWString) import Control.Exception (bracket,throwIO) -- // parse a string from a registry value of certain type parseRegString :: RegValueType -> LPBYTE -> IO String parseRegString ty mem | ty == rEG_SZ = peekCWString (castPtr mem) | ty == rEG_EXPAND_SZ = peekCWString (castPtr mem) >>= expandEnvironmentStrings | otherwise = ioError (userError "Invalid registry value type") -- // FFI import of the ExpandEnvironmentStrings function needed -- // to make use of the registry values expandEnvironmentStrings :: String -> IO String expandEnvironmentStrings toexpand = withCWString toexpand $ input -> allocaBytes 512 $ output -> do c_ExpandEnvironmentStrings input output 256 peekCWString output foreign import stdcall unsafe "windows.h ExpandEnvironmentStringsW" c_ExpandEnvironmentStrings :: LPCTSTR -> LPTSTR -> DWORD -> IO DWORD -- // open the registry key userShellFolders :: IO HKEY userShellFolders = regOpenKeyEx hKEY_CURRENT_USER "Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" kEY_QUERY_VALUE -- // read the actual value localAppData :: IO String localAppData = bracket userShellFolders regCloseKey $ usfkey -> allocaBytes 512 $ mem -> do ty <- regQueryValueEx usfkey "Local AppData" mem 512 parseRegString ty mem main = localAppData >>= print
我不确定是否所有的错误情况都正确处理(如传递的缓冲区很小),所以你可能想检查Windows文档,看看在这些情况下会发生什么。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。