<Member Name="GetFolderPath(System.Environment+SpecialFolder)" Condition="FEATURE_LEGACYSURFACE" />
<Member Name="GetEnvironmentVariable(System.String)" />
<Member Name="GetEnvironmentVariables" />
+ <Member Name="GetCommandLineArgs" />
<Member Name="SetEnvironmentVariable(System.String,System.String)" />
<Member Name="ExpandEnvironmentVariables(System.String)" />
<Member MemberType="Property" Name="OSVersion" />
<Member MemberType="Property" Name="TickCount" />
<Member MemberType="Property" Name="Version" />
<Member MemberType="Property" Name="ExitCode" />
- <Member Status="ImplRoot" Name="GetResourceStringLocal(System.String)" />
+ <Member Status="ImplRoot" Name="GetResourceStringLocal(System.String)" />
+ <Member Status="ImplRoot" Name="SetCommandLineArgs(System.String[])" />
<Member Name="FailFast(System.String)" />
<Member Name="FailFast(System.String,System.Exception)" />
- <Member Name="Exit(System.Int32)" />
+ <Member Name="Exit(System.Int32)" />
<Member Status="ApiFxInternal" Name="UnsafeGetFolderPath(System.Environment+SpecialFolder)" Condition="FEATURE_LEGACYSURFACE" />
</Type>
<Type Name="System.Environment+SpecialFolder" Condition="FEATURE_LEGACYSURFACE">
}
}
-#if !FEATURE_CORECLR
/*==============================GetCommandLineArgs==============================
**Action: Gets the command line and splits it appropriately to deal with whitespace,
** quotes, and escape characters.
**Exceptions: None.
==============================================================================*/
[System.Security.SecuritySafeCritical] // auto-generated
- public static String[] GetCommandLineArgs() {
+ public static String[] GetCommandLineArgs()
+ {
new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Demand();
+#if FEATURE_CORECLR
+ /*
+ * There are multiple entry points to a hosted app.
+ * The host could use ::ExecuteAssembly() or ::CreateDelegate option
+ * ::ExecuteAssembly() -> In this particular case, the runtime invokes the main
+ method based on the arguments set by the host, and we return those arguments
+ *
+ * ::CreateDelegate() -> In this particular case, the host is asked to create a
+ * delegate based on the appDomain, assembly and methodDesc passed to it.
+ * which the caller uses to invoke the method. In this particular case we do not have
+ * any information on what arguments would be passed to the delegate.
+ * So our best bet is to simply use the commandLine that was used to invoke the process.
+ * in case it is present.
+ */
+ if(s_CommandLineArgs != null)
+ return s_CommandLineArgs;
+#endif
return GetCommandLineArgsNative();
}
[System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern String[] GetCommandLineArgsNative();
-
+
+#if !FEATURE_CORECLR
// We need to keep this Fcall since it is used in AppDomain.cs.
// If we call GetEnvironmentVariable from AppDomain.cs, we will use StringBuilder class.
// That has side effect to change the ApartmentState of the calling Thread to MTA.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String nativeGetEnvironmentVariable(String variable);
#endif //!FEATURE_CORECLR
-
+
+#if FEATURE_CORECLR
+ private static string[] s_CommandLineArgs = null;
+ private static void SetCommandLineArgs(string[] cmdLineArgs)
+ {
+ s_CommandLineArgs = cmdLineArgs;
+ }
+#endif
+
/*============================GetEnvironmentVariable============================
**Action:
**Returns:
}
#ifdef FEATURE_CORECLR
+/*
+ * This method processes the arguments sent to the host which are then used
+ * to invoke the main method.
+ * Note -
+ * [0] - points to the assemblyName that has been sent by the host.
+ * The rest are the arguments sent to the assembly.
+ * Also note, this might not always return the exact same identity as the cmdLine
+ * used to invoke the method.
+ *
+ * For example :-
+ * ActualCmdLine - Foo arg1 arg2.
+ * (Host1) - Full_path_to_Foo arg1 arg2
+*/
+void SetCommandLineArgs(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR* argv)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_COOPERATIVE;
+ }
+ CONTRACTL_END;
+
+ struct _gc
+ {
+ PTRARRAYREF cmdLineArgs;
+ } gc;
+
+ ZeroMemory(&gc, sizeof(gc));
+ GCPROTECT_BEGIN(gc);
+
+ gc.cmdLineArgs = (PTRARRAYREF)AllocateObjectArray(argc + 1 /* arg[0] should be the exe name*/, g_pStringClass);
+ OBJECTREF orAssemblyPath = StringObject::NewString(pwzAssemblyPath);
+ gc.cmdLineArgs->SetAt(0, orAssemblyPath);
+
+ for (int i = 0; i < argc; ++i)
+ {
+ OBJECTREF argument = StringObject::NewString(argv[i]);
+ gc.cmdLineArgs->SetAt(i + 1, argument);
+ }
+
+ MethodDescCallSite setCmdLineArgs(METHOD__ENVIRONMENT__SET_COMMAND_LINE_ARGS);
+
+ ARG_SLOT args[] =
+ {
+ ObjToArgSlot(gc.cmdLineArgs),
+ };
+ setCmdLineArgs.Call(args);
+
+ GCPROTECT_END();
+}
+
HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
LPCWSTR pwzAssemblyPath,
int argc,
{
GCX_COOP();
+ // Here we call the managed method that gets the cmdLineArgs array.
+ SetCommandLineArgs(pwzAssemblyPath, argc, argv);
+
PTRARRAYREF arguments = NULL;
-
GCPROTECT_BEGIN(arguments);
-
+
arguments = (PTRARRAYREF)AllocateObjectArray(argc, g_pStringClass);
-
for (int i = 0; i < argc; ++i)
{
STRINGREF argument = StringObject::NewString(argv[i]);
FCFuncElement("nativeGetEnvironmentVariable", SystemNative::_GetEnvironmentVariable)
FCFuncElement("GetCompatibilityFlag", SystemNative::_GetCompatibilityFlag)
QCFuncElement("GetCommandLine", SystemNative::_GetCommandLine)
- FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
FCFuncElement("GetResourceFromDefault", GetResourceFromDefault)
#endif // !FEATURE_CORECLR
+ FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
QCFuncElement("WinRTSupported", SystemNative::WinRTSupported)
DEFINE_METASIG_T(SM(Str_CultureInfo_RetStr, s C(CULTURE_INFO), s))
DEFINE_METASIG_T(SM(Str_CultureInfo_RefBool_RetStr, s C(CULTURE_INFO) r(F), s))
DEFINE_METASIG(IM(Str_ArrStr_ArrStr_RetVoid, s a(s) a(s), v))
+DEFINE_METASIG(SM(ArrStr_RetVoid, a(s), v))
DEFINE_METASIG(IM(Str_RetVoid, s, v))
DEFINE_METASIG(SM(RefBool_RefBool_RetVoid, r(F) r(F), v))
DEFINE_METASIG_T(IM(Str_Exception_RetVoid, s C(EXCEPTION), v))
DEFINE_CLASS(ENVIRONMENT, System, Environment)
DEFINE_METHOD(ENVIRONMENT, GET_RESOURCE_STRING_LOCAL, GetResourceStringLocal, SM_Str_RetStr)
+DEFINE_METHOD(ENVIRONMENT, SET_COMMAND_LINE_ARGS, SetCommandLineArgs, SM_ArrStr_RetVoid)
#ifdef FEATURE_COMINTEROP
DEFINE_CLASS(ERROR_WRAPPER, Interop, ErrorWrapper)