diff --git a/silently.cabal b/silently.cabal
--- a/silently.cabal
+++ b/silently.cabal
@@ -1,5 +1,5 @@
 name: silently
-version: 1.1.1
+version: 1.1.2
 cabal-version: >= 1.2
 build-type: Simple
 license: BSD3
diff --git a/src/other/System/IO/Silently.hs b/src/other/System/IO/Silently.hs
--- a/src/other/System/IO/Silently.hs
+++ b/src/other/System/IO/Silently.hs
@@ -21,13 +21,22 @@
 -- This will, as a side effect, create and delete a temp file in the current directory.
 hSilence :: [Handle] -> IO a -> IO a
 hSilence handles action = do
-  oldHandles <- mapM hDuplicate handles
-  bracket (openTempFile "." "silence")
-          (\(tmpFile, tmpHandle) -> do sequence_ $ zipWith hDuplicateTo oldHandles handles
-                                       hClose tmpHandle
-                                       removeFile tmpFile)
-          (\(_,       tmpHandle) -> do mapM_ (hDuplicateTo tmpHandle) handles
-                                       action)
+  tmpDir <- getTempOrCurrentDirectory
+  bracket (openTempFile tmpDir "silence")
+                             cleanup
+                             prepareAndRun
+ where
+  cleanup (tmpFile,tmpHandle) = do
+    hClose tmpHandle
+    removeFile tmpFile
+  prepareAndRun (_,tmpHandle) = go handles
+    where
+      go []     = action
+      go (h:hs) = bracket (do old <- hDuplicate h
+                              hDuplicateTo tmpHandle h
+                              return old)
+                          (\old -> hDuplicateTo old h)
+                          (\_   -> go hs)
 
 
 getTempOrCurrentDirectory :: IO String
@@ -42,14 +51,28 @@
 -- This will, as a side effect, create and delete a temp file in the temp directory or current directory if there is no temp directory.
 hCapture :: [Handle] -> IO a -> IO (String, a)
 hCapture handles action = do
-  oldHandles <- mapM hDuplicate handles
   tmpDir <- getTempOrCurrentDirectory
   bracket (openTempFile tmpDir "capture")
-          (\(tmpFile, tmpHandle) -> do sequence_ $ zipWith hDuplicateTo oldHandles handles
-                                       hClose tmpHandle
-                                       removeFile tmpFile)
-          (\(tmpFile, tmpHandle) -> do mapM_ (hDuplicateTo tmpHandle) handles
-                                       a <- action
-                                       hClose tmpHandle
-                                       str <- readFile tmpFile
-                                       return (str, a))
+                             cleanup
+                             prepareAndRun
+ where
+  cleanup (tmpFile,tmpHandle) = do
+    hClose tmpHandle
+    removeFile tmpFile
+  prepareAndRun (tmpFile,tmpHandle) = go handles
+    where
+      go []     = do
+                 a <- action
+                 hClose tmpHandle
+                 str <- readFile tmpFile
+                 forceList str
+                 return (str,a)
+      go (h:hs) = bracket (do old <- hDuplicate h
+                              hDuplicateTo tmpHandle h
+                              return old)
+                          (\old -> hDuplicateTo old h)
+                          (\_   -> go hs)
+
+forceList [] = return ()
+forceList (x:xs) = forceList xs
+
diff --git a/src/unix/System/IO/Silently.hs b/src/unix/System/IO/Silently.hs
--- a/src/unix/System/IO/Silently.hs
+++ b/src/unix/System/IO/Silently.hs
@@ -18,14 +18,18 @@
 
 -- | Run an IO action while preventing all output to the given handles.
 hSilence :: [Handle] -> IO a -> IO a
-hSilence handles action = do
-  oldHandles <- mapM hDuplicate handles
-  bracket (openFile "/dev/null" AppendMode)
-          (\ tmpHandle -> do sequence_ $ zipWith hDuplicateTo oldHandles handles
-                             hClose tmpHandle)
-          (\ tmpHandle -> do mapM_ (hDuplicateTo tmpHandle) handles
-                             action)
-
+hSilence handles action = bracket (openFile "/dev/null" AppendMode)
+                             hClose
+                             prepareAndRun
+ where
+  prepareAndRun tmpHandle = go handles
+    where
+      go []     = action
+      go (h:hs) = bracket (do old <- hDuplicate h
+                              hDuplicateTo tmpHandle h
+                              return old)
+                          (\old -> hDuplicateTo old h)
+                          (\_   -> go hs)
 
 
 getTempOrCurrentDirectory :: IO String
