-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[Single-Exe] Run from bundle #26504
[Single-Exe] Run from bundle #26504
Changes from all commits
071fafa
3ea260d
2e19196
c7ec374
c3f3014
ca8fb68
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,6 @@ | |
|
||
#include "assemblybinder.hpp" | ||
#include "assemblyname.hpp" | ||
|
||
#include "assembly.hpp" | ||
#include "applicationcontext.hpp" | ||
#include "loadcontext.hpp" | ||
|
@@ -645,19 +644,23 @@ namespace BINDER_SPACE | |
|
||
_ASSERTE(ppSystemAssembly != NULL); | ||
|
||
StackSString sCoreLibDir(systemDirectory); | ||
ReleaseHolder<Assembly> pSystemAssembly; | ||
StackSString sCoreLib; | ||
|
||
// For normal runs, corelib is expected to be found in systemDirectory. | ||
// For self-contained single-file bundles, corelib is expected within the bundle | ||
// (systemDirectory is set accordingly) | ||
|
||
StackSString sCoreLibDir(systemDirectory); | ||
if (!sCoreLibDir.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) | ||
{ | ||
sCoreLibDir.Append(DIRECTORY_SEPARATOR_CHAR_W); | ||
} | ||
|
||
StackSString sCoreLib; | ||
|
||
// At run-time, System.Private.CoreLib.dll is expected to be the NI image. | ||
sCoreLib = sCoreLibDir; | ||
sCoreLib.Append(CoreLibName_IL_W); | ||
|
||
// At run-time, System.Private.CoreLib.dll is expected to be the NI image. | ||
BOOL fExplicitBindToNativeImage = (fBindToNativeImage == true)? TRUE:FALSE; | ||
#ifdef FEATURE_NI_BIND_FALLBACK | ||
// Some non-Windows platforms do not automatically generate the NI image as CoreLib.dll. | ||
|
@@ -667,7 +670,9 @@ namespace BINDER_SPACE | |
IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLib, | ||
TRUE /* fIsInGAC */, | ||
fExplicitBindToNativeImage, | ||
&pSystemAssembly)); | ||
&pSystemAssembly, | ||
NULL /* szMDAssemblyPath */, | ||
Bundle::ProbeAppBundle(CoreLibName_IL_W, /* pathIsBundleRelative */ true))); | ||
|
||
*ppSystemAssembly = pSystemAssembly.Extract(); | ||
|
||
|
@@ -708,7 +713,9 @@ namespace BINDER_SPACE | |
IF_FAIL_GO(AssemblyBinder::GetAssembly(sMscorlibSatellite, | ||
TRUE /* fIsInGAC */, | ||
FALSE /* fExplicitBindToNativeImage */, | ||
&pSystemAssembly)); | ||
&pSystemAssembly, | ||
NULL /* szMDAssemblyPath */, | ||
Bundle::ProbeAppBundle(sMscorlibSatellite))); | ||
|
||
*ppSystemAssembly = pSystemAssembly.Extract(); | ||
|
||
|
@@ -873,7 +880,9 @@ namespace BINDER_SPACE | |
// specified. Generally only NGEN PDB generation has | ||
// this TRUE. | ||
fExplicitBindToNativeImage, | ||
&pAssembly)); | ||
&pAssembly, | ||
NULL /* szMDAssemblyPath */, | ||
Bundle::ProbeAppBundle(assemblyPath))); | ||
#ifdef FEATURE_VERSIONING_LOG | ||
IF_FAIL_GO(LogAssemblyNameWhereRef(pApplicationContext, pAssembly)); | ||
#endif // FEATURE_VERSIONING_LOG | ||
|
@@ -1106,6 +1115,13 @@ namespace BINDER_SPACE | |
|
||
/* | ||
* BindByTpaList is the entry-point for the custom binding algorithm in CoreCLR. | ||
* | ||
* The search for assemblies will proceed in the following order: | ||
* | ||
* If this application is a single-file bundle, the meta-data contained in the bundle | ||
* will be probed to find the requested assembly. If the assembly is not found, | ||
* The list of platform assemblies (TPAs) are considered next. | ||
* | ||
* Platform assemblies are specified as a list of files. This list is the only set of | ||
* assemblies that we will load as platform. They can be specified as IL or NIs. | ||
* | ||
|
@@ -1158,13 +1174,55 @@ namespace BINDER_SPACE | |
pBindResult)); | ||
} | ||
} | ||
else | ||
else | ||
{ | ||
// Is assembly on TPA list? | ||
ReleaseHolder<Assembly> pTPAAssembly; | ||
SString &simpleName = pRequestedAssemblyName->GetSimpleName(); | ||
|
||
// Is assembly in the bundle? | ||
// Single-file bundle contents take precedence over TPA. | ||
// The list of bundled assemblies is contained in the bundle manifest, and NOT in the TPA. | ||
// Therefore the bundle is first probed using the assembly's simple name. | ||
// If found, the assembly is loaded from the bundle. | ||
if (Bundle::AppIsBundle()) | ||
{ | ||
SString candidates[] = { W(".dll"), W(".ni.dll") }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the .ni.dll stuff is still needed for managed c++ R2R at this time. |
||
|
||
// Loop through the binding paths looking for a matching assembly | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: This is not looping through paths, just candidate extensions - the comment is just confusing. |
||
for (int i = 0; i < 2; i++) | ||
{ | ||
SString assemblyFileName(simpleName); | ||
assemblyFileName.Append(candidates[i]); | ||
|
||
SString assemblyFilePath(Bundle::AppBundle->BasePath()); | ||
assemblyFilePath.Append(assemblyFileName); | ||
|
||
hr = GetAssembly(assemblyFilePath, | ||
TRUE, // fIsInGAC | ||
FALSE, // fExplicitBindToNativeImage | ||
&pTPAAssembly, | ||
NULL, // szMDAssemblyPath | ||
Bundle::ProbeAppBundle(assemblyFileName, /* pathIsBundleRelative */ true)); | ||
|
||
if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) | ||
{ | ||
// Any other error is fatal | ||
IF_FAIL_GO(hr); | ||
|
||
if (TestCandidateRefMatchesDef(pRequestedAssemblyName, pTPAAssembly->GetAssemblyName(), true /*tpaListAssembly*/)) | ||
{ | ||
// We have found the requested assembly match in the bundle with validation of the full-qualified name. | ||
// Bind to it. | ||
pBindResult->SetResult(pTPAAssembly); | ||
GO_WITH_HRESULT(S_OK); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Is assembly on TPA list? | ||
SimpleNameToFileNameMap * tpaMap = pApplicationContext->GetTpaList(); | ||
const SimpleNameToFileNameMapEntry *pTpaEntry = tpaMap->LookupPtr(simpleName.GetUnicode()); | ||
ReleaseHolder<Assembly> pTPAAssembly; | ||
if (pTpaEntry != nullptr) | ||
{ | ||
if (pTpaEntry->m_wszNIFileName != nullptr) | ||
|
@@ -1350,20 +1408,21 @@ namespace BINDER_SPACE | |
} | ||
|
||
/* static */ | ||
HRESULT AssemblyBinder::GetAssembly(SString &assemblyPath, | ||
BOOL fIsInGAC, | ||
HRESULT AssemblyBinder::GetAssembly(SString &assemblyPath, | ||
BOOL fIsInGAC, | ||
|
||
// When binding to the native image, should we | ||
// assume assemblyPath explicitly specifies that | ||
// NI? (If not, infer the path to the NI | ||
// implicitly.) | ||
BOOL fExplicitBindToNativeImage, | ||
BOOL fExplicitBindToNativeImage, | ||
|
||
Assembly **ppAssembly, | ||
Assembly **ppAssembly, | ||
|
||
// If assemblyPath refers to a native image without metadata, | ||
// szMDAssemblyPath gives the alternative file to get metadata. | ||
LPCTSTR szMDAssemblyPath) | ||
LPCTSTR szMDAssemblyPath, | ||
BundleFileLocation bundleFileLocation) | ||
{ | ||
HRESULT hr = S_OK; | ||
|
||
|
@@ -1387,7 +1446,7 @@ namespace BINDER_SPACE | |
LPCTSTR szAssemblyPath = const_cast<LPCTSTR>(assemblyPath.GetUnicode()); | ||
|
||
BINDER_LOG_ENTER(W("BinderAcquirePEImage")); | ||
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, fExplicitBindToNativeImage); | ||
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, fExplicitBindToNativeImage, bundleFileLocation); | ||
BINDER_LOG_LEAVE_HR(W("BinderAcquirePEImage"), hr); | ||
IF_FAIL_GO(hr); | ||
|
||
|
@@ -1404,7 +1463,7 @@ namespace BINDER_SPACE | |
BinderReleasePEImage(pNativePEImage); | ||
|
||
BINDER_LOG_ENTER(W("BinderAcquirePEImageIL")); | ||
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, false); | ||
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, false, bundleFileLocation); | ||
BINDER_LOG_LEAVE_HR(W("BinderAcquirePEImageIL"), hr); | ||
IF_FAIL_GO(hr); | ||
} | ||
|
@@ -1434,7 +1493,7 @@ namespace BINDER_SPACE | |
else | ||
{ | ||
BINDER_LOG_ENTER(W("BinderAcquirePEImage")); | ||
hr = BinderAcquirePEImage(szMDAssemblyPath, &pPEImage, NULL, FALSE); | ||
hr = BinderAcquirePEImage(szMDAssemblyPath, &pPEImage, NULL, FALSE, bundleFileLocation); | ||
BINDER_LOG_LEAVE_HR(W("BinderAcquirePEImage"), hr); | ||
IF_FAIL_GO(hr); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nit - it seems this move was not necessary. It is better to keep the variable definition close to its first usage.