DotNet.au3 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include-once
  2. #include "Interfaces.au3"
  3. #include "AccVarsUtilities.au3"
  4. Func DotNet_Start( $sVersion = "" )
  5. Static $pRuntimeHost = 0, $oRuntimeHost
  6. If $pRuntimeHost Then Return $oRuntimeHost
  7. If $sVersion = "" Then
  8. Local $sPath = @WindowsDir & "\Microsoft.NET\Framework" & ( @AutoItX64 ? "64" : "" ) & "\"
  9. Local $hSearch = FileFindFirstFile( $sPath & "v?.*" ), $sFolder
  10. If $hSearch <> -1 Then
  11. While 1
  12. $sFolder = FileFindNextFile( $hSearch )
  13. Local $iError = @error, $iExtended = @extended
  14. If $iExtended = 1 And FileExists( $sPath & $sFolder & "\mscorlib.dll" ) And $sVersion < $sFolder Then $sVersion = $sFolder
  15. If $iError Then ExitLoop
  16. WEnd
  17. EndIf
  18. ElseIf Not FileExists( @WindowsDir & "\Microsoft.NET\Framework" & ( @AutoItX64 ? "64" : "" ) & "\" & $sVersion ) Then
  19. Return SetError( 1,0,0 )
  20. EndIf
  21. Local Const $tagGUID = "struct; ulong Data1;ushort Data2;ushort Data3;byte Data4[8]; endstruct"
  22. Local $tCLSID_CorRuntimeHost = DllStructCreate( $tagGUID )
  23. GUIDFromStringEx( $sCLSID_CorRuntimeHost, $tCLSID_CorRuntimeHost )
  24. Local $tIID_ICorRuntimeHost = DllStructCreate( $tagGUID )
  25. GUIDFromStringEx( $sIID_ICorRuntimeHost, $tIID_ICorRuntimeHost )
  26. Local $aRet = DllCall( "MSCorEE.dll", "long", "CorBindToRuntimeEx", "wstr", $sVersion, "ptr", NULL, "dword", 0, _
  27. "struct*", $tCLSID_CorRuntimeHost, "struct*", $tIID_ICorRuntimeHost, "ptr*", 0 )
  28. If Not ( @error = 0 And $aRet[0] = 0 And $aRet[6] ) Then Return SetError( 1,0,0 )
  29. $pRuntimeHost = $aRet[6]
  30. $oRuntimeHost = ObjCreateInterface( $pRuntimeHost, $sIID_ICorRuntimeHost, $sTag_ICorRuntimeHost )
  31. Return $oRuntimeHost
  32. EndFunc
  33. Func DotNet_StartDomain( ByRef $oAppDomain, $sFriendlyName = "", $sBaseDirectory = "" )
  34. Local $oDefDomain = DotNet_GetDefaultDomain()
  35. Local $pType, $oType
  36. $oDefDomain.GetType( $pType )
  37. $oType = ObjCreateInterface( $pType, $sIID__Type, $sTag__Type )
  38. Local $psaEmpty = SafeArrayCreateEmpty( $VT_VARIANT )
  39. Local $aArguments[5], $pSafeArray
  40. $aArguments[0] = $sFriendlyName
  41. $aArguments[2] = $sBaseDirectory
  42. $aArguments[4] = False
  43. AccVars_ArrayToSafeArray( $aArguments, $pSafeArray )
  44. $oType.InvokeMember_3( "CreateDomain", $BindingFlags_DefaultValue, $psaEmpty, $psaEmpty, $pSafeArray, $oAppDomain )
  45. EndFunc
  46. Func DotNet_StopDomain( ByRef $oAppDomain )
  47. Local $oRuntimeHost = DotNet_Start()
  48. $oRuntimeHost.UnloadDomain( Ptr( $oAppDomain ) )
  49. $oAppDomain = 0
  50. EndFunc
  51. ; Internal function
  52. Func DotNet_GetDefaultDomain()
  53. Static $pDefDomain = 0, $oDefDomain
  54. If $pDefDomain Then Return $oDefDomain
  55. Local $oRuntimeHost = DotNet_Start()
  56. $oRuntimeHost.Start()
  57. $oRuntimeHost.GetDefaultDomain( $pDefDomain )
  58. $oDefDomain = ObjCreateInterface( $pDefDomain, $sIID__AppDomain, $sTag__AppDomain )
  59. Return $oDefDomain
  60. EndFunc
  61. Func DotNet_LoadAssembly( $sAssemblyName, $oAppDomain = 0 )
  62. If Not $oAppDomain Then $oAppDomain = DotNet_GetDefaultDomain()
  63. Local $pType, $oType
  64. $oAppDomain.GetType( $pType )
  65. $oType = ObjCreateInterface( $pType, $sIID__Type, $sTag__Type )
  66. Local $pAssembly, $oAssembly
  67. $oType.get_Assembly( $pAssembly )
  68. $oAssembly = ObjCreateInterface( $pAssembly, $sIID__Assembly, $sTag__Assembly )
  69. Local $pAssemblyType, $oAssemblyType
  70. $oAssembly.GetType( $pAssemblyType )
  71. $oAssemblyType = ObjCreateInterface( $pAssemblyType, $sIID__Type, $sTag__Type )
  72. Local $aAssemblyName = [ $sAssemblyName ], $pSafeArray
  73. AccVars_ArrayToSafeArray( $aAssemblyName, $pSafeArray )
  74. Local $pNetCode
  75. $oAssemblyType.InvokeMember_3( "LoadFrom", $BindingFlags_DefaultValue, 0, 0, $pSafeArray, $pNetCode )
  76. ; We first try to load the .NET assembly with the LoadFrom method
  77. ; If LoadFrom method fails, we try to load the .NET assembly using the LoadWithPartialName method
  78. If Not Ptr( $pNetCode ) Then
  79. Local $iPos = StringInStr( $sAssemblyName, ".", Default, -1 )
  80. If StringRight( $sAssemblyName, StringLen( $sAssemblyName ) - $iPos ) = "dll" Then _ ; Use name of .NET assembly without DLL-
  81. $sAssemblyName = StringLeft( $sAssemblyName, $iPos - 1 ) ; extension in LoadWithPartialName method.
  82. $aAssemblyName[0] = $sAssemblyName
  83. AccVars_ArrayToSafeArray( $aAssemblyName, $pSafeArray )
  84. $oAssemblyType.InvokeMember_3( "LoadWithPartialName", $BindingFlags_DefaultValue, 0, 0, $pSafeArray, $pNetCode )
  85. ; LoadWithPartialName searches for the .NET assembly in the path given by $sBaseDirectory in DotNet_StartDomain
  86. EndIf
  87. If Not Ptr( $pNetCode ) Then Return SetError( 2,0,0 )
  88. Return ObjCreateInterface( $pNetCode, $sIID__Assembly, $sTag__Assembly )
  89. EndFunc
  90. Func DotNet_LoadCScode( $sCode, $sReferences = "", $oAppDomain = 0, $sFileName = "", $sCompilerOptions = "" )
  91. Local $oNetCode = DotNet_LoadCode( $sCode, $sReferences, "System", "Microsoft.CSharp.CSharpCodeProvider", $oAppDomain, $sFileName, $sCompilerOptions )
  92. If @error Then Return SetError( @error,0,0 )
  93. Return $oNetCode
  94. EndFunc
  95. Func DotNet_LoadVBcode( $sCode, $sReferences = "", $oAppDomain = 0, $sFileName = "", $sCompilerOptions = "" )
  96. Local $oNetCode = DotNet_LoadCode( $sCode, $sReferences, "System", "Microsoft.VisualBasic.VBCodeProvider", $oAppDomain, $sFileName, $sCompilerOptions )
  97. If @error Then Return SetError( @error,0,0 )
  98. Return $oNetCode
  99. EndFunc
  100. ; Internal function
  101. Func DotNet_LoadCode( $sCode, $sReferences, $sProviderAssembly, $sProviderType, $oAppDomain = 0, $sFileName = "", $sCompilerOptions = "" )
  102. If Not $oAppDomain Then $oAppDomain = DotNet_GetDefaultDomain()
  103. Local $oAsmProvider, $oCodeProvider, $oCodeCompiler, $oAsmSystem, $oPrms
  104. If IsObj( $oAppDomain ) Then $oAsmProvider = DotNet_LoadAssembly( $sProviderAssembly, $oAppDomain )
  105. If IsObj( $oAsmProvider ) Then $oAsmProvider.CreateInstance( $sProviderType, $oCodeProvider )
  106. If IsObj( $oCodeProvider ) Then $oCodeCompiler = $oCodeProvider.CreateCompiler()
  107. If IsObj( $oCodeCompiler ) Then $oAsmSystem = $sProviderAssembly = "System" ? $oAsmProvider : DotNet_LoadAssembly( "System", $oAppDomain )
  108. If Not IsObj( $oAsmSystem ) Then Return SetError( 3,0,0 )
  109. Local $aReferences = StringSplit( StringStripWS( StringRegExpReplace( $sReferences, "\s*\|\s*", "|" ), 3 ), "|", 2 ) ; 3 = $STR_STRIPLEADING + $STR_STRIPTRAILING, 2 = $STR_NOCOUNT
  110. Local $pSafeArray = AccVars_ArrayToSafeArrayOfVartype( $aReferences, $VT_BSTR )
  111. Local $psaVariant = AccVars_SafeArrayToSafeArrayOfVariant( $pSafeArray )
  112. Local $psaEmpty = SafeArrayCreateEmpty( $VT_VARIANT )
  113. ; Create $oPrms object
  114. $oAsmSystem.CreateInstance_3( "System.CodeDom.Compiler.CompilerParameters", True, 0, 0, $psaVariant, 0, $psaEmpty, $oPrms )
  115. If Not IsObj( $oPrms ) Then Return SetError( 4,0,0 )
  116. ; Set parameters for compiler
  117. $oPrms.OutputAssembly = $sFileName
  118. $oPrms.GenerateInMemory = ( $sFileName = "" )
  119. $oPrms.GenerateExecutable = ( StringRight( $sFileName, 4 ) = ".exe" )
  120. $oPrms.CompilerOptions = $sCompilerOptions
  121. $oPrms.IncludeDebugInformation = True
  122. ; Compile code
  123. Local $oCompilerRes = $oCodeCompiler.CompileAssemblyFromSource( $oPrms, $sCode )
  124. ; Compiler errors?
  125. If $oCompilerRes.Errors.Count() Then
  126. Local $b = False
  127. For $err In $oCompilerRes.Errors
  128. If $b Then ConsoleWrite( @CRLF )
  129. ConsoleWrite( "Line: " & $err.Line & @CRLF & "Column: " & $err.Column & @CRLF & $err.ErrorNumber & ": " & $err.ErrorText & @CRLF )
  130. $b = True
  131. Next
  132. Return SetError( 5,0,0 )
  133. EndIf
  134. If $sFileName Then
  135. Return $oCompilerRes.PathToAssembly()
  136. Else
  137. Local $pNetCode = $oCompilerRes.CompiledAssembly()
  138. Return ObjCreateInterface( $pNetCode, $sIID__Assembly, $sTag__Assembly )
  139. EndIf
  140. EndFunc
  141. Func DotNet_CreateObject( ByRef $oNetCode, $sClassName, $v3 = Default, $v4 = Default, $v5 = Default, $v6 = Default, $v7 = Default, $v8 = Default, $v9 = Default )
  142. Local $aParams = [ $v3, $v4, $v5, $v6, $v7, $v8, $v9 ], $oObject = 0
  143. If @NumParams = 2 Then
  144. $oNetCode.CreateInstance_2( $sClassName, True, $oObject )
  145. Return $oObject
  146. EndIf
  147. Local $iArgs = @NumParams - 2, $aArgs[$iArgs], $pSafeArray
  148. For $i = 0 To $iArgs - 1
  149. $aArgs[$i] = $aParams[$i]
  150. Next
  151. AccVars_ArrayToSafeArray( $aArgs, $pSafeArray )
  152. Local $psaEmpty = SafeArrayCreateEmpty( $VT_VARIANT )
  153. $oNetCode.CreateInstance_3( $sClassName, True, 0, 0, $pSafeArray, 0, $psaEmpty, $oObject )
  154. Return $oObject
  155. EndFunc