Merge pull request #1335 from dotnet-maestro-bot/merge/release/2.2-to-master
[automated] Merge branch 'release/2.2' => 'master'
This commit is contained in:
commit
9f82ec3c18
|
|
@ -108,7 +108,7 @@ HandlerResolver::LoadRequestHandlerAssembly(IHttpApplication &pApplication, Shim
|
|||
}
|
||||
}
|
||||
|
||||
LOG_INFOF("Loading request handler: %S", handlerDllPath.c_str());
|
||||
LOG_INFOF(L"Loading request handler: '%ls'", handlerDllPath.c_str());
|
||||
|
||||
hRequestHandlerDll = LoadLibrary(handlerDllPath.c_str());
|
||||
if (preventUnload)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ APPLICATION_INFO::GetOrCreateApplication(
|
|||
{
|
||||
if (m_pApplication->QueryStatus() == RECYCLED)
|
||||
{
|
||||
LOG_INFO("Application went offline");
|
||||
LOG_INFO(L"Application went offline");
|
||||
|
||||
// Call to wait for application to complete stopping
|
||||
m_pApplication->Stop(/* fServerInitiated */ false);
|
||||
|
|
@ -50,14 +50,14 @@ APPLICATION_INFO::GetOrCreateApplication(
|
|||
|
||||
if (AppOfflineApplication::ShouldBeStarted(httpApplication))
|
||||
{
|
||||
LOG_INFO("Detected app_offline file, creating polling application");
|
||||
LOG_INFO(L"Detected app_offline file, creating polling application");
|
||||
m_pApplication.reset(new AppOfflineApplication(httpApplication));
|
||||
}
|
||||
else
|
||||
{
|
||||
FINISHED_IF_FAILED(m_handlerResolver.GetApplicationFactory(httpApplication, m_pApplicationFactory));
|
||||
|
||||
LOG_INFO("Creating handler application");
|
||||
LOG_INFO(L"Creating handler application");
|
||||
IAPPLICATION * newApplication;
|
||||
FINISHED_IF_FAILED(m_pApplicationFactory->Execute(
|
||||
&m_pServer,
|
||||
|
|
@ -97,7 +97,7 @@ APPLICATION_INFO::ShutDownApplication(bool fServerInitiated)
|
|||
|
||||
if (m_pApplication)
|
||||
{
|
||||
LOG_ERRORF("Stopping application %S", QueryApplicationInfoKey().c_str());
|
||||
LOG_ERRORF(L"Stopping application '%ls'", QueryApplicationInfoKey().c_str());
|
||||
m_pApplication ->Stop(fServerInitiated);
|
||||
m_pApplication = nullptr;
|
||||
m_pApplicationFactory = nullptr;
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
|
|||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERRORF("Failed to stop application %S", application->QueryApplicationInfoKey().c_str());
|
||||
LOG_ERRORF(L"Failed to stop application '%ls'", application->QueryApplicationInfoKey().c_str());
|
||||
OBSERVE_CAUGHT_EXCEPTION();
|
||||
|
||||
// Failed to recycle an application. Log an event
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening(
|
|||
{
|
||||
UNREFERENCED_PARAMETER(pProvider);
|
||||
|
||||
LOG_INFO("ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening");
|
||||
LOG_INFO(L"ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening");
|
||||
|
||||
if (g_fInShutdown)
|
||||
{
|
||||
|
|
@ -56,7 +56,7 @@ ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange(
|
|||
// Retrieve the path that has changed.
|
||||
PCWSTR pwszChangePath = pProvider->GetChangePath();
|
||||
|
||||
LOG_INFOF("ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange %S", pwszChangePath);
|
||||
LOG_INFOF(L"ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange '%ls'", pwszChangePath);
|
||||
|
||||
// Test for an error.
|
||||
if (NULL != pwszChangePath &&
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public:
|
|||
|
||||
VOID Terminate()
|
||||
{
|
||||
LOG_INFO("ASPNET_CORE_GLOBAL_MODULE::Terminate");
|
||||
LOG_INFO(L"ASPNET_CORE_GLOBAL_MODULE::Terminate");
|
||||
// Remove the class from memory.
|
||||
delete this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ EventLog::LogEvent(
|
|||
);
|
||||
}
|
||||
|
||||
DebugPrintf(dwEventInfoType == EVENTLOG_ERROR_TYPE ? ASPNETCORE_DEBUG_FLAG_ERROR : ASPNETCORE_DEBUG_FLAG_INFO, "Event Log: %S \r\nEnd Event Log Message.", pstrMsg);
|
||||
DebugPrintfW(dwEventInfoType == EVENTLOG_ERROR_TYPE ? ASPNETCORE_DEBUG_FLAG_ERROR : ASPNETCORE_DEBUG_FLAG_INFO, L"Event Log: '%ls' \r\nEnd Event Log Message.", pstrMsg);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ HRESULT PipeOutputManager::Stop()
|
|||
if (!LOG_LAST_ERROR_IF(GetExitCodeThread(m_hErrThread, &dwThreadStatus) == 0) &&
|
||||
dwThreadStatus == STILL_ACTIVE)
|
||||
{
|
||||
LOG_WARN("Thread reading stdout/err hit timeout, forcibly closing thread.");
|
||||
LOG_WARN(L"Thread reading stdout/err hit timeout, forcibly closing thread.");
|
||||
TerminateThread(m_hErrThread, STATUS_CONTROL_C_EXIT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ HRESULT
|
|||
PrintDebugHeader()
|
||||
{
|
||||
// Major, minor are stored in dwFileVersionMS field and patch, build in dwFileVersionLS field as pair of 32 bit numbers
|
||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "Initializing logs for %S. %S. %S.",
|
||||
DebugPrintfW(ASPNETCORE_DEBUG_FLAG_INFO, L"Initializing logs for '%ls'. %ls. %ls.",
|
||||
GetModuleName().c_str(),
|
||||
GetProcessIdString().c_str(),
|
||||
GetVersionInfoString().c_str()
|
||||
|
|
@ -86,7 +86,7 @@ std::wstring
|
|||
GetModuleName()
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
LOG_LAST_ERROR_IF(GetModuleFileName(g_hModule, path, sizeof(path)));
|
||||
LOG_LAST_ERROR_IF(!GetModuleFileName(g_hModule, path, sizeof(path)));
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ bool CreateDebugLogFile(const std::wstring &debugOutputFile)
|
|||
{
|
||||
if (g_logFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LOG_INFOF("Switching debug log files to %S", debugOutputFile.c_str());
|
||||
LOG_INFOF(L"Switching debug log files to '%ls'", debugOutputFile.c_str());
|
||||
}
|
||||
|
||||
SRWExclusiveLock lock(g_logFileLock);
|
||||
|
|
@ -296,19 +296,29 @@ IsEnabled(
|
|||
return ( dwFlag & DEBUG_FLAGS_VAR );
|
||||
}
|
||||
|
||||
void WriteFileEncoded(UINT codePage, HANDLE hFile, const LPCWSTR szString)
|
||||
{
|
||||
DWORD nBytesWritten = 0;
|
||||
auto const encodedByteCount = WideCharToMultiByte(codePage, 0, szString, -1, nullptr, 0, nullptr, nullptr);
|
||||
auto encodedBytes = std::shared_ptr<CHAR[]>(new CHAR[encodedByteCount]);
|
||||
WideCharToMultiByte(codePage, 0, szString, -1, encodedBytes.get(), encodedByteCount, nullptr, nullptr);
|
||||
|
||||
WriteFile(hFile, encodedBytes.get(), encodedByteCount - 1, &nBytesWritten, nullptr);
|
||||
}
|
||||
|
||||
VOID
|
||||
DebugPrint(
|
||||
DebugPrintW(
|
||||
DWORD dwFlag,
|
||||
const LPCSTR szString
|
||||
const LPCWSTR szString
|
||||
)
|
||||
{
|
||||
STACK_STRA (strOutput, 256);
|
||||
STACK_STRU (strOutput, 256);
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if ( IsEnabled( dwFlag ) )
|
||||
{
|
||||
hr = strOutput.SafeSnprintf(
|
||||
"[%s] %s\r\n",
|
||||
hr = strOutput.SafeSnwprintf(
|
||||
L"[%S] %s\r\n",
|
||||
DEBUG_LABEL_VAR, szString );
|
||||
|
||||
if (FAILED (hr))
|
||||
|
|
@ -316,22 +326,68 @@ DebugPrint(
|
|||
return;
|
||||
}
|
||||
|
||||
OutputDebugStringA( strOutput.QueryStr() );
|
||||
DWORD nBytesWritten = 0;
|
||||
if (IsEnabled(ASPNETCORE_DEBUG_FLAG_CONSOLE))
|
||||
OutputDebugString( strOutput.QueryStr() );
|
||||
|
||||
if (IsEnabled(ASPNETCORE_DEBUG_FLAG_CONSOLE) || g_logFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
auto outputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
WriteFile(outputHandle, strOutput.QueryStr(), strOutput.QueryCB(), &nBytesWritten, nullptr);
|
||||
if (IsEnabled(ASPNETCORE_DEBUG_FLAG_CONSOLE))
|
||||
{
|
||||
WriteFileEncoded(GetConsoleOutputCP(), GetStdHandle(STD_OUTPUT_HANDLE), strOutput.QueryStr());
|
||||
}
|
||||
|
||||
if (g_logFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SRWExclusiveLock lock(g_logFileLock);
|
||||
|
||||
SetFilePointer(g_logFile, 0, nullptr, FILE_END);
|
||||
WriteFileEncoded(CP_UTF8, g_logFile, strOutput.QueryStr());
|
||||
FlushFileBuffers(g_logFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
DebugPrintfW(
|
||||
DWORD dwFlag,
|
||||
const LPCWSTR szFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
STACK_STRU (strCooked,256);
|
||||
|
||||
va_list args;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if ( IsEnabled( dwFlag ) )
|
||||
{
|
||||
va_start( args, szFormat );
|
||||
|
||||
hr = strCooked.SafeVsnwprintf(szFormat, args );
|
||||
|
||||
va_end( args );
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_logFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SRWExclusiveLock lock(g_logFileLock);
|
||||
DebugPrintW( dwFlag, strCooked.QueryStr() );
|
||||
}
|
||||
}
|
||||
|
||||
SetFilePointer(g_logFile, 0, nullptr, FILE_END);
|
||||
WriteFile(g_logFile, strOutput.QueryStr(), strOutput.QueryCB(), &nBytesWritten, nullptr);
|
||||
FlushFileBuffers(g_logFile);
|
||||
}
|
||||
VOID
|
||||
DebugPrint(
|
||||
DWORD dwFlag,
|
||||
const LPCSTR szString
|
||||
)
|
||||
{
|
||||
STACK_STRU (strOutput, 256);
|
||||
|
||||
if ( IsEnabled( dwFlag ) )
|
||||
{
|
||||
strOutput.CopyA(szString);
|
||||
DebugPrintW(dwFlag, strOutput.QueryStr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@
|
|||
#define ASPNETCORE_DEBUG_FLAG_CONSOLE 0x00000008
|
||||
#define ASPNETCORE_DEBUG_FLAG_FILE 0x00000010
|
||||
|
||||
#define LOG_INFO(...) DebugPrint(ASPNETCORE_DEBUG_FLAG_INFO, __VA_ARGS__)
|
||||
#define LOG_INFOF(...) DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, __VA_ARGS__)
|
||||
#define LOG_INFO(...) DebugPrintW(ASPNETCORE_DEBUG_FLAG_INFO, __VA_ARGS__)
|
||||
#define LOG_INFOF(...) DebugPrintfW(ASPNETCORE_DEBUG_FLAG_INFO, __VA_ARGS__)
|
||||
|
||||
#define LOG_WARN(...) DebugPrint(ASPNETCORE_DEBUG_FLAG_WARNING, __VA_ARGS__)
|
||||
#define LOG_WARNF(...) DebugPrintf(ASPNETCORE_DEBUG_FLAG_WARNING, __VA_ARGS__)
|
||||
#define LOG_WARN(...) DebugPrintW(ASPNETCORE_DEBUG_FLAG_WARNING, __VA_ARGS__)
|
||||
#define LOG_WARNF(...) DebugPrintfW(ASPNETCORE_DEBUG_FLAG_WARNING, __VA_ARGS__)
|
||||
|
||||
#define LOG_ERROR(...) DebugPrint(ASPNETCORE_DEBUG_FLAG_ERROR, __VA_ARGS__)
|
||||
#define LOG_ERRORF(...) DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR, __VA_ARGS__)
|
||||
#define LOG_ERROR(...) DebugPrintW(ASPNETCORE_DEBUG_FLAG_ERROR, __VA_ARGS__)
|
||||
#define LOG_ERRORF(...) DebugPrintfW(ASPNETCORE_DEBUG_FLAG_ERROR, __VA_ARGS__)
|
||||
|
||||
VOID
|
||||
DebugInitialize(HMODULE hModule);
|
||||
|
|
@ -37,6 +37,20 @@ IsEnabled(
|
|||
DWORD dwFlag
|
||||
);
|
||||
|
||||
VOID
|
||||
DebugPrintW(
|
||||
DWORD dwFlag,
|
||||
LPCWSTR szString
|
||||
);
|
||||
|
||||
VOID
|
||||
DebugPrintfW(
|
||||
DWORD dwFlag,
|
||||
LPCWSTR szFormat,
|
||||
...
|
||||
);
|
||||
|
||||
|
||||
VOID
|
||||
DebugPrint(
|
||||
DWORD dwFlag,
|
||||
|
|
|
|||
|
|
@ -23,19 +23,16 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
std::vector<std::wstring> &arguments
|
||||
)
|
||||
{
|
||||
LOG_INFOF("Resolving hostfxr parameters for application: '%S' arguments: '%S' path: '%S'",
|
||||
LOG_INFOF(L"Resolving hostfxr parameters for application: '%ls' arguments: '%ls' path: '%ls'",
|
||||
processPath.c_str(),
|
||||
applicationArguments.c_str(),
|
||||
applicationPhysicalPath.c_str());
|
||||
arguments = std::vector<std::wstring>();
|
||||
|
||||
fs::path expandedProcessPath = Environment::ExpandEnvironmentVariables(processPath);
|
||||
const auto expandedApplicationArguments = Environment::ExpandEnvironmentVariables(applicationArguments);
|
||||
|
||||
LOG_INFOF("Expanded hostfxr parameters for application: '%S' arguments: '%S'",
|
||||
expandedProcessPath.c_str(),
|
||||
expandedApplicationArguments.c_str());
|
||||
|
||||
LOG_INFOF("Known dotnet.exe location: '%S'", dotnetExePath.c_str());
|
||||
LOG_INFOF(L"Known dotnet.exe location: '%ls'", dotnetExePath.c_str());
|
||||
|
||||
if (!expandedProcessPath.has_extension())
|
||||
{
|
||||
|
|
@ -50,7 +47,12 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
// Check if the absolute path is to dotnet or not.
|
||||
if (IsDotnetExecutable(expandedProcessPath))
|
||||
{
|
||||
LOG_INFOF("Process path '%S' is dotnet, treating application as portable", expandedProcessPath.c_str());
|
||||
LOG_INFOF(L"Process path '%ls' is dotnet, treating application as portable", expandedProcessPath.c_str());
|
||||
|
||||
if (applicationArguments.empty())
|
||||
{
|
||||
throw StartupParametersResolutionException(L"Application arguments are empty.");
|
||||
}
|
||||
|
||||
if (dotnetExePath.empty())
|
||||
{
|
||||
|
|
@ -59,16 +61,16 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
|
||||
hostFxrDllPath = GetAbsolutePathToHostFxr(dotnetExePath);
|
||||
|
||||
ParseHostfxrArguments(
|
||||
arguments.push_back(dotnetExePath);
|
||||
AppendArguments(
|
||||
expandedApplicationArguments,
|
||||
dotnetExePath,
|
||||
applicationPhysicalPath,
|
||||
arguments,
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFOF("Process path '%S' is not dotnet, treating application as standalone or portable with bootstrapper", expandedProcessPath.c_str());
|
||||
LOG_INFOF(L"Process path '%ls' is not dotnet, treating application as standalone or portable with bootstrapper", expandedProcessPath.c_str());
|
||||
|
||||
auto executablePath = expandedProcessPath;
|
||||
|
||||
|
|
@ -87,21 +89,23 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
auto applicationDllPath = executablePath;
|
||||
applicationDllPath.replace_extension(".dll");
|
||||
|
||||
LOG_INFOF("Checking application.dll at %S", applicationDllPath.c_str());
|
||||
LOG_INFOF(L"Checking application.dll at '%ls'", applicationDllPath.c_str());
|
||||
if (!is_regular_file(applicationDllPath))
|
||||
{
|
||||
throw StartupParametersResolutionException(format(L"Application .dll was not found at %s", applicationDllPath.c_str()));
|
||||
}
|
||||
|
||||
hostFxrDllPath = executablePath.parent_path() / "hostfxr.dll";
|
||||
LOG_INFOF("Checking hostfxr.dll at %S", hostFxrDllPath.c_str());
|
||||
LOG_INFOF(L"Checking hostfxr.dll at '%ls'", hostFxrDllPath.c_str());
|
||||
if (is_regular_file(hostFxrDllPath))
|
||||
{
|
||||
LOG_INFOF("hostfxr.dll found app local at '%S', treating application as standalone", hostFxrDllPath.c_str());
|
||||
LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as standalone", hostFxrDllPath.c_str());
|
||||
// For standalone apps we need .exe to be argv[0], dll would be discovered next to it
|
||||
arguments.push_back(executablePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFOF("hostfxr.dll found app local at '%S', treating application as portable with launcher", hostFxrDllPath.c_str());
|
||||
LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str());
|
||||
|
||||
// passing "dotnet" here because we don't know where dotnet.exe should come from
|
||||
// so trying all fallbacks is appropriate
|
||||
|
|
@ -109,13 +113,15 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
{
|
||||
dotnetExePath = GetAbsolutePathToDotnet(applicationPhysicalPath, L"dotnet");
|
||||
}
|
||||
executablePath = dotnetExePath;
|
||||
hostFxrDllPath = GetAbsolutePathToHostFxr(dotnetExePath);
|
||||
|
||||
// For portable with launcher apps we need dotnet.exe to be argv[0] and .dll be argv[1]
|
||||
arguments.push_back(dotnetExePath);
|
||||
arguments.push_back(applicationDllPath);
|
||||
}
|
||||
|
||||
ParseHostfxrArguments(
|
||||
applicationDllPath.generic_wstring() + L" " + expandedApplicationArguments,
|
||||
executablePath,
|
||||
AppendArguments(
|
||||
expandedApplicationArguments,
|
||||
applicationPhysicalPath,
|
||||
arguments);
|
||||
}
|
||||
|
|
@ -137,29 +143,49 @@ HOSTFXR_UTILITY::IsDotnetExecutable(const std::filesystem::path & dotnetPath)
|
|||
}
|
||||
|
||||
void
|
||||
HOSTFXR_UTILITY::ParseHostfxrArguments(
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
const std::wstring &applicationArguments,
|
||||
const fs::path &applicationExePath,
|
||||
const fs::path &applicationPhysicalPath,
|
||||
std::vector<std::wstring> &arguments,
|
||||
bool expandDllPaths
|
||||
)
|
||||
{
|
||||
LOG_INFOF("Resolving hostfxr_main arguments application: '%S' arguments: '%S' path: %S", applicationExePath.c_str(), applicationArguments.c_str(), applicationPhysicalPath.c_str());
|
||||
|
||||
arguments = std::vector<std::wstring>();
|
||||
arguments.push_back(applicationExePath);
|
||||
|
||||
if (applicationArguments.empty())
|
||||
{
|
||||
throw StartupParametersResolutionException(L"Application arguments are empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
// don't throw while trying to expand arguments
|
||||
std::error_code ec;
|
||||
|
||||
// Try to treat entire arguments section as a single path
|
||||
if (expandDllPaths)
|
||||
{
|
||||
fs::path argumentAsPath = applicationArguments;
|
||||
if (is_regular_file(argumentAsPath, ec))
|
||||
{
|
||||
LOG_INFOF(L"Treating '%ls' as a single path argument", applicationArguments.c_str());
|
||||
arguments.push_back(argumentAsPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argumentAsPath.is_relative())
|
||||
{
|
||||
argumentAsPath = applicationPhysicalPath / argumentAsPath;
|
||||
if (is_regular_file(argumentAsPath, ec))
|
||||
{
|
||||
LOG_INFOF(L"Converted argument '%ls' to '%ls'", applicationArguments.c_str(), argumentAsPath.c_str());
|
||||
arguments.push_back(argumentAsPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int argc = 0;
|
||||
auto pwzArgs = std::unique_ptr<LPWSTR[], LocalFreeDeleter>(CommandLineToArgvW(applicationArguments.c_str(), &argc));
|
||||
if (!pwzArgs)
|
||||
{
|
||||
throw StartupParametersResolutionException(format(L"Unable parse command line arguments '%s' or '%s'", applicationArguments.c_str()));
|
||||
throw StartupParametersResolutionException(format(L"Unable parse command line arguments '%s'", applicationArguments.c_str()));
|
||||
}
|
||||
|
||||
for (int intArgsProcessed = 0; intArgsProcessed < argc; intArgsProcessed++)
|
||||
|
|
@ -173,9 +199,9 @@ HOSTFXR_UTILITY::ParseHostfxrArguments(
|
|||
if (argumentAsPath.is_relative())
|
||||
{
|
||||
argumentAsPath = applicationPhysicalPath / argumentAsPath;
|
||||
if (exists(argumentAsPath))
|
||||
if (is_regular_file(argumentAsPath, ec))
|
||||
{
|
||||
LOG_INFOF("Converted argument '%S' to %S", argument.c_str(), argumentAsPath.c_str());
|
||||
LOG_INFOF(L"Converted argument '%ls' to '%ls'", argument.c_str(), argumentAsPath.c_str());
|
||||
argument = argumentAsPath;
|
||||
}
|
||||
}
|
||||
|
|
@ -183,11 +209,6 @@ HOSTFXR_UTILITY::ParseHostfxrArguments(
|
|||
|
||||
arguments.push_back(argument);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < arguments.size(); i++)
|
||||
{
|
||||
LOG_INFOF("Argument[%d] = %S", i, arguments[i].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// The processPath ends with dotnet.exe or dotnet
|
||||
|
|
@ -199,7 +220,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
|
|||
const fs::path & requestedPath
|
||||
)
|
||||
{
|
||||
LOG_INFOF("Resolving absolute path to dotnet.exe from %S", requestedPath.c_str());
|
||||
LOG_INFOF(L"Resolving absolute path to dotnet.exe from '%ls'", requestedPath.c_str());
|
||||
|
||||
auto processPath = requestedPath;
|
||||
if (processPath.is_relative())
|
||||
|
|
@ -212,7 +233,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
|
|||
//
|
||||
if (is_regular_file(processPath))
|
||||
{
|
||||
LOG_INFOF("Found dotnet.exe at %S", processPath.c_str());
|
||||
LOG_INFOF(L"Found dotnet.exe at '%ls'", processPath.c_str());
|
||||
|
||||
return processPath;
|
||||
}
|
||||
|
|
@ -223,7 +244,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
|
|||
// Only do it if no path is specified
|
||||
if (requestedPath.has_parent_path())
|
||||
{
|
||||
LOG_INFOF("Absolute path to dotnet.exe was not found at %S", requestedPath.c_str());
|
||||
LOG_INFOF(L"Absolute path to dotnet.exe was not found at '%ls'", requestedPath.c_str());
|
||||
|
||||
throw StartupParametersResolutionException(format(L"Could not find dotnet.exe at '%s'", processPath.c_str()));
|
||||
}
|
||||
|
|
@ -231,7 +252,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
|
|||
const auto dotnetViaWhere = InvokeWhereToFindDotnet();
|
||||
if (dotnetViaWhere.has_value())
|
||||
{
|
||||
LOG_INFOF("Found dotnet.exe via where.exe invocation at %S", dotnetViaWhere.value().c_str());
|
||||
LOG_INFOF(L"Found dotnet.exe via where.exe invocation at '%ls'", dotnetViaWhere.value().c_str());
|
||||
|
||||
return dotnetViaWhere.value();
|
||||
}
|
||||
|
|
@ -239,12 +260,12 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
|
|||
const auto programFilesLocation = GetAbsolutePathToDotnetFromProgramFiles();
|
||||
if (programFilesLocation.has_value())
|
||||
{
|
||||
LOG_INFOF("Found dotnet.exe in Program Files at %S", programFilesLocation.value().c_str());
|
||||
LOG_INFOF(L"Found dotnet.exe in Program Files at '%ls'", programFilesLocation.value().c_str());
|
||||
|
||||
return programFilesLocation.value();
|
||||
}
|
||||
|
||||
LOG_INFOF("dotnet.exe not found");
|
||||
LOG_INFOF(L"dotnet.exe not found");
|
||||
throw StartupParametersResolutionException(format(
|
||||
L"Could not find dotnet.exe at '%s' or using the system PATH environment variable."
|
||||
" Check that a valid path to dotnet is on the PATH and the bitness of dotnet matches the bitness of the IIS worker process.",
|
||||
|
|
@ -259,7 +280,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
|
|||
std::vector<std::wstring> versionFolders;
|
||||
const auto hostFxrBase = dotnetPath.parent_path() / "host" / "fxr";
|
||||
|
||||
LOG_INFOF("Resolving absolute path to hostfxr.dll from %S", dotnetPath.c_str());
|
||||
LOG_INFOF(L"Resolving absolute path to hostfxr.dll from '%ls'", dotnetPath.c_str());
|
||||
|
||||
if (!is_directory(hostFxrBase))
|
||||
{
|
||||
|
|
@ -281,7 +302,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
|
|||
throw StartupParametersResolutionException(format(L"hostfxr.dll not found at '%s'", hostFxrPath.c_str()));
|
||||
}
|
||||
|
||||
LOG_INFOF("hostfxr.dll located at %S", hostFxrPath.c_str());
|
||||
LOG_INFOF(L"hostfxr.dll located at '%ls'", hostFxrPath.c_str());
|
||||
return hostFxrPath;
|
||||
}
|
||||
|
||||
|
|
@ -323,7 +344,7 @@ HOSTFXR_UTILITY::InvokeWhereToFindDotnet()
|
|||
securityAttributes.lpSecurityDescriptor = NULL;
|
||||
securityAttributes.bInheritHandle = TRUE;
|
||||
|
||||
LOG_INFO("Invoking where.exe to find dotnet.exe");
|
||||
LOG_INFO(L"Invoking where.exe to find dotnet.exe");
|
||||
|
||||
// Create a read/write pipe that will be used for reading the result of where.exe
|
||||
FINISHED_LAST_ERROR_IF(!CreatePipe(&hStdOutReadPipe, &hStdOutWritePipe, &securityAttributes, 0));
|
||||
|
|
@ -398,7 +419,7 @@ HOSTFXR_UTILITY::InvokeWhereToFindDotnet()
|
|||
|
||||
FINISHED_IF_FAILED(struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead));
|
||||
|
||||
LOG_INFOF("where.exe invocation returned: %S", struDotnetLocationsString.QueryStr());
|
||||
LOG_INFOF(L"where.exe invocation returned: '%ls'", struDotnetLocationsString.QueryStr());
|
||||
|
||||
// Check the bitness of the currently running process
|
||||
// matches the dotnet.exe found.
|
||||
|
|
@ -417,7 +438,7 @@ HOSTFXR_UTILITY::InvokeWhereToFindDotnet()
|
|||
fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
|
||||
}
|
||||
|
||||
LOG_INFOF("Current process bitness type detected as isX64=%d", fIsCurrentProcess64Bit);
|
||||
LOG_INFOF(L"Current process bitness type detected as isX64=%d", fIsCurrentProcess64Bit);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
|
|
@ -431,14 +452,14 @@ HOSTFXR_UTILITY::InvokeWhereToFindDotnet()
|
|||
// \r\n is two wchars, so add 2 here.
|
||||
prevIndex = index + 2;
|
||||
|
||||
LOG_INFOF("Processing entry %S", struDotnetSubstring.QueryStr());
|
||||
LOG_INFOF(L"Processing entry '%ls'", struDotnetSubstring.QueryStr());
|
||||
|
||||
if (LOG_LAST_ERROR_IF(!GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_INFOF("Binary type %d", dwBinaryType);
|
||||
LOG_INFOF(L"Binary type %d", dwBinaryType);
|
||||
|
||||
if (fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,9 +45,8 @@ public:
|
|||
|
||||
static
|
||||
void
|
||||
ParseHostfxrArguments(
|
||||
AppendArguments(
|
||||
const std::wstring &arugments,
|
||||
const std::filesystem::path &exePath,
|
||||
const std::filesystem::path &applicationPhysicalPath,
|
||||
std::vector<std::wstring> &arguments,
|
||||
bool expandDllPaths = false
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ HRESULT HOSTFXR_OPTIONS::Create(
|
|||
knownDotnetLocation,
|
||||
arguments);
|
||||
|
||||
LOG_INFOF(L"Parsed hostfxr options: dotnet location: '%ls' hostfxr path: '%ls' arguments:", knownDotnetLocation.c_str(), hostFxrDllPath.c_str());
|
||||
for (size_t i = 0; i < arguments.size(); i++)
|
||||
{
|
||||
LOG_INFOF(L"Argument[%d] = '%ls'", i, arguments[i].c_str());
|
||||
}
|
||||
ppWrapper = std::make_unique<HOSTFXR_OPTIONS>(knownDotnetLocation, hostFxrDllPath, arguments);
|
||||
}
|
||||
catch (HOSTFXR_UTILITY::StartupParametersResolutionException &resolutionException)
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
|
|||
FINISHED_IF_FAILED(SetEnvironementVariablesOnWorkerProcess());
|
||||
}
|
||||
|
||||
LOG_INFO("Starting managed application");
|
||||
LOG_INFO(L"Starting managed application");
|
||||
|
||||
if (m_pLoggerProvider == NULL)
|
||||
{
|
||||
|
|
@ -547,12 +547,12 @@ IN_PROCESS_APPLICATION::RunDotnetApplication(DWORD argc, CONST PCWSTR* argv, hos
|
|||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
LOG_INFOF("Managed application exited with code %d", m_ProcessExitCode);
|
||||
LOG_INFOF(L"Managed application exited with code %d", m_ProcessExitCode);
|
||||
}
|
||||
__except(GetExceptionCode() != 0)
|
||||
{
|
||||
|
||||
LOG_INFOF("Managed threw an exception %d", GetExceptionCode());
|
||||
LOG_INFOF(L"Managed threw an exception %d", GetExceptionCode());
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
HRESULT AppOfflineTrackingApplication::StartMonitoringAppOffline()
|
||||
{
|
||||
LOG_INFOF("Starting app_offline monitoring in application %S", m_applicationPath.c_str());
|
||||
LOG_INFOF(L"Starting app_offline monitoring in application '%ls'", m_applicationPath.c_str());
|
||||
HRESULT hr = StartMonitoringAppOflineImpl();
|
||||
|
||||
if (FAILED_LOG(hr))
|
||||
|
|
@ -56,7 +56,7 @@ void AppOfflineTrackingApplication::OnAppOffline()
|
|||
return;
|
||||
}
|
||||
|
||||
LOG_INFOF("Received app_offline notification in application %S", m_applicationPath.c_str());
|
||||
LOG_INFOF(L"Received app_offline notification in application '%ls'", m_applicationPath.c_str());
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE,
|
||||
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG,
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ Win32 error
|
|||
DWORD dwErrorStatus;
|
||||
ULONG_PTR completionKey;
|
||||
|
||||
LOG_INFO("Starting file watcher thread");
|
||||
LOG_INFO(L"Starting file watcher thread");
|
||||
pFileMonitor = (FILE_WATCHER*)pvArg;
|
||||
DBG_ASSERT(pFileMonitor != NULL);
|
||||
|
||||
|
|
@ -177,7 +177,7 @@ Win32 error
|
|||
|
||||
pFileMonitor->m_fThreadExit = TRUE;
|
||||
|
||||
LOG_INFO("Stopping file watcher thread");
|
||||
LOG_INFO(L"Stopping file watcher thread");
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit.Abstractions;
|
||||
|
|
@ -37,6 +38,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
return (IISDeploymentResult)await _deployer.DeployAsync();
|
||||
}
|
||||
|
||||
protected virtual async Task<IISDeploymentResult> StartAsync(IISDeploymentParameters parameters)
|
||||
{
|
||||
var result = await DeployAsync(parameters);
|
||||
await result.AssertStarts();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
StopServer(false);
|
||||
|
|
|
|||
|
|
@ -65,12 +65,15 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
{
|
||||
foreach (DirectoryInfo directoryInfo in source.GetDirectories())
|
||||
{
|
||||
CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name), logger);
|
||||
if (directoryInfo.FullName != target.FullName)
|
||||
{
|
||||
CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name), logger);
|
||||
}
|
||||
}
|
||||
logger.LogDebug($"Processing {target.FullName}");
|
||||
logger?.LogDebug($"Processing {target.FullName}");
|
||||
foreach (FileInfo fileInfo in source.GetFiles())
|
||||
{
|
||||
logger.LogDebug($" Copying {fileInfo.Name}");
|
||||
logger?.LogDebug($" Copying {fileInfo.Name}");
|
||||
var destFileName = Path.Combine(target.FullName, fileInfo.Name);
|
||||
fileInfo.CopyTo(destFileName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,64 +11,58 @@
|
|||
TEST(ParseHostFxrArguments, BasicHostFxrArguments)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
PCWSTR exeStr = L"C:/Program Files/dotnet.exe";
|
||||
|
||||
HOSTFXR_UTILITY::ParseHostfxrArguments(
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
L"exec \"test.dll\"", // args
|
||||
exeStr, // exe path
|
||||
L"invalid", // physical path to application
|
||||
bstrArray); // args array.
|
||||
|
||||
EXPECT_EQ(3, bstrArray.size());
|
||||
ASSERT_STREQ(exeStr, bstrArray[0].c_str());
|
||||
ASSERT_STREQ(L"exec", bstrArray[1].c_str());
|
||||
ASSERT_STREQ(L"test.dll", bstrArray[2].c_str());
|
||||
EXPECT_EQ(2, bstrArray.size());
|
||||
ASSERT_STREQ(L"exec", bstrArray[0].c_str());
|
||||
ASSERT_STREQ(L"test.dll", bstrArray[1].c_str());
|
||||
}
|
||||
|
||||
TEST(ParseHostFxrArguments, NoExecProvided)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
PCWSTR exeStr = L"C:/Program Files/dotnet.exe";
|
||||
|
||||
HOSTFXR_UTILITY::ParseHostfxrArguments(
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
L"test.dll", // args
|
||||
exeStr, // exe path
|
||||
L"ignored", // physical path to application
|
||||
bstrArray); // args array.
|
||||
|
||||
EXPECT_EQ(DWORD(2), bstrArray.size());
|
||||
ASSERT_STREQ(exeStr, bstrArray[0].c_str());
|
||||
ASSERT_STREQ(L"test.dll", bstrArray[1].c_str());
|
||||
EXPECT_EQ(1, bstrArray.size());
|
||||
ASSERT_STREQ(L"test.dll", bstrArray[0].c_str());
|
||||
}
|
||||
|
||||
TEST(ParseHostFxrArguments, ConvertDllToAbsolutePath)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
PCWSTR exeStr = L"C:/Program Files/dotnet.exe";
|
||||
// we need to use existing dll so let's use ntdll that we know exists everywhere
|
||||
auto system32 = Environment::ExpandEnvironmentVariables(L"%WINDIR%\\System32");
|
||||
HOSTFXR_UTILITY::ParseHostfxrArguments(
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
L"exec \"ntdll.dll\"", // args
|
||||
exeStr, // exe path
|
||||
system32, // physical path to application
|
||||
bstrArray, // args array.
|
||||
true); // expandDllPaths
|
||||
|
||||
EXPECT_EQ(DWORD(3), bstrArray.size());
|
||||
ASSERT_STREQ(exeStr, bstrArray[0].c_str());
|
||||
ASSERT_STREQ(L"exec", bstrArray[1].c_str());
|
||||
ASSERT_STREQ((system32 + L"\\ntdll.dll").c_str(), bstrArray[2].c_str());
|
||||
EXPECT_EQ(2, bstrArray.size());
|
||||
ASSERT_STREQ(L"exec", bstrArray[0].c_str());
|
||||
ASSERT_STREQ((system32 + L"\\ntdll.dll").c_str(), bstrArray[1].c_str());
|
||||
}
|
||||
|
||||
TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
PCWSTR exeStr = L"C:/Program Files/dotnet.exe";
|
||||
std::filesystem::path struHostFxrDllLocation;
|
||||
std::filesystem::path struExeLocation;
|
||||
|
||||
ASSERT_THROW(HOSTFXR_UTILITY::ParseHostfxrArguments(
|
||||
L"", // args
|
||||
exeStr, // exe path
|
||||
L"ignored", // physical path to application
|
||||
EXPECT_THROW(HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||
L"dotnet", // processPath
|
||||
L"some\\path", // application physical path, ignored.
|
||||
L"", //arguments
|
||||
struHostFxrDllLocation,
|
||||
struExeLocation,
|
||||
bstrArray), // args array.
|
||||
HOSTFXR_UTILITY::StartupParametersResolutionException);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,13 +33,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
public async Task ExpandEnvironmentVariableInWebConfig()
|
||||
{
|
||||
// Point to dotnet installed in user profile.
|
||||
await AssertStarts(
|
||||
deploymentParameters =>
|
||||
{
|
||||
deploymentParameters.EnvironmentVariables["DotnetPath"] = _dotnetLocation;
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "%DotnetPath%"));
|
||||
}
|
||||
);
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
deploymentParameters.EnvironmentVariables["DotnetPath"] = _dotnetLocation;
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "%DotnetPath%"));
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
|
|
@ -68,26 +65,23 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
[ConditionalFact]
|
||||
public async Task StartsWithDotnetLocationWithoutExe()
|
||||
{
|
||||
var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf("."));
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
await AssertStarts(
|
||||
deploymentParameters =>
|
||||
{
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension));
|
||||
}
|
||||
);
|
||||
var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf("."));
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension));
|
||||
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task StartsWithDotnetLocationUppercase()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf(".")).ToUpperInvariant();
|
||||
await AssertStarts(
|
||||
deploymentParameters =>
|
||||
{
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension));
|
||||
}
|
||||
);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension));
|
||||
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
|
|
@ -95,32 +89,18 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
[InlineData("dotnet.EXE")]
|
||||
public async Task StartsWithDotnetOnThePath(string path)
|
||||
{
|
||||
await AssertStarts(
|
||||
deploymentParameters =>
|
||||
{
|
||||
deploymentParameters.EnvironmentVariables["PATH"] = Path.GetDirectoryName(_dotnetLocation);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", path));
|
||||
}
|
||||
);
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
deploymentParameters.EnvironmentVariables["PATH"] = Path.GetDirectoryName(_dotnetLocation);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", path));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
// Verify that in this scenario where.exe was invoked only once by shim and request handler uses cached value
|
||||
Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains("Invoking where.exe to find dotnet.exe")));
|
||||
}
|
||||
|
||||
private async Task AssertStarts(Action<IISDeploymentParameters> preDeploy = null)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
preDeploy?.Invoke(deploymentParameters);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("Hello World", responseText);
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22)
|
||||
|
|
@ -132,13 +112,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
public async Task HelloWorld(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal("Hello World", responseText);
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
|
|
@ -149,7 +123,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
deploymentParameters.ApplicationPublisher = null;
|
||||
// ReferenceTestTasks is workaround for https://github.com/dotnet/sdk/issues/2482
|
||||
deploymentParameters.AdditionalPublishParameters = "-p:RuntimeIdentifier=win7-x64 -p:UseAppHost=true -p:SelfContained=false -p:ReferenceTestTasks=false";
|
||||
deploymentParameters.RestoreOnPublish = true;
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
Assert.True(File.Exists(Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.exe")));
|
||||
|
|
@ -194,7 +167,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(InvalidConfigTransformationsScenarios))]
|
||||
public async Task StartsWithWebConfigVariationsPortable(string scenario)
|
||||
public async Task ReportsWebConfigAuthoringErrors(string scenario)
|
||||
{
|
||||
var (expectedError, action) = InvalidConfigTransformations[scenario];
|
||||
var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
|
@ -227,5 +200,148 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
));
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static Dictionary<string, Func<IISDeploymentParameters, string>> PortableConfigTransformations = InitPortableWebConfigTransformations();
|
||||
public static IEnumerable<object[]> PortableConfigTransformationsScenarios => PortableConfigTransformations.ToTheoryData();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(PortableConfigTransformationsScenarios))]
|
||||
public async Task StartsWithWebConfigVariationsPortable(string scenario)
|
||||
{
|
||||
var action = PortableConfigTransformations[scenario];
|
||||
var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
var expectedArguments = action(iisDeploymentParameters);
|
||||
var result = await DeployAsync(iisDeploymentParameters);
|
||||
Assert.Equal(expectedArguments, await result.HttpClient.GetStringAsync("/CommandLineArgs"));
|
||||
}
|
||||
|
||||
public static Dictionary<string, Func<IISDeploymentParameters, string>> InitPortableWebConfigTransformations()
|
||||
{
|
||||
var dictionary = new Dictionary<string, Func<IISDeploymentParameters, string>>();
|
||||
var pathWithSpace = "\u03c0 \u2260 3\u00b714";
|
||||
|
||||
dictionary.Add("App in bin subdirectory full path to dll using exec and quotes",
|
||||
parameters => {
|
||||
MoveApplication(parameters, "bin");
|
||||
TransformArguments(parameters, (arguments, root) => "exec " + Path.Combine(root, "bin", arguments));
|
||||
return "";
|
||||
});
|
||||
|
||||
dictionary.Add("App in subdirectory with space",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
TransformArguments(parameters, (arguments, root) => Path.Combine(pathWithSpace, arguments));
|
||||
return "";
|
||||
});
|
||||
|
||||
dictionary.Add("App in subdirectory with space and full path to dll",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
TransformArguments(parameters, (arguments, root) => Path.Combine(root, pathWithSpace, arguments));
|
||||
return "";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory with space full path to dll using exec and quotes",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
TransformArguments(parameters, (arguments, root) => "exec \"" + Path.Combine(root, pathWithSpace, arguments) + "\" extra arguments");
|
||||
return "extra|arguments";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory and quoted argument",
|
||||
parameters => {
|
||||
MoveApplication(parameters, "bin");
|
||||
TransformArguments(parameters, (arguments, root) => Path.Combine("bin", arguments) + " \"extra argument\"");
|
||||
return "extra argument";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory full path to dll",
|
||||
parameters => {
|
||||
MoveApplication(parameters, "bin");
|
||||
TransformArguments(parameters, (arguments, root) => Path.Combine(root, "bin", arguments) + " extra arguments");
|
||||
return "extra|arguments";
|
||||
});
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<string, Func<IISDeploymentParameters, string>> StandaloneConfigTransformations = InitStandaloneConfigTransformations();
|
||||
public static IEnumerable<object[]> StandaloneConfigTransformationsScenarios => StandaloneConfigTransformations.ToTheoryData();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(StandaloneConfigTransformationsScenarios))]
|
||||
public async Task StartsWithWebConfigVariationsStandalone(string scenario)
|
||||
{
|
||||
var action = StandaloneConfigTransformations[scenario];
|
||||
var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
iisDeploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||
var expectedArguments = action(iisDeploymentParameters);
|
||||
var result = await DeployAsync(iisDeploymentParameters);
|
||||
Assert.Equal(expectedArguments, await result.HttpClient.GetStringAsync("/CommandLineArgs"));
|
||||
}
|
||||
|
||||
public static Dictionary<string, Func<IISDeploymentParameters, string>> InitStandaloneConfigTransformations()
|
||||
{
|
||||
var dictionary = new Dictionary<string, Func<IISDeploymentParameters, string>>();
|
||||
var pathWithSpace = "\u03c0 \u2260 3\u00b714";
|
||||
|
||||
dictionary.Add("App in subdirectory",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
TransformPath(parameters, (path, root) => Path.Combine(pathWithSpace, path));
|
||||
TransformArguments(parameters, (arguments, root) => "\"additional argument\"");
|
||||
return "additional argument";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory full path",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
TransformPath(parameters, (path, root) => Path.Combine(root, pathWithSpace, path));
|
||||
TransformArguments(parameters, (arguments, root) => "additional arguments");
|
||||
return "additional|arguments";
|
||||
});
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static void MoveApplication(
|
||||
IISDeploymentParameters parameters,
|
||||
string subdirectory)
|
||||
{
|
||||
parameters.WebConfigActionList.Add((config, contentRoot) =>
|
||||
{
|
||||
var source = new DirectoryInfo(contentRoot);
|
||||
var subDirectoryPath = source.CreateSubdirectory(subdirectory);
|
||||
|
||||
// Copy everything into a subfolder
|
||||
Helpers.CopyFiles(source, subDirectoryPath, null);
|
||||
// Cleanup files
|
||||
foreach (var fileSystemInfo in source.GetFiles())
|
||||
{
|
||||
fileSystemInfo.Delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void TransformPath(IISDeploymentParameters parameters, Func<string, string, string> transformation)
|
||||
{
|
||||
parameters.WebConfigActionList.Add(
|
||||
(config, contentRoot) =>
|
||||
{
|
||||
var aspNetCoreElement = config.Descendants("aspNetCore").Single();
|
||||
aspNetCoreElement.SetAttributeValue("processPath", transformation((string)aspNetCoreElement.Attribute("processPath"), contentRoot));
|
||||
});
|
||||
}
|
||||
|
||||
private static void TransformArguments(IISDeploymentParameters parameters, Func<string, string, string> transformation)
|
||||
{
|
||||
parameters.WebConfigActionList.Add(
|
||||
(config, contentRoot) =>
|
||||
{
|
||||
var aspNetCoreElement = config.Descendants("aspNetCore").Single();
|
||||
aspNetCoreElement.SetAttributeValue("arguments", transformation((string)aspNetCoreElement.Attribute("arguments"), contentRoot));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -46,7 +47,7 @@ namespace IISTestSite
|
|||
private async Task HostingEnvironment(HttpContext context)
|
||||
{
|
||||
var hostingEnv = context.RequestServices.GetService<IHostingEnvironment>();
|
||||
|
||||
|
||||
await context.Response.WriteAsync("ContentRootPath "+hostingEnv.ContentRootPath + Environment.NewLine);
|
||||
await context.Response.WriteAsync("WebRootPath "+hostingEnv.WebRootPath + Environment.NewLine);
|
||||
await context.Response.WriteAsync("CurrentDirectory "+Environment.CurrentDirectory);
|
||||
|
|
@ -762,5 +763,10 @@ namespace IISTestSite
|
|||
}
|
||||
await context.Response.WriteAsync("Response End");
|
||||
}
|
||||
|
||||
private async Task CommandLineArgs(HttpContext context)
|
||||
{
|
||||
await context.Response.WriteAsync(string.Join("|", Environment.GetCommandLineArgs().Skip(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue