diff --git a/CabalHelper/Main.hs b/CabalHelper/Main.hs
--- a/CabalHelper/Main.hs
+++ b/CabalHelper/Main.hs
@@ -159,8 +159,6 @@
   print =<< flip mapM cmds $$ \cmd -> do
   case cmd of
     "write-autogen-files":[] -> do
-      -- can't use @projdir@ here
-      let pd = localPkgDescr lbi
        -- calls writeAutogenFiles
       initialBuildSteps distdir pd lbi v
       return Nothing
diff --git a/CabalHelper/Sandbox.hs b/CabalHelper/Sandbox.hs
--- a/CabalHelper/Sandbox.hs
+++ b/CabalHelper/Sandbox.hs
@@ -1,6 +1,5 @@
 module CabalHelper.Sandbox where
 
-
 import Control.Applicative
 import Data.Char
 import Data.Maybe
@@ -8,6 +7,7 @@
 import Data.Version
 import System.FilePath
 import System.Directory
+import Prelude
 
 import qualified Data.Traversable as T
 
diff --git a/CabalHelper/Wrapper.hs b/CabalHelper/Wrapper.hs
--- a/CabalHelper/Wrapper.hs
+++ b/CabalHelper/Wrapper.hs
@@ -381,7 +381,7 @@
 \version %s of Cabal manually (into your user or global package-db):\n\
 \    $ cabal install Cabal --constraint \"Cabal == %s\"\n\
 \\n\
-\Building Cabal %s ...\n" appdir sver sver sver
+\Installing Cabal %s ...\n" appdir sver sver sver
 
   db <- createPkgDb opts ver
   cabalInstallVer <- cabalInstallVersion opts
diff --git a/Distribution/Helper.hs b/Distribution/Helper.hs
--- a/Distribution/Helper.hs
+++ b/Distribution/Helper.hs
@@ -24,6 +24,7 @@
   , Query
   , runQuery
   , runQuery'
+  , runQuery''
 
   -- * Queries against Cabal\'s on disk state
 
@@ -76,6 +77,7 @@
 import System.IO.Unsafe
 import Text.Printf
 import GHC.Generics
+import Prelude
 
 import Paths_cabal_helper (getLibexecDir)
 import CabalHelper.Types
@@ -106,16 +108,23 @@
 -- as reading in Cabal's @LocalBuildInfo@ datatype from disk is very slow but
 -- running all possible queries against it at once is cheap.
 newtype Query m a = Query { unQuery :: StateT (Maybe SomeLocalBuildInfo)
-                                         (ReaderT (Programs, FilePath, FilePath) m) a }
+                                         (ReaderT QueryEnv m) a }
     deriving (Functor, Applicative, Monad, MonadIO)
 
+data QueryEnv = QueryEnv {
+      _qeReadProcess :: FilePath -> [String] -> String -> IO String,
+      _qeProgs       :: Programs,
+      _qeProjectDir  :: FilePath,
+      _qeDistDir     :: FilePath
+    }
+
 type MonadQuery m = ( MonadIO m
                     , MonadState (Maybe SomeLocalBuildInfo) m
-                    , MonadReader (Programs, FilePath, FilePath) m)
+                    , MonadReader QueryEnv m)
 
 run :: Monad m
-  => (Programs, FilePath, FilePath) -> Maybe SomeLocalBuildInfo -> Query m a -> m a
-run r s action = flip runReaderT r (flip evalStateT s (unQuery action))
+  => QueryEnv -> Maybe SomeLocalBuildInfo -> Query m a -> m a
+run e s action = flip runReaderT e (flip evalStateT s (unQuery action))
 
 -- | @runQuery query distdir@. Run a 'Query'. @distdir@ is where Cabal's
 -- @setup-config@ file is located.
@@ -125,7 +134,7 @@
          -> FilePath -- ^ Path to @dist/@
          -> Query m a
          -> m a
-runQuery pd dd action = run (def, pd, dd) Nothing action
+runQuery pd dd action = run (QueryEnv readProcess def pd dd) Nothing action
 
 runQuery' :: Monad m
          => Programs
@@ -134,8 +143,23 @@
          -> FilePath -- ^ Path to @dist/@
          -> Query m a
          -> m a
-runQuery' progs pd dd action = run (progs, pd, dd) Nothing action
+runQuery' progs pd dd action =
+    run (QueryEnv readProcess progs pd dd) Nothing action
 
+runQuery'' :: Monad m
+         => (FilePath -> [String] -> String -> IO String)
+         -- ^ How to start the cabal-helper process. Useful if you need to
+         -- capture stderr output from the helper.
+         -> Programs
+         -> FilePath -- ^ Path to project directory, i.e. the one containing the
+                     -- @project.cabal@ file
+         -> FilePath -- ^ Path to @dist/@
+         -> Query m a
+         -> m a
+runQuery'' readProc progs pd dd action =
+    run (QueryEnv readProc progs pd dd) Nothing action
+
+
 getSlbi :: MonadQuery m => m SomeLocalBuildInfo
 getSlbi = do
   s <- get
@@ -184,10 +208,11 @@
 
 -- | Run @cabal configure@
 reconfigure :: MonadIO m
