Default to using program files if where.exe doesn't find dotnet.exe (#578)

This commit is contained in:
Justin Kotalik 2018-02-06 12:12:23 -08:00 committed by GitHub
parent e035d0ed96
commit 9162ab3436
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 104 additions and 77 deletions

View File

@ -145,10 +145,6 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
{
goto Finished;
}
if (FAILED(hr = struHostFxrDllLocation->Copy(struDllPath)))
{
goto Finished;
}
Finished:
@ -479,6 +475,7 @@ HOSTFXR_UTILITY::FindDotnetExePath(
DWORD dwNumBytesRead;
DWORD dwFilePointer;
DWORD dwBinaryType;
DWORD dwPathSize = MAX_PATH;
INT index = 0;
INT prevIndex = 0;
BOOL fResult = FALSE;
@ -545,105 +542,135 @@ HOSTFXR_UTILITY::FindDotnetExePath(
}
//
// where.exe will return 1 if the file is not found
// where.exe will return 0 on success, 1 if the file is not found
// and 2 if there was an error. Check if the exit code is 1 and set
// a new hr result saying it couldn't find dotnet.exe
//
if (!GetExitCodeProcess(processInformation.hProcess, &dwExitCode) ||
dwExitCode != 0)
if (!GetExitCodeProcess(processInformation.hProcess, &dwExitCode))
{
if (dwExitCode == 1)
goto Fallback;
}
//
// In this block, if anything fails, we will goto our fallback of
// looking in C:/Program Files/
//
if (dwExitCode == 0)
{
// Where succeeded.
// Reset file pointer to the beginning of the file.
dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN);
if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
goto Fallback;
}
//
// As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang.
// TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block.
//
if (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL))
{
goto Fallback;
}
if (dwNumBytesRead >= READ_BUFFER_SIZE)
{
// This shouldn't ever be this large. We could continue to call ReadFile in a loop,
// however I'd rather error out here and report an issue.
goto Fallback;
}
if (FAILED(hr = struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead)))
{
goto Finished;
}
// Check the bitness of the currently running process
// matches the dotnet.exe found.
if (!IsWow64Process(GetCurrentProcess(), &fIsWow64Process))
{
// Calling IsWow64Process failed
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
if (fIsWow64Process)
{
// 32 bit mode
fIsCurrentProcess64Bit = FALSE;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
}
while (!fFound)
{
index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex);
if (index == -1)
{
break;
}
if (FAILED(hr = struDotnetSubstring.Copy(struDotnetLocationsString.QueryStr(), index - prevIndex)))
{
goto Finished;
}
prevIndex = index;
if (GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType) &&
fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY)) {
// Found a valid dotnet.
if (FAILED(hr = struDotnetPath->Copy(struDotnetSubstring)))
{
goto Finished;
}
fFound = TRUE;
}
}
goto Finished;
}
// Reset file pointer to the beginning of the file.
dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN);
if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
goto Finished;
}
//
// As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang.
// TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block.
//
if (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL))
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
goto Finished;
}
if (dwNumBytesRead >= READ_BUFFER_SIZE)
{
// This shouldn't ever be this large. We could continue to call ReadFile in a loop,
// however I'd rather error out here and report an issue.
hr = HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
goto Finished;
}
if (FAILED(hr = struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead)))
{
goto Finished;
}
// Check the bitness of the currently running process
// matches the dotnet.exe found.
if (!IsWow64Process(GetCurrentProcess(), &fIsWow64Process))
{
// Calling IsWow64Process failed
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
if (fIsWow64Process)
{
// 32 bit mode
fIsCurrentProcess64Bit = FALSE;
}
else
{
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
}
Fallback:
// Look in ProgramFiles
while (!fFound)
{
index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex);
if (index == -1)
{
break;
}
if (FAILED(hr = struDotnetSubstring.Copy(struDotnetLocationsString.QueryStr(), index - prevIndex)))
if (FAILED(hr = struDotnetSubstring.Resize(dwPathSize)))
{
goto Finished;
}
prevIndex = index;
if (!GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType))
// Program files will changes based on the
dwNumBytesRead = GetEnvironmentVariable(L"ProgramFiles", struDotnetSubstring.QueryStr(), dwPathSize);
if (dwNumBytesRead == 0)
{
// TODO should we ignore this failure and continue to trying the next dotnet.exe?
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
if (fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY)) {
// Found a valid dotnet.
struDotnetPath->Copy(struDotnetSubstring);
else if (dwNumBytesRead == dwPathSize)
{
dwPathSize *= 2 + 30; // for dotnet substring
}
else
{
if (FAILED(hr = struDotnetSubstring.SyncWithBuffer()) ||
FAILED(hr = struDotnetSubstring.Append(L"\\dotnet\\dotnet.exe")))
{
goto Finished;
}
if (!UTILITY::CheckIfFileExists(struDotnetSubstring.QueryStr()))
{
hr = HRESULT_FROM_WIN32( GetLastError() );
goto Finished;
}
if (FAILED(hr = struDotnetPath->Copy(struDotnetSubstring)))
{
goto Finished;
}
fFound = TRUE;
}
}
if (!fFound)
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
goto Finished;
}
Finished: