Adding ConfigFileReader back into the plugin and fixing it to more efficiently parse the configuration file.

This commit is contained in:
Mike Richmond 2016-07-16 22:01:06 -07:00
parent d7618d731d
commit 4e7f582d43
12 changed files with 353 additions and 100 deletions

View File

@ -99,12 +99,11 @@ function Start-PSBuild {
Use-MSBuild
#mc.exe is Message Compiler for native resources
<# This currently doesn't work reliably and clean systems. Removing for now since mc.exe is not being used yet.
# This currently doesn't work reliably and clean systems. Removing for now since mc.exe is not being used yet.
$mcexe = Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\" -Recurse -Filter 'mc.exe' | ? {$_.FullName -match 'x64'} | select -First 1 | % {$_.FullName}
if (-not $mcexe) {
throw 'mc.exe not found. Install Microsoft Windows SDK.'
}
#>
$vcVarsPath = (Get-Item(Join-Path -Path "$env:VS140COMNTOOLS" -ChildPath '../../vc')).FullName
if ((Test-Path -Path $vcVarsPath\vcvarsall.bat) -eq $false)
@ -223,7 +222,6 @@ function Start-PSBuild {
try {
Push-Location "$PSScriptRoot\src\powershell-native"
<#
# Compile native resources
@("nativemsh/pwrshplugin") | % {
$nativeResourcesFolder = $_
@ -231,7 +229,6 @@ function Start-PSBuild {
& $mcexe -o -d -c -U $_.FullName -h $nativeResourcesFolder -r $nativeResourcesFolder
}
}
#>
# Disabling until I figure out if it is necessary
# $overrideFlags = "-DCMAKE_USER_MAKE_RULES_OVERRIDE=$PSScriptRoot\src\powershell-native\windows-compiler-override.txt"

View File

@ -4,7 +4,9 @@
#
add_library(pwrshcommon
pwrshcommon.cpp
WinSystemCallFacade.cpp)
WinSystemCallFacade.cpp
ConfigFileReader.cpp
)
target_include_directories(pwrshcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -37,7 +37,7 @@ namespace NativeMsh
//
// The following methods are direct thin wrappers for the host calls.
//
virtual HMODULE SetupWrapper(LPCSTR coreClrPathPtr) = 0;
virtual unsigned int SetupWrapper(LPCSTR coreClrPathPtr) = 0;
virtual int InitializeClr(
const char* exePath,
@ -123,15 +123,13 @@ namespace NativeMsh
{
return (NULL != coreClrHandle);
}
//
// TODO: This shouldn't return HMODULE because that breaks encapsulation. I need a better way to
// have the caller extract the value. Either Pass as a reference or provide an accessor.
//
//
// Attempts to load CoreCLR.dll from the specified directory.
// On success pins the dll, sets coreCLRDirectoryPath and returns the HMODULE.
// On failure returns NULL.
virtual HMODULE SetupWrapper(LPCSTR coreClrPathPtr)
//
virtual unsigned int SetupWrapper(LPCSTR coreClrPathPtr)
{
std::string coreClrPath(coreClrPathPtr);
coreClrPath += coreClrDllName;
@ -139,13 +137,13 @@ namespace NativeMsh
HMODULE result = LoadLibraryExA(coreClrPath.c_str(), NULL, 0);
if (!result)
{
return NULL;
return EXIT_CODE_INIT_FAILURE;
}
// Pin the module - CoreCLR.dll does not support being unloaded.
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, coreClrPath.c_str(), &pinnedModuleHandle))
{
return NULL;
return EXIT_CODE_INIT_FAILURE;
}
initPtr = (coreclr_initialize_ptr)GetProcAddress(result, "coreclr_initialize");
@ -156,12 +154,12 @@ namespace NativeMsh
NULL == shutdownPtr ||
NULL == createDelegatePtr)
{
return NULL;
return EXIT_CODE_INIT_FAILURE;
}
// Initialization succeeded. Save the handle and return success;
coreClrHandle = result;
return result;
return EXIT_CODE_SUCCESS;
}
virtual unsigned int CleanUpHostWrapper()
@ -246,6 +244,7 @@ namespace NativeMsh
private:
// The path to this module
char m_hostPath[MAX_PATH];
wchar_t m_hostPathW[MAX_PATH];
// The path to the directory containing this module
char m_hostDirectoryPath[MAX_PATH];
@ -253,11 +252,56 @@ namespace NativeMsh
// The name of this module, without the path
std::string m_hostBinaryName;
std::wstring m_hostBinaryNameW;
// The path to the directory that CoreCLR is in
char m_coreCLRDirectoryPath[MAX_PATH];
wchar_t m_coreCLRDirectoryPathW[MAX_PATH];
void convertAnsiToWide(char* ansiArray, wchar_t* wideArray)
{
// Generate the wide version of the string and save its value;
//
// This is a two call function. The first call is to get the necessary length.
// The second call is to perform the actual operation.
int length = ::MultiByteToWideChar(CP_UTF8, 0, ansiArray, -1, NULL, 0);
if (0 < length)
{
LPWSTR result = new wchar_t[length];
if (NULL != result)
{
length = ::MultiByteToWideChar(CP_UTF8, 0, ansiArray, -1, result, length);
if (0 < length)
{
wcscpy_s(wideArray, MAX_PATH, result);
}
delete[] result; // Free the allocated string to avoid a memory leak
}
}
}
void convertWideToAnsi(wchar_t* wideArray, char* ansiArray)
{
// Generate the ansi version of the string and save its value;
//
// This is a two call function. The first call is to get the necessary length.
// The second call is to perform the actual operation.
int length = ::WideCharToMultiByte(CP_ACP, 0, wideArray, -1, NULL, 0, NULL, NULL);
if (0 < length)
{
LPSTR result = new char[length];
if (NULL != result)
{
length = ::WideCharToMultiByte(CP_ACP, 0, wideArray, -1, result, length, NULL, NULL);
if (0 < length)
{
strcpy_s(ansiArray, MAX_PATH, result);
}
delete[] result; // Free the allocated string to avoid a memory leak
}
}
}
public:
HostEnvironment()
@ -275,6 +319,17 @@ namespace NativeMsh
if (hostPath)
{
::ExpandEnvironmentStringsA(hostPath, m_hostPath, MAX_PATH);
convertAnsiToWide(m_hostPath, m_hostPathW);
}
}
void SetHostPathW(PCWSTR hostPath)
{
if (hostPath)
{
::ExpandEnvironmentStringsW(hostPath, m_hostPathW, MAX_PATH);
convertWideToAnsi(m_hostPathW, m_hostPath);
}
}
@ -284,6 +339,11 @@ namespace NativeMsh
return m_hostPath;
}
PCWSTR GetHostPathW()
{
return m_hostPathW;
}
// Safely copies in a host binary name
void SetHostBinaryName(PCSTR hostBinaryName)
{
@ -293,12 +353,25 @@ namespace NativeMsh
}
}
void SetHostBinaryNameW(PCWSTR hostBinaryName)
{
if (hostBinaryName)
{
m_hostBinaryNameW = std::wstring(hostBinaryName);
}
}
// Returns the name of the host module
PCSTR GetHostBinaryName()
{
return m_hostBinaryName.c_str();
}
PCWSTR GetHostBinaryNameW()
{
return m_hostBinaryNameW.c_str();
}
// Safely copies in a host directory path
void SetHostDirectoryPath(PCSTR hostDirPath)
{
@ -306,24 +379,17 @@ namespace NativeMsh
{
::ExpandEnvironmentStringsA(hostDirPath, m_hostDirectoryPath, MAX_PATH);
// Generate the wide version of the string and save its value;
//
// This is a two call function. The first call is to get the necessary length.
// The second call is to perform the actual operation.
int length = MultiByteToWideChar(CP_UTF8, 0, m_hostDirectoryPath, -1, NULL, 0);
if (0 < length)
{
LPWSTR result = new wchar_t[length];
if (NULL != result)
{
length = ::MultiByteToWideChar(CP_UTF8, 0, m_hostDirectoryPath, -1, result, length);
if (0 < length)
{
wcscpy_s(m_hostDirectoryPathW, MAX_PATH, result);
}
delete[] result; // Free the allocated string to avoid a memory leak
}
}
convertAnsiToWide(m_hostDirectoryPath, m_hostDirectoryPathW);
}
}
void SetHostDirectoryPathW(PCWSTR hostDirPath)
{
if (hostDirPath)
{
::ExpandEnvironmentStringsW(hostDirPath, m_hostDirectoryPathW, MAX_PATH);
convertWideToAnsi(m_hostDirectoryPathW, m_hostDirectoryPath);
}
}
@ -346,24 +412,17 @@ namespace NativeMsh
{
::ExpandEnvironmentStringsA(hostClrPath, m_coreCLRDirectoryPath, MAX_PATH);
// Generate the wide version of the string and save its value;
//
// This is a two call function. The first call is to get the necessary length.
// The second call is to perform the actual operation.
int length = MultiByteToWideChar(CP_UTF8, 0, m_coreCLRDirectoryPath, -1, NULL, 0);
if (0 < length)
{
LPWSTR result = new wchar_t[length];
if (NULL != result)
{
length = ::MultiByteToWideChar(CP_UTF8, 0, m_coreCLRDirectoryPath, -1, result, length);
if (0 < length)
{
wcscpy_s(m_coreCLRDirectoryPathW, MAX_PATH, result);
}
delete[] result; // Free the allocated string to avoid a memory leak
}
}
convertAnsiToWide(m_coreCLRDirectoryPath, m_coreCLRDirectoryPathW);
}
}
void SetCoreCLRDirectoryPathW(PCWSTR hostClrPath)
{
if (hostClrPath)
{
::ExpandEnvironmentStringsW(hostClrPath, m_coreCLRDirectoryPathW, MAX_PATH);
convertWideToAnsi(m_coreCLRDirectoryPathW, m_coreCLRDirectoryPath);
}
}
@ -378,5 +437,7 @@ namespace NativeMsh
{
return m_coreCLRDirectoryPathW;
}
};
} // namespace NativeMsh

View File

@ -0,0 +1,131 @@
#include <iostream>
#include <fstream>
#include <windef.h>
#include "NativeMsh.h"
#include "ConfigFileReader.h"
namespace NativeMsh
{
// The name of the PowerShell config file that identifies the PowerShell install location.
// We use a config file to avoid writing to the registry during install
// or hard coding paths into the binary.
static PCWSTR powerShellConfigFileName = L"RemotePowerShellConfig.txt";
ConfigFileReader::ConfigFileReader()
{
}
unsigned int ConfigFileReader::Read(
std::wstring pathToConfig)
{
std::wstring absolutePathToConfigFile(pathToConfig);
absolutePathToConfigFile += powerShellConfigFileName;
std::wfstream psConfigFile(absolutePathToConfigFile.c_str());
if (!psConfigFile.is_open())
{
return EXIT_CODE_INIT_FAILURE;
}
std::wstring line;
std::wstring psHomeDirTag(L"PSHOMEDIR=");
std::wstring coreClrDirTag(L"CORECLRDIR=");
while (std::getline(psConfigFile, line))
{
std::wstring::const_iterator iter = line.begin();
// Search for the first actionable character in the line to
// limit the number of passes that are made iterating through the line.
while(iter != line.end())
{
if (*iter == L'#')
{
// Stop parsing the line because the rest of it is a comment
break;
}
else if (*iter == L'p' || *iter == L'P')
{
this->pathToPowerShellAssemblies = this->getValueFromLine(line, psHomeDirTag);
if (this->pathToPowerShellAssemblies.size() > 0) // Found a match
{
std::wstring::const_iterator slashIter = this->pathToPowerShellAssemblies.end();
slashIter--;
if (*slashIter != L'\\')
{
// Guarantee that there is a '\' at the end of the path
this->pathToPowerShellAssemblies.append(L"\\");
}
}
}
else if (*iter == L'c' || *iter == L'C')
{
this->coreClrDirectory = this->getValueFromLine(line, coreClrDirTag);
if (this->coreClrDirectory.size() > 0) // Found a match
{
std::wstring::const_iterator slashIter = this->coreClrDirectory.end();
slashIter--;
if (*slashIter != L'\\')
{
// Guarantee that there is a '\' at the end of the path
this->coreClrDirectory.append(L"\\");
}
}
}
// Do nothing to ignore unmatched characters (whitespace, etc.)
iter++;
}
}
if (0 == this->pathToPowerShellAssemblies.size() ||
0 == this->coreClrDirectory.size())
{
return EXIT_CODE_INIT_FAILURE;
}
else
{
return EXIT_CODE_SUCCESS;
}
}
// This trim function removes beginning and ending whitespace. It does not
// remove internal whitespace because that is valid within paths.
std::wstring ConfigFileReader::trim(
const std::wstring& toTrim)
{
static PCWSTR WHITESPACE_CHARS = L" \n\r\t";
std::wstring copyToTrim = toTrim;
std::size_t first = copyToTrim.find_first_not_of(WHITESPACE_CHARS);
if (first == std::wstring::npos)
{
// No non-whitespace found
return std::wstring(L"");
}
// Result not checked for std::wstring::npos because it is guaranteed to have a value if the first pass succeeded.
copyToTrim.erase(copyToTrim.find_last_not_of(WHITESPACE_CHARS)+1);
return copyToTrim.substr(first);
}
// Parses the specified line for the given tag. Tags are assumed to include
// the "=" separator character.
std::wstring ConfigFileReader::getValueFromLine(
const std::wstring& line, // Passed by value to preserve the original line.
std::wstring& tagToFind)
{
std::wstring trimmedLine = this->trim(line);
std::size_t index = trimmedLine.find(tagToFind);
if (std::string::npos != index)
{
std::wstring value = trimmedLine.substr(index + tagToFind.size()); // Everything else after the tag
return this->trim(value);
}
else
{
return std::wstring(L"");
}
}
}

