diff --git a/SystemTools.cxx b/SystemTools.cxx
index 6c4a7a67586fe1f6e6d655e08eedd555811b2e50..c834e34d1172d2144f8963d7e5b136ef686163f5 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -2674,27 +2674,43 @@ kwsys_stl::string SystemTools::GetLastSystemError()
 bool SystemTools::RemoveFile(const kwsys_stl::string& source)
 {
 #ifdef _WIN32
+  kwsys_stl::wstring const& ws =
+    SystemTools::ConvertToWindowsExtendedPath(source);
+  if (DeleteFileW(ws.c_str()))
+    {
+    return true;
+    }
+  DWORD err = GetLastError();
+  if (err == ERROR_FILE_NOT_FOUND ||
+      err == ERROR_PATH_NOT_FOUND)
+    {
+    return true;
+    }
+  if (err != ERROR_ACCESS_DENIED)
+    {
+    return false;
+    }
+  /* The file may be read-only.  Try adding write permission.  */
   mode_t mode;
-  if ( !SystemTools::GetPermissions(source, mode) )
+  if (!SystemTools::GetPermissions(source, mode) ||
+      !SystemTools::SetPermissions(source, S_IWRITE))
     {
+    SetLastError(err);
     return false;
     }
-  /* Win32 unlink is stupid --- it fails if the file is read-only  */
-  SystemTools::SetPermissions(source, S_IWRITE);
-#endif
-#ifdef _WIN32
-  bool res =
-    _wunlink(SystemTools::ConvertToWindowsExtendedPath(source).c_str()) == 0;
-#else
-  bool res = unlink(source.c_str()) != 0 ? false : true;
-#endif
-#ifdef _WIN32
-  if ( !res )
+  if (DeleteFileW(ws.c_str()) ||
+      GetLastError() == ERROR_FILE_NOT_FOUND ||
+      GetLastError() == ERROR_PATH_NOT_FOUND)
     {
-    SystemTools::SetPermissions(source, mode);
+    return true;
     }
+  /* Try to restore the original permissions.  */
+  SystemTools::SetPermissions(source, mode);
+  SetLastError(err);
+  return false;
+#else
+  return unlink(source.c_str()) == 0 || errno == ENOENT;
 #endif
-  return res;
 }
 
 bool SystemTools::RemoveADirectory(const kwsys_stl::string& source)
diff --git a/testSystemTools.cxx b/testSystemTools.cxx
index 42b62497b587dac6a0603f894e0c23a748192b00..15d8eab1b10750b091388dd450f2fb3ecba9c126 100644
--- a/testSystemTools.cxx
+++ b/testSystemTools.cxx
@@ -156,6 +156,24 @@ static bool CheckFileOperations()
     res = false;
     }
 
+  kwsys_stl::string const testFileMissing(testNewDir + "/testMissingFile.txt");
+  if (!kwsys::SystemTools::RemoveFile(testFileMissing))
+    {
+    std::string const& msg = kwsys::SystemTools::GetLastSystemError();
+    kwsys_ios::cerr <<
+      "RemoveFile(\"" << testFileMissing << "\") failed: " << msg << "\n";
+    res = false;
+    }
+
+  kwsys_stl::string const testFileMissingDir(testNewDir + "/missing/file.txt");
+  if (!kwsys::SystemTools::RemoveFile(testFileMissingDir))
+    {
+    std::string const& msg = kwsys::SystemTools::GetLastSystemError();
+    kwsys_ios::cerr <<
+      "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg << "\n";
+    res = false;
+    }
+
   kwsys::SystemTools::Touch(testNewFile.c_str(), true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
     {