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}}
]