View File

@ -0,0 +1,36 @@
// ---------------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2014.
//
// Contents: A class that extracts the path to $PSHOME and the path to its
// CoreCLR from a configuration file.
// ---------------------------------------------------------------------------
#pragma once
#include <string>
namespace NativeMsh
{
class ConfigFileReader
{
private:
std::wstring pathToPowerShellAssemblies;
std::wstring coreClrDirectory;
std::wstring trim(const std::wstring& toTrim);
std::wstring getValueFromLine(const std::wstring& line, std::wstring& tagToFind);
public:
ConfigFileReader();
// Initiates a Read operation of the specified configuration file.
unsigned int Read(std::wstring pathToConfig);
// Information Getters
std::wstring GetPathToPowerShell() { return pathToPowerShellAssemblies; }
std::wstring GetPathToCoreClr() { return coreClrDirectory; }
};
} // namespace NativeMsh

View File

@ -17,6 +17,7 @@
#include "NativeMshConstants.h"
#include "ClrHostWrapper.h"
#include "SystemCallFacade.h"
#include "ConfigFileReader.h"
#include "IPwrshCommonOutput.h"
#if !CORECLR
@ -29,6 +30,7 @@ namespace NativeMsh
{
private:
IPwrshCommonOutput* output;
ConfigFileReader* reader;
SystemCallFacade* sysCalls;
public:
@ -41,6 +43,7 @@ namespace NativeMsh
// allocate them with "new".
PwrshCommon(
IPwrshCommonOutput* outObj, // Enables clients to specify how error messages are displayed or suppressed
ConfigFileReader* rdr, // Enables specification of how the config file is read.
SystemCallFacade* systemCalls); // Wraps all calls to Windows APIs to allow for dependency injection via unit test
~PwrshCommon();

View File

@ -820,29 +820,40 @@ namespace NativeMsh
// The name of the CoreCLR native runtime DLL.
static PCSTR coreClrDll = "CoreCLR.dll";
// The location where CoreCLR is expected to be installed. If CoreCLR.dll isn't
// The location where CoreCLR is expected to be installed for inbox PowerShell. If CoreCLR.dll isn't
// found in the same directory as the host, it will be looked for here.
static PCSTR coreCLRInstallDirectory = "%windir%\\system32\\DotNetCore\\v1.0\\";
// The location where CoreCLR PowerShell Ext binaries are expected to be installed.
// The location where CoreCLR PowerShell Ext binaries are expected to be installed for inbox PowerShell.
static PCSTR coreCLRPowerShellExtInstallDirectory = "%windir%\\system32\\CoreClrPowerShellExt\\v1.0\\";
// The default PowerShell install directory. This location may be overridden through a config file in %windir%\System32.
// The default PowerShell install directory for inbox PowerShell.
// This location may be overridden by placing a config file in the same directory as the PowerShell host.
static PCSTR powerShellInstallPath = "%windir%\\System32\\WindowsPowerShell\\v1.0\\";
unsigned int PwrshCommon::IdentifyHostDirectory(
HostEnvironment& hostEnvironment)
{
// Discover the path to the exe's module (powershell.exe or wsmprovhost.exe).
// For remoting, this is expected to be %windir%\system32 since that is the location of wsmprovhost.exe.
char hostPath[MAX_PATH];
DWORD thisModuleLength = sysCalls->GetModuleFileNameA(sysCalls->GetModuleHandleA(NULL), hostPath, MAX_PATH);
// Discover the path to the plugin or the executable (pwrshplugin.dll or powershell.exe).
// For PowerShell Core, the plugin no longer resides in %windir%\\system32 (it is in a sub-directory).
// If pwrshplugin.dll is not loaded, it means that this is running via powershell.exe.
wchar_t hostPath[MAX_PATH];
DWORD thisModuleLength;
if (0 == thisModuleLength)
if (GetModuleHandleW(L"pwrshplugin.dll"))
{
thisModuleLength = GetModuleFileNameW(GetModuleHandleW(L"pwrshplugin.dll"), hostPath, MAX_PATH);
}
else
{
thisModuleLength = GetModuleFileNameW(GetModuleHandleW(NULL), hostPath, MAX_PATH);
}
if (0 == thisModuleLength) // Greater than zero means it is the length of the fully qualified path (without the NULL character)
{
// TODO: Use GetLastError() to find the specific error #
return EXIT_CODE_INIT_FAILURE;
}
// Search for the last backslash in the host path.
int lastBackslashIndex;
for (lastBackslashIndex = thisModuleLength - 1; lastBackslashIndex >= 0; lastBackslashIndex--)
@ -854,14 +865,34 @@ namespace NativeMsh
}
// The remaining part of the path after the last '\' is the binary name.
hostEnvironment.SetHostBinaryName(hostPath + lastBackslashIndex + 1);
hostEnvironment.SetHostBinaryNameW(hostPath + lastBackslashIndex + 1);
// Copy the directory path portion of the path
hostPath[lastBackslashIndex + 1] = '\0';
hostEnvironment.SetHostPath(hostPath);
hostEnvironment.SetHostDirectoryPath(powerShellInstallPath);
hostEnvironment.SetHostPathW(hostPath);
// Read the config file to determine the appropriate host path and CoreCLR path to use.
unsigned int result = reader->Read(hostPath);
if (EXIT_CODE_SUCCESS == result)
{
// The config file was successfully parsed. Use those directories.
hostEnvironment.SetHostDirectoryPathW(reader->GetPathToPowerShell().c_str());
hostEnvironment.SetCoreCLRDirectoryPathW(reader->GetPathToCoreClr().c_str());
}
else
{
// There was an issue accessing or parsing the config file OR
// we are working for the EXE.
//
// TODO: This should not be the fallback for inbox PowerShell.exe.
// It should use coreCLRInstallDirectory and coreCLRPowerShellExtInstallDirectory.
//
// Use the directory detected via GetModuleFileName + GetModuleHandle
hostEnvironment.SetHostDirectoryPathW(hostPath);
// At the moment, CoreCLR is in the same directory as PowerShell Core.
// This path must be modified if we decide to use a different directory.
hostEnvironment.SetCoreCLRDirectoryPathW(hostPath);
}
return EXIT_CODE_SUCCESS;
}
@ -959,20 +990,26 @@ namespace NativeMsh
//
PwrshCommon::PwrshCommon()
: output(new PwrshCommonOutputDefault()), sysCalls(new WinSystemCallFacade())
: output(new PwrshCommonOutputDefault()), reader(new ConfigFileReader()), sysCalls(new WinSystemCallFacade())
{
}
PwrshCommon::PwrshCommon(
IPwrshCommonOutput* outObj,
ConfigFileReader* rdr,
SystemCallFacade* systemCalls)
: output(outObj), sysCalls(systemCalls)
: output(outObj), reader(rdr), sysCalls(systemCalls)
{
if (NULL == output)
{
output = new PwrshCommonOutputDefault();
}
if (NULL == reader)
{
reader = new ConfigFileReader();
}
if (NULL == sysCalls)
{
sysCalls = new WinSystemCallFacade();
@ -987,6 +1024,12 @@ namespace NativeMsh
output = NULL;
}
if (reader)
{
delete reader;
reader = NULL;
}
if (sysCalls)
{
delete sysCalls;
@ -1299,37 +1342,13 @@ namespace NativeMsh
return exitCode;
}
// Try to load from the well-known location.
char coreCLRInstallPath[MAX_PATH];
exitCode = ::ExpandEnvironmentStringsA(coreCLRInstallDirectory, coreCLRInstallPath, MAX_PATH);
if (0 == exitCode || _countof(coreCLRInstallPath) <= exitCode)
exitCode = hostWrapper->SetupWrapper(hostEnvironment.GetCoreCLRDirectoryPath());
if (EXIT_CODE_SUCCESS != exitCode)
{
this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError());
return EXIT_CODE_INIT_FAILURE;
}
HMODULE coreClrModule = hostWrapper->SetupWrapper(coreCLRInstallPath);
if (!coreClrModule)
{
this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError());
return EXIT_CODE_INIT_FAILURE;
return exitCode;
}
// Save the directory that CoreCLR was found in
char coreCLRDirectoryPath[MAX_PATH];
DWORD modulePathLength = sysCalls->GetModuleFileNameA(coreClrModule, coreCLRDirectoryPath, MAX_PATH);
// Search for the last backslash and terminate it there to keep just the directory path with trailing slash
for (int lastBackslashIndex = modulePathLength - 1; lastBackslashIndex >= 0; lastBackslashIndex--)
{
if (coreCLRDirectoryPath[lastBackslashIndex] == L'\\')
{
coreCLRDirectoryPath[lastBackslashIndex + 1] = L'\0';
break;
}
}
hostEnvironment.SetCoreCLRDirectoryPath(coreCLRDirectoryPath);
const int nMaxProps = 8;
LPCSTR props[nMaxProps];
LPCSTR vals[nMaxProps];

