diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index 599b521014..5d3910b5ef 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -380,8 +380,10 @@ sub plcheck
 
 sub subdircheck
 {
+	my $subpath = shift;
 	my $module = shift;
 
+	chdir "${topdir}/${subpath}";
 	if (   !-d "$module/sql"
 		|| !-d "$module/expected"
 		|| (!-f "$module/GNUmakefile" && !-f "$module/Makefile"))
@@ -389,7 +391,7 @@ sub subdircheck
 		return;
 	}
 
-	chdir $module;
+	chdir "${topdir}/${subpath}/${module}";
 	my @tests = fetchTests();
 	my @opts  = fetchRegressOpts();
 
@@ -419,17 +421,23 @@ sub subdircheck
 	print "Checking $module\n";
 	my @args = (
 		"$topdir/$Config/pg_regress/pg_regress",
-		"--bindir=${topdir}/${Config}/psql",
+		"--dlpath=${topdir}/src/test/regress",
+		"--bindir=",
+		"--encoding=SQL_ASCII",
+		"--no-locale",
+		"--temp-instance=./tmp_check",
+		"--inputdir=.",
 		"--dbname=contrib_regression", @opts, @tests);
 	print join(' ', @args), "\n";
 	system(@args);
-	chdir "..";
 	return;
 }
 
 sub contribcheck
 {
-	chdir "../../../contrib";
+	InstallTemp();
+	my $subpath = "contrib";
+	chdir "${topdir}/${subpath}";
 	my $mstat = 0;
 	foreach my $module (glob("*"))
 	{
@@ -441,7 +449,7 @@ sub contribcheck
 		next if ($module =~ /_plpython$/ && !defined($config->{python}));
 		next if ($module eq "sepgsql");
 
-		subdircheck($module);
+		subdircheck($subpath, $module);
 		my $status = $? >> 8;
 		$mstat ||= $status;
 	}
@@ -451,11 +459,13 @@ sub contribcheck
 
 sub modulescheck
 {
-	chdir "../../../src/test/modules";
+	InstallTemp();
+	my $subpath = "src/test/modules";
+	chdir "${topdir}/${subpath}";
 	my $mstat = 0;
 	foreach my $module (glob("*"))
 	{
-		subdircheck($module);
+		subdircheck($subpath, $module);
 		my $status = $? >> 8;
 		$mstat ||= $status;
 	}
@@ -619,13 +629,18 @@ sub fetchRegressOpts
 	$m =~ s{\\\r?\n}{}g;
 	if ($m =~ /^\s*REGRESS_OPTS\s*\+?=(.*)/m)
 	{
+		my @split_opts = split(/\s+/, $1);
 
-		# Substitute known Makefile variables, then ignore options that retain
-		# an unhandled variable reference.  Ignore anything that isn't an
-		# option starting with "--".
-		@opts = grep { !/\$\(/ && /^--/ }
-		  map { (my $x = $_) =~ s/\Q$(top_builddir)\E/\"$topdir\"/; $x; }
-		  split(/\s+/, $1);
+		# Substitute known Makefile variables for each option by
+		# something which is supported in this context.
+		foreach my $opt (@split_opts)
+		{
+			# ignore empty strings
+			next if ($opt =~ /^\s*$/);
+			$opt =~ s#\$\(top_builddir\)#"$topdir"#gs;
+			$opt =~ s#\$\(top_srcdir\)#"$topdir"#gs;
+			push @opts, $opt;
+		}
 	}
 	if ($m =~ /^\s*ENCODING\s*=\s*(\S+)/m)
 	{