-            => Programs -- ^ Program paths
+            => (FilePath -> [String] -> String -> IO String)
+            -> Programs -- ^ Program paths
             -> [String] -- ^ Command line arguments to be passed to @cabal@
             -> m ()
-reconfigure progs cabalOpts = do
+reconfigure readProc progs cabalOpts = do
     let progOpts =
             [ "--with-ghc=" ++ ghcProgram progs ]
             -- Only pass ghc-pkg if it was actually set otherwise we
@@ -196,11 +221,11 @@
                  then [ "--with-ghc-pkg=" ++ ghcPkgProgram progs ]
                  else []
             ++ cabalOpts
-    _ <- liftIO $ readProcess (cabalProgram progs) ("configure":progOpts) ""
+    _ <- liftIO $ readProc (cabalProgram progs) ("configure":progOpts) ""
     return ()
 
 getSomeConfigState :: MonadQuery m => m SomeLocalBuildInfo
-getSomeConfigState = ask >>= \(progs, projdir, distdir) -> do
+getSomeConfigState = ask >>= \(QueryEnv readProc progs projdir distdir) -> do
   let progArgs = [ "--with-ghc="     ++ ghcProgram progs
                  , "--with-ghc-pkg=" ++ ghcPkgProgram progs
                  , "--with-cabal="   ++ cabalProgram progs
@@ -218,7 +243,7 @@
 
   res <- liftIO $ do
     exe  <- findLibexecExe "cabal-helper-wrapper"
-    out <- readProcess exe (projdir:distdir:args) ""
+    out <- readProc exe (projdir:distdir:args) ""
     evaluate (read out) `E.catch` \(SomeException _) ->
       error $ concat ["getSomeConfigState", ": ", exe, " "
                      , intercalate " " (map show $ distdir:args)
@@ -239,25 +264,31 @@
 -- | Create @cabal_macros.h@ and @Paths_\<pkg\>@ possibly other generated files
 -- in the usual place.
 writeAutogenFiles :: MonadIO m
-                  => FilePath -- ^ Path to the @dist/@ directory
+                  => (FilePath -> [String] -> String -> IO String)
+                  -> FilePath
+                  -- ^ Path to project directory, i.e. the one containing the
+                  -- @project.cabal@ file
+                  -> FilePath
+                  -- ^ Path to the @dist/@ directory
                   -> m ()
-writeAutogenFiles distdir = liftIO $ do
+writeAutogenFiles readProc projdir distdir = liftIO $ do
   exe  <- findLibexecExe "cabal-helper-wrapper"
-  void $ readProcess exe ["/nowhere/../..", distdir, "write-autogen-files"] ""
+  void $ readProc exe [projdir, distdir, "write-autogen-files"] ""
 
 -- | Get the path to the sandbox package-db in a project
-getSandboxPkgDb :: FilePath
+getSandboxPkgDb :: (FilePath -> [String] -> String -> IO String)
+             -> FilePath
              -- ^ Cabal build platform, i.e. @buildPlatform@
              -> Version
              -- ^ GHC version (@cProjectVersion@ is your friend)
              -> IO (Maybe FilePath)
-getSandboxPkgDb =
-    CabalHelper.Sandbox.getSandboxPkgDb $ unsafePerformIO buildPlatform
+getSandboxPkgDb readProc =
+    CabalHelper.Sandbox.getSandboxPkgDb $ unsafePerformIO $ buildPlatform readProc
 
-buildPlatform :: IO String
-buildPlatform = do
+buildPlatform :: (FilePath -> [String] -> String -> IO String) -> IO String
+buildPlatform readProc = do
   exe  <- findLibexecExe "cabal-helper-wrapper"
-  CabalHelper.Sandbox.dropWhileEnd isSpace <$> readProcess exe ["print-build-platform"] ""
+  CabalHelper.Sandbox.dropWhileEnd isSpace <$> readProc exe ["print-build-platform"] ""
 
 -- | This exception is thrown by all 'runQuery' functions if the internal
 -- wrapper executable cannot be found. You may catch this and present the user
diff --git a/cabal-helper.cabal b/cabal-helper.cabal
--- a/cabal-helper.cabal
+++ b/cabal-helper.cabal
@@ -1,5 +1,5 @@
 name:                cabal-helper
-version:             0.4.0.0
+version:             0.5.0.0
 synopsis:            Simple interface to some of Cabal's configuration state used by ghc-mod
 description:
     @cabal-helper@ provides a library which wraps the internal use of
@@ -90,3 +90,4 @@
                      , cabal-helper
                      , extra
                      , unix
+                     , process
diff --git a/tests/Spec.hs b/tests/Spec.hs
--- a/tests/Spec.hs
+++ b/tests/Spec.hs
@@ -1,10 +1,11 @@
 import Distribution.Helper
 import System.Environment.Extra (lookupEnv)
 import System.Posix.Env (setEnv)
+import System.Process
 import Data.Maybe
 import Data.Functor
 
 main :: IO ()
 main = do
   flip (setEnv "HOME") True =<< fromMaybe "/tmp" <$> lookupEnv "TMPDIR"
-  writeAutogenFiles "./dist"
+  writeAutogenFiles readProcess "." "./dist"