View File

@ -34,7 +34,7 @@ else ()
# CoreCLR libs
${STATIC_MT_CRT_LIB}
${STATIC_MT_VCRT_LIB}
${STATIC_UCRT_LIB}
# ${STATIC_UCRT_LIB}
# ole32.lib
# oleaut32.lib
# uuid.lib

View File

@ -18,6 +18,7 @@
#include "NativeMsh.h"
#include "ClrHostWrapper.h"
#include "OutputWriter.h"
#include "ConfigFileReader.h"
#include "WinSystemCallFacade.h"
namespace NativeMsh
@ -35,7 +36,7 @@ namespace NativeMsh
// All these objects will be destroyed when commonFuncs goes out of scope.
PwrshExeOutput* output = new PwrshExeOutput();
PwrshCommon commonFuncs(output, new WinSystemCallFacade());
PwrshCommon commonFuncs(output, new ConfigFileReader(), new WinSystemCallFacade());
CoreClrHostingApiWrapper hostWrapper;
exitCode = commonFuncs.LaunchCoreCLR(&hostWrapper, hostEnvironment, "powershell");

View File

@ -26,6 +26,7 @@
#include <msxml6.h>
#include <VersionHelpers.h>
#include "OutputWriter.h"
#include "ConfigFileReader.h"
#include "WinSystemCallFacade.h"
// include the tlb for mscorlib for access to the default AppDomain through COM Interop
@ -49,7 +50,7 @@ WCHAR g_IconApp[MAX_PATH+1];
// All these objects will be destroyed when pwrshCommon goes out of scope.
PwrshExeOutput* pwrshExeOutput = new PwrshExeOutput();
PwrshCommon pwrshCommon(pwrshExeOutput, new WinSystemCallFacade());
PwrshCommon pwrshCommon(pwrshExeOutput, new ConfigFileReader(), new WinSystemCallFacade());
bool ConvertArgvToSafeArray(
IN int argc,

View File

@ -5,7 +5,8 @@ add_library(pwrshplugin SHARED
entrypoints.cpp
pwrshclrhost.cpp
pwrshpluginerrorcodes.mc
pwrshpluginerrorcodes.rc
#pwrshpluginerrorcodes.rc
pwrshpluginResources.rc
pwrshplugin.def
)
@ -40,7 +41,7 @@ else ()
# CoreCLR lib
${STATIC_MT_CRT_LIB}
${STATIC_MT_VCRT_LIB}
${STATIC_UCRT_LIB}
# ${STATIC_UCRT_LIB}
legacy_stdio_definitions.lib # Resolves: LNK2019: unresolved external symbol _vsnwprintf
)
set(pwrshplugin_definitions ${common_pwrsh_definitions})

View File

@ -130,7 +130,7 @@ PowerShellCoreClrWorker::PowerShellCoreClrWorker(
if (NULL == commonLib)
{
commonLib = new PwrshCommon(new PwrshPluginOutputDefault(), new WinSystemCallFacade());
commonLib = new PwrshCommon(new PwrshPluginOutputDefault(), new ConfigFileReader(), new WinSystemCallFacade());
}
}
@ -344,7 +344,8 @@ unsigned int PowerShellClrManagedWorker::LoadWorkerCallbackPtrs(
// use CreateInstance because we use the assembly strong name (as opposed to CreateInstanceFrom)
//
// wszMgdPlugInFileName is %systemdir%\Windows\System32\WindowsPowerShell\v1.0\system.management.automation.dll.
// wszMgdPlugInFileName is system.management.automation.dll within the powershell install path.
// For inbox PowerShell, this is %systemdir%\Windows\System32\WindowsPowerShell\v1.0\system.management.automation.dll (Aka $PSHOME\system.management.automation.dll)
_bstr_t bstrConsoleHostAssemblyName = _bstr_t(L"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
_bstr_t bstrUnmanagedMshEntryClass = _bstr_t(L"System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper");