如何以跨平台方式设置环境变量?

Tik*_*vis 10 haskell cross-platform environment-variables

我可以轻松地使用读取环境变量System.Environment.getEnv.但是,System.Environment没有任何相应的setEnv功能(据我所知).

如何从Haskell程序设置环境变量?我更喜欢跨平台的解决方案.(所以只是执行export VAR=val或使用System.Posix.Env并不是我正在寻找的.)

Emm*_*ery 4

请注意,base 4.7.0 现在有一个setEnvin System.Environment. 所以现在或不久的将来它已经解决了。

但是,如果您在 <4.7.0 版本中需要此功能(这是我目前的情况),我还从添加该功能的提交中提取了使其与较旧的基本版本一起使用所需的功能。

然而,我对这件事严重失去了耐心,做得相当丑陋,但它对我有用......

混乱之处在于,在 Windows 环境中需要调用 3 个函数:putenvSetEnvironmentVariableA(ASCII) 和SetEnvironmentVariableW(widechar, utf16)。致力于基础 4.7 的补丁会自动执行此操作,但由于时间不够,我做了一些更丑陋的事情(我可能还会清理它)。

这是我所拥有的:

setEnv_ :: String -> String -> IO () 
setEnv_ key value = withCString key $ \k -> withCString value $ \v -> do 
  success <- c_SetEnvironmentVariable k v 
  unless success (throwGetLastError "setEnv") 

putEnv :: String -> IO ()
putEnv v = void (withCString v $ \vv -> c_putenv vv)

foreign import stdcall unsafe "windows.h SetEnvironmentVariableA" 
  c_SetEnvironmentVariable :: CString -> CString -> IO Bool 

-- SetEnv_ :: String -> String -> IO () 
-- SetEnv_ key value = withCWString key $ \k -> withCWString value $ \v -> do 
--   success <- c_SetEnvironmentVariable k v 
--   unless success (throwGetLastError "setEnv") 
--  
-- Foreign import stdcall unsafe "windows.h SetEnvironmentVariableW" 
--   c_SetEnvironmentVariable :: LPTSTR -> LPTSTR -> IO Bool 

foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt 
Run Code Online (Sandbox Code Playgroud)

显然用于CPP将整个内容放入#ifdef仅适用于 Windows 的环境中。如您所见,我有 Widechar 调用的代码,但我目前对其进行了评论。我认为对于我的用例来说,只需调用就足够了putenv,但它照常工作。所以我是这样称呼它的:

setEnv_ "LANG" localeStr
putEnv $ "LANG=" ++ localeStr
Run Code Online (Sandbox Code Playgroud)

我的问题是我在家主要是一个linux用户,我不喜欢在家在windows上做太多的工作,我花了很多精力让这个和其他东西在windows上正常工作,我可以不要让自己进一步清理这个问题。但是使用此代码和原始补丁,您应该可以使其在 <4.7 基础上工作,而不会出现太多问题。