//clr 公共语言运行时 import win.ole; import com.interface; import dotNet.interface.ICLRMetaHost; import dotNet.interface.ICLRRuntimeInfo; import dotNet.interface.ICLRRuntimeHost; import dotNet.interface.ICorRuntimeHost; import dotNet.interface.IAppDomainSetup; import dotNet.appDomain; namespace dotNet; class clr{ ctor( version, ... ){ if( !version ) { return ..dotNet.clr("v4.0") || ..dotNet.clr("v2.0"); } if( ... ){ return ..dotNet.clr(version) || ..dotNet.clr(...); } if( version[1] != 'v'# ) version = "v" + version; if( ! ..string.match(version,"^v\d+[\d.]+$") ) return; if( ..string.startsWith( version,"v1.") ){ error("指定的.NET Framework 最低版本不能小于v2.0"); } if( version == "v2.0" || ..string.startsWith( version,"v3.") ){ version = "v2.0.50727"; this.majorVersion = 2; } elseif( version == "v4.0" || ..string.startsWith( version,"v4.") ){ //必须是 2 或 3 位版本号,CLR 4 只有这一个 3 位版本号,不能写 v4.0.30319.42000 version = "v4.0.30319"; this.majorVersion = 4; }; this.version = version; var hr,pRuntimeHost,pCorRuntimeHost; if( CLRCreateInstance ){ try{ this.metaHost = createInterface( CLSID_CLRMetaHost,..dotNet.interface.ICLRMetaHost ); var hr,pRuntimeInfo = this.metaHost.GetRuntime(version, ..dotNet.interface.ICLRRuntimeInfo.IID); if( (hr)<0/*_FAILED*/ ){ return null,..lasterr(hr,"ICLRMetaHost.GetRuntime()"); } this.runtimeInfo = ..com.interface(pRuntimeInfo,..dotNet.interface.ICLRRuntimeInfo ); ..com.Release(pRuntimeInfo) var hr,loadable = this.runtimeInfo.IsLoadable(); if( (hr)<0/*_FAILED*/ ){ return null,..lasterr(hr,"ICLRRuntimeInfo.IsLoadable()"); } if (!loadable) { return null,..string.format(".NET runtime %s cannot be loaded",version ) } //启用.net Framework 2.0 运行时激活策略 hr = this.runtimeInfo.BindAsLegacyV2Runtime(); if( (hr)<0/*_FAILED*/ ){ //return null,..lasterr(hr,"ICLRRuntimeInfo.BindAsLegacyV2Runtime()"); } this.runtimeInfo.SetDefaultStartupFlags(1/*STARTUP_CONCURRENT_GC*/ | ( 0x1 << 3 ) ,"" ); hr,pCorRuntimeHost = this.runtimeInfo.GetInterface(CLSID_CorRuntimeHost, ..dotNet.interface.ICorRuntimeHost.IID ) if( (hr)<0/*_FAILED*/ ){ return null,..lasterr(hr,"ICLRRuntimeInfo.GetInterface(CLSID_CorRuntimeHost)"); } hr,pRuntimeHost = this.runtimeInfo.GetInterface(CLSID_CLRRuntimeHost, ..dotNet.interface.ICLRRuntimeHost.IID ) if( (hr)<0/*_FAILED*/ ){ return null,..lasterr(hr,"ICLRRuntimeInfo.GetInterface(CLSID_CLRRuntimeHost)"); } } } if( CorBindToRuntimeEx && ( !(pCorRuntimeHost && pRuntimeHost ) ) ){ hr,pCorRuntimeHost = CorBindToRuntimeEx( version, "wks" ,1/*STARTUP_CONCURRENT_GC*/ | ( 0x3 << 1 ), CLSID_CorRuntimeHost,..dotNet.interface.ICorRuntimeHost.IID) if( (hr)<0/*_FAILED*/ ){ return null,..string.format(".NET runtime %s cannot be loaded",version ) } hr,pRuntimeHost = CorBindToRuntimeEx( version, "wks" , 1/*STARTUP_CONCURRENT_GC*/ | ( 0x3 << 1 ), CLSID_CLRRuntimeHost,..dotNet.interface.ICLRRuntimeHost.IID) if( (hr)<0/*_FAILED*/ ){ pRuntimeHost = null; } } if( pRuntimeHost ){ this.runtimeHost = ..com.interface(pRuntimeHost,..dotNet.interface.ICLRRuntimeHost ); ..com.Release(pRuntimeHost) } this.corRuntimeHost = ..com.interface(pCorRuntimeHost,..dotNet.interface.ICorRuntimeHost ); ..com.Release(pCorRuntimeHost) // Start the CLR. var hr = this.runtimeHost.Start(); if( (hr)<0/*_FAILED*/ ){ return null,..string.format("CLR failed to start w/hr 0x%08X",hr ) } var hr,pAppDomainSetup = this.corRuntimeHost.CreateDomainSetup(); if( (hr)<0/*_FAILED*/ ){ return null,..lasterr(hr,"ICorRuntimeHost.CreateDomainSetup()"); } ..com.Release(pAppDomainSetup) this.AppDomainSetupReal = ..com.interface(pAppDomainSetup,..dotNet.interface.IAppDomainSetup ); this.AppDomainSetup = { @{ _get = function(k){ var method = this.AppDomainSetupReal["get_"+k]; if( method ){ var hr,bstr = method(); if( (hr)>=0/*_SUCCEEDED*/ ){ return ..win.ole.fromSysString(bstr) } return; } }; _set = function(k,v){ var method = this.AppDomainSetupReal["put_"+k]; if( method ){ var bstr = ::SysAllocString( v ); method(bstr); ::SysFreeString(bstr); } }; _topointer = function(){ return this.AppDomainSetupReal; } } } this.AppDomainSetup.ApplicationBase = ..io.fullpath("/"); this.AppDomainSetup.PrivateBinPath = "bin"; this.createAppDomain = function(domainName){ return ..dotNet.appDomain(this,domainName) } }; } namespace clr{ var dll = ..raw.loadDll("MSCorEE.dll") try{ CLRCreateInstance = dll.api("CLRCreateInstance","int(struct clsid,struct riid,pointer &ppInterface)" ); } CorBindToRuntimeEx = dll.api("CorBindToRuntimeEx","int(ustring pwszVersion,ustring pwszBuildFlavor, INT startupFlags, struct rclsid, struct riid, pointer &ppv)" ); var guid = ..win.guid; CLSID_CLRMetaHost = guid( 0x9280188d, 0xe8e, 0x4867, { 0xb3; 0xc; 0x7f; 0xa8; 0x38; 0x84; 0xe8; 0xde } ); CLSID_CLRRuntimeHost = guid( 0x90F1A06E, 0x7712, 0x4762, { 0x86; 0xB5; 0x7A; 0x5E; 0xBA; 0x6B; 0xDB; 0x02 } ); CLSID_CorRuntimeHost = guid( 0xcb2f6723, 0xab3a, 0x11d2, { 0x9c; 0x40; 0x00; 0xc0; 0x4f; 0xa3; 0x0a; 0x3e } ) ..com.interface.checkInterface(..dotNet.interface.ICLRRuntimeInfo,2); ..com.interface.checkInterface(..dotNet.interface.ICLRRuntimeHost,2); ..com.interface.checkInterface(..dotNet.interface.ICorRuntimeHost,2); createInterface = function(clsid,itface){ if(type(clsid)==type.string) clsid = guid.fromString(clsid) ..com.interface.checkInterface(itface,2); var iid = itface.IID ; var hr,unknown = CLRCreateInstance(clsid,iid ); ..com.interface.checkError(hr,2); var iterface = ..com.interface(unknown,itface); ..com.Release(unknown) return iterface; } } if(..thread.getMainId() === ..thread.getId() ){ ..io.curDir("/"); } /**intellisense() dotNet.clr = CLR 运行时支持库。\n导入此库时如果当前是主线程则将应用程序根目录("/")设为当前目录。 dotNet.clr("v4->0") = 创建 CLR 运行时,\n可以使用多个参数指定多个允许加载的版本号,\n不指定参数可以自动选择合适的版本,\n如果之前已成功创建此对象,则会使用之前指定的 .Net 运行时版本,\n\n注意 .NET 3.5 的 CLR 运行时是 v2.0,.Net 4.x 的 CLR 运行时是 v4.0,\nWin7 自带 CLR 2.0运行时,Win10,Win11 自带 CLR 4.0 运行时\n\naardio 可以自适应 CLR 2.0/4.0,对 .Net 版本没有严格要求,\n一般不需要自己去创建应用程序域,例如加载程序集,直接写 \ndotNet.load 或 dotNet.loadFile 就可以 dotNet.clr() = !dotNetClr. !dotNetClr.runtimeHost = !dotNetCorRuntimeHost. !dotNetClr.createAppDomain(.("域名称") = 创建应用程序域,参数可选\n\n如果尚未创建默认单例应用程序域,\n则不指定 @domainName 参数时创建并返回为默认单例应用程序域,\n无参数调用 dotNet.appDomain 总是返回默认单例应用程序域,\n引入 dotNet 库也会自动创建默认应用程序域 !dotNetClr.createAppDomain() = !dotNetAppDomain. !dotNetClr.version = CLR 运行时版本。\n这个值只有可能是 "v2.0.50727" 或 "v4.0.30319"。\n注意 CLR 版本不完全等于 .NET 版本\n\n获取完整 CLR 版本号或检测 .NET Framework 版本请查看\naardio 提供的 System.Environment.Version 库 !dotNetClr.majorVersion = CLR 运行时版本号,数值。\n只有可能是 2 或 4,不会有其他主版本。\n\n注意 CLR 版本不完全等于 .NET 版本\n\n获取完整 CLR 版本号或检测 .NET Framework 版本请查看\naardio 提供的 System.Environment.Version 库 end intellisense**/ /**intellisense(!dotNetClr.AppDomainSetup) ApplicationBase=获取或设置包含该应用程序的目录的名称。 ApplicationName=获取或设置应用程序的名称。 CachePath=获取和设置特定于应用程序的区域名称,在该区域中影像复制文件。 ConfigurationFile=获取和设置应用程序域的配置文件的名称。 DynamicBase=获取或设置将在其中存储和访问动态生成文件的目录。 LicenseFile=获取或设置与此域关联的许可证文件的位置。 PrivateBinPath=获取或设置目录列表,它与 ApplicationBase 目录结合来探测专用程序集。 PrivateBinPathProbe=获取或设置用于定位应用程序的专用二进制目录路径。 ShadowCopyDirectories=获取或设置目录的名称,这些目录包含要影像复制的程序集。 ShadowCopyFiles=获取或设置指示影像复制是打开还是关闭的字符串 end intellisense**/ /**intellisense(!dotNetCorRuntimeHost) Stop() = 停止 .Net 运行时 end intellisense**/