Re: NETLink + CodeDOM 01 HelloNetWorld Revisited
- To: mathgroup at smc.vnet.net
- Subject: [mg47702] Re: [mg47656] NETLink + CodeDOM 01 HelloNetWorld [mg45125] Revisited
- From: "ToolmakerSteve" <ToolmakerSteve at shawstudio.com>
- Date: Thu, 22 Apr 2004 02:39:11 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Added code to **run** the newly created .NET assembly: The "Hello, Net World!" MessageBox appears. Showed TWO different ways to do this: 1. Using NET Reflection/Invoke function. 2. Using NETLink's LoadNETAssembly, after which can call as a Mathematica function: HelloWorldMsgApp'Main[] Paste the following Notebook Expression into any open notebook. - - - - - - - - - - Notebook[{ Cell[BoxData[ RowBox[{"(*", " ", RowBox[{ RowBox[{ StyleBox[\(\(--\(--\(-\ 01\)\)\) - NetLink + CodeDom - \(\(Tests\ --\)--\) - \), FontFamily->"Arial", FontSize->16], " ", ";", "\[IndentingNewLine]", \(Makes\ an\ assembly\), ";", " ", \(Running\ that\ shows\ "\<Hello, Net World\>"\), ";", "\[IndentingNewLine]", \(By : \ ToolMakerSteve\ at\ shawstudio . com\)}], ",", " ", \(April\ 2004. \[IndentingNewLine]\[IndentingNewLine] NOTE : \ If\ you\ want\ to\ experiment\ with\ the\ different\ \ objects\ created\ along\ the\ way\), ",", " ", \(then\ comment\ out\ THREE\ \(places : \ \ \ \ "\<NetBlock[\>"\)\), ",", " ", "\"\<]\>\"", ",", " ", \(and\ the\ module\ locals\ \ "\<assemblyName,...,nErrors\>"; \[IndentingNewLine]these\ are\ marked\ \ with\ \(\*"\"\<\!\( (*\(<\)\(\(--Comment\)\\\ out\\\ to\\\ \ \(\(experiment\)\(.\)\)\)*) \)\>\"" . \[IndentingNewLine]For\ \ example, \ notebook #02 - Net - Object - Reflection\ contains\ an\ Example\[IndentingNewLine] "\<Examine object in nb#01...\>", \ which\ requires\ access\ to\ those\ \ \(\(values\)\(.\)\)\)\)}], "\[IndentingNewLine]", "*)"}]], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(\((FileType /. FileInformation[ ToFileName[ Environment["\<WINDIR\>"], "\<assembly\>"]])\)\)], \ "Input"], Cell[BoxData[ \(Directory\)], "Output"] }, Open ]], Cell[BoxData[ \(\(\( (*\ \(--\(-\ Quiet\)\)\ spell\ warnings\ + \ limit\ output\ \(length\ --\) - \ *) \)\(\n\)\(Off[ General::spell]; \ \ \ Off[General::spell1];\n \($PrePrint = Short[#, 50] &;\)\)\)\)], "Input"], Cell[CellGroupData[{ Cell[BoxData[{ \(Needs["\<NETLink`\>"]\), "\[IndentingNewLine]", \(\(\(InstallNET[]\)\(\[IndentingNewLine]\)\(\[IndentingNewLine]\)\ \) (*\ \(\(\(\(\(--\(--\(-\ Print\)\)\)\ a\ NET\ Object\ normally\ &\)\ as\ \ a\ Math' a\ \(\(expression\ --\)--\)\)\(-\)\);\)\ *) \), "\ \[IndentingNewLine]", \(\(NETObPrint[\ netObject_\ ] := {netObject, \[IndentingNewLine]netObject // NETObjectToExpression} // Print;\)\), "\[IndentingNewLine]", \(\(NETObPrint[\ netObject_, message_\ ] := message[\ netObject, \[IndentingNewLine]netObject // NETObjectToExpression\ ] // Print;\)\[IndentingNewLine]\[IndentingNewLine] (*\ "\<net1 \ | net2\>"\ *) \), "\[IndentingNewLine]", \(\(\(NetBitOr[\ net1_, net2_\ ] := \[IndentingNewLine]BitOr[\ NETObjectToExpression[\ net1\ ], NETObjectToExpression[\ net2\ ]\ ];\)\(\[IndentingNewLine]\) \)\), "\[IndentingNewLine]", \(\(LoadNETType[\ "\<System.Enum\>"\ ];\)\ \[IndentingNewLine] \ (*\ Hard\ to\ decide\ when\ to\ switch\ back\ from\ Math' a\ to\ Net\ object; \[IndentingNewLine]Here, \ or\ in\ \(\(NetBitOr\)\(?\)\); \ \ Decided\ "\<Here\>";\ \[IndentingNewLine]*) \), "\[IndentingNewLine]", \(\(\(MakeEnum[\ mathValue_, netType_\ ] := \[IndentingNewLine]Enum`ToObject[\ netType, \ MakeNETObject[\ mathValue\ ]\ ];\)\(\[IndentingNewLine]\) \)\), "\[IndentingNewLine]", \(\(memberAttributesType\ = \ GetTypeObject[\ LoadNETType[\ "\<System.CodeDom.MemberAttributes\>"\ ]\ \ ];\)\ \[IndentingNewLine]\[IndentingNewLine] (*\ "\<net1 | net2\>"\ \ for\ CodeDom . \(MemberAttributes\ --\); \[IndentingNewLine]Work - Around\ . NET\ Bug\ \(\((missing\ "\<Flags\>"\ Attribute\ on\ \ MemberAttributes)\)\(.\)\)\ *) \), "\[IndentingNewLine]", \(\(NetMergeAttributes[\ net1_, net2_\ ] := MakeEnum[\ NetBitOr[\ net1, \ net2\ ], memberAttributesType\ ];\)\[IndentingNewLine]\ \[IndentingNewLine] (*\ \(--\(--\(-\ Csharp\)\)\)\ Compile - Assembly - From - \(\(Dom\ --\)--\) - ; \[IndentingNewLine]RETURN : \ csharp@\(CreateCompiler[]@ CompileAssemblyFromDom[\ compParams, \ compUnit\ ]\);\[IndentingNewLine]*) \), "\ \[IndentingNewLine]", \(\(CsharpCompileAssemblyFromDom[\ compParams_, \ compUnit_\ ] := \[IndentingNewLine]Module[\ {csharp, cscompiler, iCodeCompilerType, compileMethod}, \[IndentingNewLine]csharp = NETNew[\ \ "\<Microsoft.CSharp.CSharpCodeProvider\>"\ ]; \ \[IndentingNewLine]cscompiler = csharp@CreateCompiler[]; \ \[IndentingNewLine]iCodeCompilerType = GetTypeObject[\ LoadNETType[\ \ "\<System.CodeDom.Compiler.ICodeCompiler\>"\ ]\ ]; \ \[IndentingNewLine]compileMethod = \ iCodeCompilerType@ GetMethod[\ "\<CompileAssemblyFromDom\>"\ ]; \ \ \[IndentingNewLine]compileMethod@ Invoke[\ cscompiler, \ {compParams, \ compUnit}\ \ ]\[IndentingNewLine]];\)\[IndentingNewLine]\[IndentingNewLine] (*\ RETURN : \ A\ M' a\ list\ of\ Net\ Objects\ contained\ in\ a\ Net\ \ Collection; \[IndentingNewLine]So\ can\ operate\ on\ the\ individual\ \ Net\ Objects;\[IndentingNewLine]*) \), "\[IndentingNewLine]", \(\(\(NetAsList[\ netCollection_\ ] := \[IndentingNewLine]Module[\ \ {expressions}, \[IndentingNewLine]expressions = NETObjectToExpression[\ netCollection\ ]; \[IndentingNewLine]Map[\ MakeNETObject, expressions\ \ ]\[IndentingNewLine]];\)\(\[IndentingNewLine]\) \)\), "\[IndentingNewLine]", \(\(AddImport[\ importName1_String, netImports_\ ] := \[IndentingNewLine]netImports@ Add[\ NETNew[\ "\<System.CodeDom.CodeNamespaceImport\>", importName1\ ]\ ];\)\[IndentingNewLine]\ \[IndentingNewLine] (*\ "\<imports\>"\ is\ a\ list\ of\ Strings; \ \[IndentingNewLine]Each\ string\ is\ the\ path\ of\ an\ import; \ \[IndentingNewLine]e . g . \ "\<System.Windows.Forms\>" . \[IndentingNewLine]*) \), \ "\[IndentingNewLine]", \(\(AddImports[\ imports_, netSpace1_\ ] := \[IndentingNewLine]Module[\ {netImports}, \ \[IndentingNewLine]netImports = netSpace1@Imports; \[IndentingNewLine]Map[\ AddImport[\ #, netImports\ ] &, imports\ ];\[IndentingNewLine]];\)\)}], "Input"], Cell[BoxData[ TagBox[\(LinkObject[ "C:\\Program Files\\Wolfram \ Research\\Mathematica\\5.0\\AddOns\\NETLink\\InstallableNET.exe", 2, 2]\), (Short[ #, 50]&)]], "Output"] }, Open ]], Cell[BoxData[ \(\(\(\[IndentingNewLine]\)\( (*\ \ \(--\(--\(--\(--\(-\(--\(--\(-\(-\ \(\(\(\(\(\(\(GLOBALS\ \ --\)--\)--\)--\)--\)--\)--\)\)\)\)\)\)\)\)\)\)\(-\)\ *) \)\(\ \[IndentingNewLine]\)\(\[IndentingNewLine]\)\(\(outputPath = \ "\<c:\\Temp\\01-HelloWorldMsg.exe\>";\)\[IndentingNewLine] \(assemblyName = "\<MyNamespace\>";\)\[IndentingNewLine] \(className = "\<HelloWorldMsgApp\>";\)\[IndentingNewLine] \(fullClassPath = assemblyName <> "\<.\>" <> className;\)\)\)\)], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(\(\(result\)\(=\)\(\[IndentingNewLine]\)\(NETBlock[\ (*\(<\)\(\ \(--Comment\)\ out\ to\ \(\(experiment\)\(.\)\)\)\ *) \[IndentingNewLine]Module[\ {\[IndentingNewLine]netSpace1, netImports1, spaceTypes1, netType1, main, snippet1, statement1, compUnit1, compParams, refAssemblies, csharp, cscompiler, result, errors, nErrors\ \ (*\(<\)\(\(--Comment\)\ out\ to\ \ \(\(experiment\)\(.\)\)\)*) \[IndentingNewLine]}, \[IndentingNewLine]\ \[IndentingNewLine] (*\ Load\ type \((s)\)\ to\ call\ static\ \ \(\(members\)\(.\)\)*) \[IndentingNewLine]LoadNETType[\ \ "\<System.CodeDom.MemberAttributes\>"\ ]; \[IndentingNewLine]\ \[IndentingNewLine]netSpace1 = NETNew[\ "\<System.CodeDom.CodeNamespace\>"\ ]; \ \[IndentingNewLine]netSpace1@Name = assemblyName; \[IndentingNewLine]"\<netSpace1@Name:\>"[\ netSpace1@Name\ ] // Print; \[IndentingNewLine]spaceTypes1 = netSpace1@Types; \[IndentingNewLine]"\<spaceTypes1:\>"[\ spaceTypes1\ ] // Print; \[IndentingNewLine]"\<spaceTypes1@Count:\>"[\ spaceTypes1@Count\ ] // Print; \[IndentingNewLine]\[IndentingNewLine]netImports1 \ = netSpace1@ Imports; \[IndentingNewLine]AddImports[\ \[IndentingNewLine]{"\<System\>", "\<System.Windows.Forms\>"}, \ \[IndentingNewLine]netSpace1\ ]; \[IndentingNewLine]\ \[IndentingNewLine]netType1 = NETNew[\ "\<System.CodeDom.CodeTypeDeclaration\>"\ ]; \ \[IndentingNewLine]netType1@Name = className; \[IndentingNewLine]netType1@IsClass = True; \[IndentingNewLine]netType1@Attributes = MemberAttributes`Public; \[IndentingNewLine]spaceTypes1@ Add[\ netType1\ ]; \ \[IndentingNewLine]"\<spaceTypes1@Count:\>"[\ spaceTypes1@Count\ ] // Print; \[IndentingNewLine]"\<(spaceTypes1@Item[ 0 \ ])@Name:\>"[\ \((spaceTypes1@Item[\ 0\ ])\)@Name\ ] // Print; \[IndentingNewLine]\[IndentingNewLine]main = NETNew[\ "\<System.CodeDom.CodeEntryPointMethod\>"\ ]; \ \[IndentingNewLine]main@Name = "\<Main\>"; \[IndentingNewLine]main@ Attributes = NetMergeAttributes[\ MemberAttributes`Public, MemberAttributes`Static\ ]; \ \[IndentingNewLine]NETObPrint[\ main@Attributes, "\<main@Attributes\>"\ ]; \ \[IndentingNewLine]\((netType1@Members)\)@ Add[\ main\ ]; \[IndentingNewLine]"\<# \ netType1@Members:\>"[\ \((netType1@Members)\)@Count\ ] // Print; \[IndentingNewLine]\[IndentingNewLine]snippet1 = NETNew[\ "\<System.CodeDom.CodeSnippetExpression\>", \ \[IndentingNewLine]"\<MessageBox.Show( \"Hello, .NET World!\" )\>"\ \ ]; \[IndentingNewLine]statement1 = NETNew[\ "\<System.CodeDom.CodeExpressionStatement\>", snippet1\ ]; \[IndentingNewLine]\((main@Statements)\)@ Add[\ statement1\ ]; \[IndentingNewLine]"\<# \ Statements:\>"[\ \((main@Statements)\)@Count\ ] // Print; \[IndentingNewLine]"\<Statement 1:\>"[\ \((\((main@ Statements)\)[\ 0\ ]@Expression)\)@ Value\ ] // Print; \[IndentingNewLine]\[IndentingNewLine]compUnit1 = NETNew[\ \ "\<System.CodeDom.CodeCompileUnit\>"\ ]; \ \[IndentingNewLine]\((compUnit1@Namespaces)\)@ Add[\ netSpace1\ ]; \[IndentingNewLine]compParams = NETNew[\ \ \ "\<System.CodeDom.Compiler.CompilerParameters\>"\ ]; \ \[IndentingNewLine]refAssemblies = compParams@ ReferencedAssemblies; \[IndentingNewLine]refAssemblies@ Add[\ "\<mscorlib.dll\>"\ ]; \ \[IndentingNewLine]refAssemblies@ Add[\ "\<System.dll\>"\ ]; \ \[IndentingNewLine]refAssemblies@ Add[\ "\<System.Drawing.dll\>"\ ]; \ \[IndentingNewLine]refAssemblies@ Add[\ "\<System.Windows.Forms.dll\>"\ ]; \ \[IndentingNewLine]"\<# refAssemblies:\>"[\ refAssemblies@Count\ ] // Print; \[IndentingNewLine]compParams@GenerateInMemory = False; \[IndentingNewLine]compParams@GenerateExecutable = True; \[IndentingNewLine]compParams@MainClass = fullClassPath; \[IndentingNewLine]"\<MainClass: \>" <> \ \((compParams@MainClass)\) // Print; \[IndentingNewLine]"\<outputPath: \>" <> \ \((compParams@OutputAssembly = outputPath)\) // Print; \[IndentingNewLine]\[IndentingNewLine] (*\ Code\ snippets\ were\ given\ in\ c #, \ so\ use\ c #\ \(\(compiler\)\(.\)\)\ \ *) \[IndentingNewLine]result = CsharpCompileAssemblyFromDom[\ compParams, \ compUnit1\ ]; \[IndentingNewLine]\[IndentingNewLine] \ (*\ Check\ for\ \(\(errors\)\(.\)\)\ *) \[IndentingNewLine]nErrors = result@\(Errors@Count\); \[IndentingNewLine]If[\ nErrors > 0, \[IndentingNewLine] (*\ Make\ list\ of\ error\ objects\ \ *) \[IndentingNewLine]errors = NetAsList[\ result@ Errors\ ]; \ \[IndentingNewLine]\[IndentingNewLine]\(("\<***Compilation Error(s): \ \>" <> ToString[\ nErrors\ ])\) @@ Map[\ #@ErrorText &, errors\ ] // Print;\[IndentingNewLine]\[IndentingNewLine], "\<NO \ ERRORS :-)\>" // Print\[IndentingNewLine]]; \[IndentingNewLine]\ \[IndentingNewLine]result\[IndentingNewLine]]\[IndentingNewLine]]\)\(\ \ \)\( (*\(<\)\(\(--Comment\)\ out\ to\ \(\(experiment\)\(.\)\)\)*) \ \)\)\)], "Input"], Cell[BoxData[ \("netSpace1@Name:"["MyNamespace"]\)], "Print"], Cell[BoxData[ RowBox[{"\<\"spaceTypes1:\"\>", "[", InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.CodeDom.CodeTypeDeclarationCollection"] \ \[RightGuillemet]\), NETLink`Objects`NETObject$100663297], "]"}]], "Print"], Cell[BoxData[ \("spaceTypes1@Count:"[0]\)], "Print"], Cell[BoxData[ \("spaceTypes1@Count:"[1]\)], "Print"], Cell[BoxData[ \("(spaceTypes1@Item[ 0 ])@Name:"[ "HelloWorldMsgApp"]\)], "Print"], Cell[BoxData[ RowBox[{"\<\"main@Attributes\"\>", "[", RowBox[{ InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.CodeDom.MemberAttributes"] \[RightGuillemet]\), NETLink`Objects`NETObject$412367192066], ",", "24579"}], "]"}]], "Print"], Cell[BoxData[ \("# netType1@Members:"[1]\)], "Print"], Cell[BoxData[ \("# Statements:"[1]\)], "Print"], Cell[BoxData[ \("Statement 1:"[ "MessageBox.Show( \"Hello, .NET World!\" )"]\)], "Print"], Cell[BoxData[ \("# refAssemblies:"[4]\)], "Print"], Cell[BoxData[ \("MainClass: MyNamespace.HelloWorldMsgApp"\)], "Print"], Cell[BoxData[ \("outputPath: c:\\Temp\\01-HelloWorldMsg.exe"\)], "Print"], Cell[BoxData[ \("NO ERRORS :-)"\)], "Print"], Cell[BoxData[ TagBox[ InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.CodeDom.Compiler.CompilerResults"] \ \[RightGuillemet]\), NETLink`Objects`NETObject$402653185], (Short[ #, 50]&)]], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(\(\( (*\ \(--\(--\(-\ Run\)\)\)\ the\ assembly, \ using\ NET\ Reflection/ Invoke . \ \(--\(---\)\)\ \ *) \)\(\[IndentingNewLine]\)\(assembly1 = result@CompiledAssembly\[IndentingNewLine] main1 = assembly1@EntryPoint\[IndentingNewLine] nullOb = MakeNETObject[\ Null\ ]\[IndentingNewLine] noParameters = MakeNETObject[\ {}, "\<System.Object[]\>"\ ]\[IndentingNewLine]\ \[IndentingNewLine] (*\ \(--\ Call\)\ assembly' s\ main - class' es\ "\<main()\>"\ - \ the\ \("\<Hello, Net World\>"!\)\ MessageBox\ appears\ - \ this\ notebook\ stays\ "\<Running\>"\ until\ it\ is\ closed . \ \ --\ *) \[IndentingNewLine] main1@Invoke[\ nullOb, noParameters\ ]\[IndentingNewLine] \)\)\)], "Input"], Cell[BoxData[ TagBox[ InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.Reflection.Assembly"] \[RightGuillemet]\), NETLink`Objects`NETObject$436207617], (Short[ #, 50]&)]], "Output"], Cell[BoxData[ TagBox[ InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.Reflection.RuntimeMethodInfo"] \ \[RightGuillemet]\), NETLink`Objects`NETObject$3990411500584961], (Short[ #, 50]&)]], "Output"], Cell[BoxData[ TagBox[ InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.Object[]"] \[RightGuillemet]\), NETLink`Objects`NETObject$452984833], (Short[ #, 50]&)]], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(\(\( (*\ \(--\(--\(-\ Run\)\)\)\ the\ assembly, \ using\ NETLink\ functions . \ \(--\(---\)\)\ *) \)\(\ \[IndentingNewLine]\)\(LoadNETAssembly[\ outputPath\ ]\[IndentingNewLine] LoadNETType[\ fullClassPath\ ]\[IndentingNewLine]\[IndentingNewLine] (*\ \(\ --\ the\)\ \("\<Hello, Net World\>"!\)\ MessageBox\ appears\ - \ this\ notebook\ stays\ "\<Running\>"\ until\ it\ is\ closed . \ \ --\ *) \[IndentingNewLine] HelloWorldMsgApp`Main[]\)\)\)], "Input"], Cell[BoxData[ TagBox[\(NETAssembly["01-HelloWorldMsg", 3]\), (Short[ #, 50]&)]], "Output"], Cell[BoxData[ TagBox[\(NETType["MyNamespace.HelloWorldMsgApp", 27]\), (Short[ #, 50]&)]], "Output"] }, Open ]] }, FrontEndVersion->"5.0 for Microsoft Windows", ScreenRectangle->{{0, 1280}, {0, 976}}, WindowSize->{688, 781}, WindowMargins->{{4, Automatic}, {4, Automatic}} ]