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