NETLink + CodeDOM 01 HelloNetWorld Revisited
- To: mathgroup at smc.vnet.net
- Subject: [mg47656] NETLink + CodeDOM 01 HelloNetWorld [mg45125] Revisited
- From: "ToolmakerSteve" <ToolmakerSteve at shawstudio.com>
- Date: Tue, 20 Apr 2004 03:19:25 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Incorporating fixes from Todd Gayley in January [mg45356], and a few minor tweaks. Now successfully creates a .NET Assembly File in: C:\Temp\01-HelloWorldMsg.exe Cut & 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]"}]], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(\((FileType /. FileInformation[ ToFileName[ Environment["\<WINDIR\>"], "\<assembly\>"]])\)\)], \ "Input"], Cell[BoxData[ TagBox["Directory", (Short[ #, 50]&)]], "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[CellGroupData[{ Cell[BoxData[ \(\(\( (*\(NETBlock\)\([\)*) \)\(\[IndentingNewLine]\)\(\(Module[\ \ { (*assemblyName, className, netSpace1, netImports1, spaceTypes1, netType1, main, snippet1, statement1, compUnit1, compParams, refAssemblies, csharp, cscompiler, result, errors, nErrors*) }, \ \[IndentingNewLine]\[IndentingNewLine]assemblyName = \ "\<MyNamespace\>"; \[IndentingNewLine]className = "\<HelloWorldMsgApp\ \>"; \[IndentingNewLine]outputPath = \ "\<c:\\Temp\\01-HelloWorldMsg.exe\>"; \[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 = assemblyName <> "\<.\>" <> className; \[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]]\)\(\[IndentingNewLine]\) \( (*]*) \)\)\)\)], "Input"], Cell[BoxData[ \("netSpace1@Name:"["MyNamespace"]\)], "Print"], Cell[BoxData[ RowBox[{"\<\"spaceTypes1:\"\>", "[", InterpretationBox[\(\[LeftGuillemet]NETObject[ "System.CodeDom.CodeTypeDeclarationCollection"] \ \[RightGuillemet]\), NETLink`Objects`NETObject$335544321], "]"}]], "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"] }, Open ]] }, FrontEndVersion->"5.0 for Microsoft Windows", ScreenRectangle->{{0, 1280}, {0, 976}}, WindowSize->{689, 781}, WindowMargins->{{4, Automatic}, {4, Automatic}} ]