diff --git a/System/Process/Common.hs b/System/Process/Common.hs
--- a/System/Process/Common.hs
+++ b/System/Process/Common.hs
@@ -159,7 +159,17 @@
                              -- @Handle@ will use the default encoding
                              -- and newline translation mode (just
                              -- like @Handle@s created by @openFile@).
-  | NoStream                 -- ^ No stream handle will be passed
+  | NoStream                 -- ^ Close the stream's file descriptor without
+                             -- passing a Handle. On POSIX systems this may
+                             -- lead to strange behavior in the child process
+                             -- because attempting to read or write after the
+                             -- file has been closed throws an error. This
+                             -- should only be used with child processes that
+                             -- don't use the file descriptor at all. If you
+                             -- wish to ignore the child process's output you
+                             -- should either create a pipe and drain it
+                             -- manually or pass a @Handle@ that writes to
+                             -- @\/dev\/null@.
   deriving (Eq, Show)
 
 -- ----------------------------------------------------------------------------
diff --git a/cbits/runProcess.c b/cbits/runProcess.c
--- a/cbits/runProcess.c
+++ b/cbits/runProcess.c
@@ -786,6 +786,25 @@
 terminateProcess (ProcHandle handle)
 {
     if (!TerminateProcess ((HANDLE) handle, 1)) {
+        DWORD e = GetLastError();
+        DWORD exitCode;
+        /*
+        This is a crude workaround that is taken from libuv. For some reason
+        TerminateProcess() can fail with ERROR_ACCESS_DENIED if the process
+        already terminated. This situation can be detected by using
+        GetExitCodeProcess() to check if the exit code is availble. Unfortunately
+        this function succeeds and gives exit code 259 (STILL_ACTIVE) if the
+        process is still running. So there is no way to ditinguish a process
+        that exited with 259 and a process that did not exit because we had
+        insufficient access to terminate it.
+        One would expect WaitForSingleObject() to be the solid solution. But this
+        function does return WAIT_TIMEOUT in that situation. Even if called
+        after GetExitCodeProcess().
+        */
+        if (e == ERROR_ACCESS_DENIED && GetExitCodeProcess((HANDLE) handle, &exitCode) && exitCode != STILL_ACTIVE)
+            return 0;
+
+        SetLastError(e);
         maperrno();
         return -1;
     }
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,11 @@
 # Changelog for [`process` package](http://hackage.haskell.org/package/process)
 
+## 1.6.5.0 *December 2018*
+
+* Bug fix: On Windows ignore ERROR_ACCESS_DENIED for TerminateProcess() if the process did terminate
+  [#110](https://github.com/haskell/process/issues/110)
+* Improve documentation of the `NoStream` data constructor
+
 ## 1.6.4.0 *July 2018*
 
 * Bug fix: Don't leak pipes on failure
diff --git a/process.cabal b/process.cabal
--- a/process.cabal
+++ b/process.cabal
@@ -1,5 +1,5 @@
 name:          process
-version:       1.6.4.0
+version:       1.6.5.0
 -- NOTE: Don't forget to update ./changelog.md
 license:       BSD3
 license-file:  LICENSE
