Note that base 4.7.0 now has a setEnv
in System.Environment
. So for the present or near future it's sorted out.
However if you need this feature in versions <4.7.0 (which is my case currently), I have also extracted from the commit that adds the feature the functions needed to make this work with an older base version.
However I seriously lost patience on this one and did it rather ugly but it works for me...
The mess is that there are 3 functions to call in a windows environment: putenv
, SetEnvironmentVariableA
(ASCII) and SetEnvironmentVariableW
(widechar, utf16). The patch that was committed to base 4.7 does this automatically, but I did something more ugly by lack of time (I may yet it clean it up).
Here's what I have:
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
Obviously use CPP
to put the whole thing in a #ifdef
for windows only. As you can see I have the code for the widechar call, but I commented it currently. I think for my use-case it would probably be enough to just call putenv
but well it works as it is. So here's how I call it then:
setEnv_ "LANG" localeStr
putEnv $ "LANG=" ++ localeStr
My problem is that I'm primarily a linux user at home and I don't like doing too much work on windows at home, and I put a lot of energy to get this and other things to work properly on windows, and I can't bring myself to clean this up further. But with this code and the original patch you should get this to work on base <4.7 without much problems.