@@ -40,14 +44,27 @@
 -- This will, as a side effect, create and delete a temp file in the temp directory or current directory if there is no temp directory.
 hCapture :: [Handle] -> IO a -> IO (String, a)
 hCapture handles action = do
-  oldHandles <- mapM hDuplicate handles
   tmpDir <- getTempOrCurrentDirectory
   bracket (openTempFile tmpDir "capture")
-          (\(tmpFile, tmpHandle) -> do sequence_ $ zipWith hDuplicateTo oldHandles handles
-                                       hClose tmpHandle
-                                       removeFile tmpFile)
-          (\(tmpFile, tmpHandle) -> do mapM_ (hDuplicateTo tmpHandle) handles
-                                       a <- action
-                                       hClose tmpHandle
-                                       str <- readFile tmpFile
-                                       return (str, a))
+                             cleanup
+                             prepareAndRun
+ where
+  cleanup (tmpFile,tmpHandle) = do
+    hClose tmpHandle
+    removeFile tmpFile
+  prepareAndRun (tmpFile,tmpHandle) = go handles
+    where
+      go []     = do
+                 a <- action
+                 hClose tmpHandle
+                 str <- readFile tmpFile
+                 forceList str
+                 return (str,a)
+      go (h:hs) = bracket (do old <- hDuplicate h
+                              hDuplicateTo tmpHandle h
+                              return old)
+                          (\old -> hDuplicateTo old h)
+                          (\_   -> go hs)
+
+forceList [] = return ()
+forceList (x:xs) = forceList xs
diff --git a/src/windows/System/IO/Silently.hs b/src/windows/System/IO/Silently.hs
--- a/src/windows/System/IO/Silently.hs
+++ b/src/windows/System/IO/Silently.hs
@@ -18,13 +18,18 @@
 
 -- | Run an IO action while preventing all output to the given handles.
 hSilence :: [Handle] -> IO a -> IO a
-hSilence handles action = do
-  oldHandles <- mapM hDuplicate handles
-  bracket (openFile "NUL" AppendMode)
-          (\ tmpHandle -> do sequence_ $ zipWith hDuplicateTo oldHandles handles
-                             hClose tmpHandle)
-          (\ tmpHandle -> do mapM_ (hDuplicateTo tmpHandle) handles
-                             action)
+hSilence handles action = bracket (openFile "NUL" AppendMode)
+                             hClose
+                             prepareAndRun
+ where
+  prepareAndRun tmpHandle = go handles
+    where
+      go []     = action
+      go (h:hs) = bracket (do old <- hDuplicate h
+                              hDuplicateTo tmpHandle h
+                              return old)
+                          (\old -> hDuplicateTo old h)
+                          (\_   -> go hs)
 
 
 getTempOrCurrentDirectory :: IO String
@@ -39,17 +44,27 @@
 -- This will, as a side effect, create and delete a temp file in the temp directory or current directory if there is no temp directory.
 hCapture :: [Handle] -> IO a -> IO (String, a)
 hCapture handles action = do
-  oldHandles <- mapM hDuplicate handles
-  bracket (openTempFile "." "capture")
-          (\(tmpFile, tmpHandle) -> do sequence_ $ zipWith hDuplicateTo oldHandles handles
-                                       hClose tmpHandle
-                                       removeFile tmpFile)
-          (\(tmpFile, tmpHandle) -> do mapM_ (hDuplicateTo tmpHandle) handles
-                                       a <- action
-                                       hClose tmpHandle
-                                       sequence_ $ zipWith hDuplicateTo oldHandles handles
-                                       str <- readFile tmpFile
-                                       forceList str
-                                       return (str, a))
+  tmpDir <- getTempOrCurrentDirectory
+  bracket (openTempFile tmpDir "capture")
+                             cleanup
+                             prepareAndRun
+ where
+  cleanup (tmpFile,tmpHandle) = do
+    hClose tmpHandle
+    removeFile tmpFile
+  prepareAndRun (tmpFile,tmpHandle) = go handles
+    where
+      go []     = do
+                 a <- action
+                 hClose tmpHandle
+                 str <- readFile tmpFile
+                 forceList str
+                 return (str,a)
+      go (h:hs) = bracket (do old <- hDuplicate h
+                              hDuplicateTo tmpHandle h
+                              return old)
+                          (\old -> hDuplicateTo old h)
+                          (\_   -> go hs)
+
 forceList [] = return ()
 forceList (x:xs) = forceList xs
