aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/Environment.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Environment.hs')
-rw-r--r--src/Environment.hs81
1 files changed, 55 insertions, 26 deletions
diff --git a/src/Environment.hs b/src/Environment.hs
index 2b53258..5a3978e 100644
--- a/src/Environment.hs
+++ b/src/Environment.hs
@@ -5,9 +5,9 @@
-}
module Environment
- ( saveToRegistry
+ ( queryFromRegistry
+ , saveToRegistry
, saveToRegistryWithPrompt
- , queryFromRegistry
, wipeFromRegistry
, wipeFromRegistryWithPrompt
, getEnv
@@ -16,12 +16,15 @@ module Environment
, RegistryBasedEnvironment(..)
) where
-import Control.Monad (liftM, when)
-import Data.List (intercalate)
-import Data.List.Split (splitOn)
-import Data.Maybe (fromMaybe)
+import Control.Monad (liftM, when)
+import Data.List (intercalate)
+import Data.List.Split (splitOn)
+import Data.Maybe (fromMaybe)
import qualified System.Environment (lookupEnv)
-import System.IO.Error (catchIOError, isDoesNotExistError)
+import System.IO.Error (catchIOError, isDoesNotExistError)
+
+import qualified Graphics.Win32.Window as WinAPI
+import qualified System.Win32.Types as WinAPI
import qualified Registry
import qualified Utils (promptToContinue)
@@ -31,22 +34,45 @@ data RegistryBasedEnvironment
| AllUsersEnvironment
deriving (Eq, Show)
-registrySubKeyPath :: RegistryBasedEnvironment -> String
-registrySubKeyPath CurrentUserEnvironment = "Environment"
-registrySubKeyPath AllUsersEnvironment = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
+subKeyPath :: RegistryBasedEnvironment -> Registry.KeyPath
+subKeyPath CurrentUserEnvironment =
+ Registry.keyPathFromString "Environment"
+subKeyPath AllUsersEnvironment =
+ Registry.keyPathFromString "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
+
+rootKey :: RegistryBasedEnvironment -> Registry.RootKey
+rootKey CurrentUserEnvironment = Registry.CurrentUser
+rootKey AllUsersEnvironment = Registry.LocalMachine
+
+openRootKey :: RegistryBasedEnvironment -> Registry.KeyHandle
+openRootKey = Registry.openRootKey . rootKey
-registryKey :: RegistryBasedEnvironment -> Registry.KeyHandle
-registryKey CurrentUserEnvironment = Registry.hkcu
-registryKey AllUsersEnvironment = Registry.hklm
+openRegistryKey :: RegistryBasedEnvironment -> IO Registry.KeyHandle
+openRegistryKey env = Registry.openSubKey (openRootKey env) (subKeyPath env)
+
+registryKeyPath :: RegistryBasedEnvironment -> Registry.KeyPath
+registryKeyPath env = Registry.keyPathJoin [Registry.rootKeyPath $ rootKey env, subKeyPath env]
+
+notifyEnvUpdate :: IO ()
+notifyEnvUpdate =
+ WinAPI.withTString "Environment" $ \lparamPtr -> do
+ let wparam = 0
+ let lparam = fromIntegral $ WinAPI.castPtrToUINTPtr lparamPtr
+ _ <- WinAPI.sendMessage allWindows messageCode wparam lparam
+ return ()
+ where
+ wM_SETTINGCHANGE = 0x1A
+ messageCode = wM_SETTINGCHANGE
-registryKeyPath :: RegistryBasedEnvironment -> String
-registryKeyPath CurrentUserEnvironment = "HKCU\\" ++ registrySubKeyPath CurrentUserEnvironment
-registryKeyPath AllUsersEnvironment = "HKLM\\" ++ registrySubKeyPath AllUsersEnvironment
+ allWindows = WinAPI.castUINTPtrToPtr 0xffff
-saveToRegistry :: RegistryBasedEnvironment -> String -> String -> IO ()
-saveToRegistry env = Registry.setString (registryKey env) (registrySubKeyPath env)
+saveToRegistry :: RegistryBasedEnvironment -> Registry.ValueName -> Registry.ValueData -> IO ()
+saveToRegistry env name value = do
+ keyHandle <- openRegistryKey env
+ Registry.setString keyHandle name value
+ notifyEnvUpdate
-saveToRegistryWithPrompt :: RegistryBasedEnvironment -> String -> String -> IO ()
+saveToRegistryWithPrompt :: RegistryBasedEnvironment -> Registry.ValueName -> Registry.ValueData -> IO ()
saveToRegistryWithPrompt env name value = do
putStrLn $ "Saving variable '" ++ name ++ "' to '" ++ registryKeyPath env ++ "'..."
oldValue <- queryFromRegistry env name
@@ -55,19 +81,22 @@ saveToRegistryWithPrompt env name value = do
agreed <- Utils.promptToContinue
when agreed $ saveToRegistry env name value
-queryFromRegistry :: RegistryBasedEnvironment -> String -> IO String
-queryFromRegistry env name = catchIOError (Registry.getString (registryKey env) (registrySubKeyPath env) name) emptyIfDoesNotExist
+queryFromRegistry :: RegistryBasedEnvironment -> Registry.ValueName -> IO Registry.ValueData
+queryFromRegistry env name = do
+ keyHandle <- openRegistryKey env
+ catchIOError (Registry.getString keyHandle name) emptyIfDoesNotExist
where
- emptyIfDoesNotExist :: IOError -> IO String
emptyIfDoesNotExist e = if isDoesNotExistError e then return "" else ioError e
-wipeFromRegistry :: RegistryBasedEnvironment -> String -> IO ()
-wipeFromRegistry env name = catchIOError (Registry.delValue (registryKey env) (registrySubKeyPath env) name) ignoreIfDoesNotExist
+wipeFromRegistry :: RegistryBasedEnvironment -> Registry.ValueName -> IO ()
+wipeFromRegistry env name = do
+ keyHandle <- openRegistryKey env
+ catchIOError (Registry.delValue keyHandle name) ignoreIfDoesNotExist
+ notifyEnvUpdate
where
- ignoreIfDoesNotExist :: IOError -> IO ()
ignoreIfDoesNotExist e = if isDoesNotExistError e then return () else ioError e
-wipeFromRegistryWithPrompt :: RegistryBasedEnvironment -> String -> IO ()
+wipeFromRegistryWithPrompt :: RegistryBasedEnvironment -> Registry.ValueName -> IO ()
wipeFromRegistryWithPrompt env name = do
putStrLn $ "Deleting variable '" ++ name ++ "' from '" ++ registryKeyPath env ++ "'..."
agreed <- Utils.promptToContinue