MrSmith: VBCodeProvider - CompilerParameters - Wie kann man Referenzen hinzufügen?

Hallo.

Ganz kurz und knapp. Ich möchte mittels vb.net einen separaten Code on-the-run compilieren. Jedoch möchte ich dazu, wie es in Sharp Develop üblich ist, eine Referenz zu z. b. System.Windows.Forms festlegen.

Über Imports funktioniert es nicht, da ja keine Referenz dazu existiert.

Hier der Part, wo ich den Code kompilieren möchte:

Dim vbel As New VBCodeProvider()
Dim oCParams As New CompilerParameters()
Dim oCResults As CompilerResults = Nothing
oCParams.GenerateInMemory = True
Dim cr As System.CodeDom.Compiler.CompilerResults = vbel.CompileAssemblyFromSource(oCParams,richTextBox1.Text)

Und das wäre ein Beispiel für einen Code, welcher in der richTextBox1 steht:

Imports System.Windows.Forms

Public Class Test
	Public Sub Main()
		MessageBox.Show("Test")
	End Sub
End Class

Jedoch funktioniert der Import von System.Windows.Forms nicht.

Wer kann mir dabei helfen?

  1. Tach!

    Ganz kurz und knapp. Ich möchte mittels vb.net einen separaten Code on-the-run compilieren. Jedoch möchte ich dazu, wie es in Sharp Develop üblich ist, eine Referenz zu z. b. System.Windows.Forms festlegen.

    System.Windows.Forms ist erstmal nur ein Namespace. Was du auch noch brauchst, ist die Assembly, die die von dir verwendeten Klassen enthält. Es dürfte durchaus auch in SharpDevelop üblich sein, neben den Namespaces im Code auch noch die verwendeten Assemblys im Projektmanagement zu referenzieren. Wenn du Code selbst kompilieren möchtest, musst du das genauso beachten.

    Ein Namespace kann sich durchaus auf mehrere Assemblys verteilen. In welcher die von dir verwendeten Klassen zu finden sind, sagt deren Dokumentation. Die listet nicht nur den Namespace sondern auch die Assembly auf. Diese Assembly jedenfalls musst du als Compilerparameter angeben.

    dedlfix.

    1. Diese Assembly jedenfalls musst du als Compilerparameter angeben.

      Ja. Und wie mach ich das bitte?

      Denn ich finde ausschließlich Dokumentationen über das Compilieren von Sachen, die OHNE diese Namespaces arbeiten ... Also steht da auch nie bei, wie ich überhaupt diese Namespaces einbinden kann.

      Das ist ja der Punkt, den ich wissen möchte ... :/

    2. Ich habe es jetzt selbst lösen können.

      Da nirgends beschrieben wird, dass man bei ReferencedAssemblies nicht nur "System.Windows.Forms" sondern "System.Windows.Forms.dll" angeben muss, konnte ich dies nur über Try-Error-Versuche herausfinden.

      Nun habe ich mein Script (und das dazugehörige Tool) fertigstellen können :D

      Trotzdem danke, da ohne deine Info bezüglich der "Namespaces" wäre ich nie auf die Idee gekommen :D

      1. Tach!

        Da nirgends beschrieben wird, dass man bei ReferencedAssemblies nicht nur "System.Windows.Forms" sondern "System.Windows.Forms.dll" angeben muss, konnte ich dies nur über Try-Error-Versuche herausfinden.

        Man kann nicht aus einem Namespace auf den Namen einer Assembly schließen und umgekehrt. Zwischen beiden gibt es keinen zwingenden Zusammenhang. Auch der .Net-Compiler kann das nicht, weswegen ihm unbedingt neben den Namespaces die Namen der Assemblys angegeben werden müssen - unter Umständen sogar noch mit Versionsnummer, Key und Ort.

        Dieser Fakt war mir bekannt und so konnte ich gezielt auf Suche gehen, auch wenn mir bis jetzt nicht bewusst war, dass man .Net-Code wie bei einer Script-Sprache zur Laufzeit auf diese Weise kompilieren und einbinden kann. Die Bestätigung, dass eine DLL angegeben werden muss, fand ich dann auch erst im x-ten Blog-Beitrag, der sich mit dem Thema beschäftigt: http://simeonpilgrim.com/blog/2007/12/04/compiling-and-running-code-at-runtime/.

        dedlfix.

        1. auch wenn mir bis jetzt nicht bewusst war, dass man .Net-Code wie bei einer Script-Sprache zur Laufzeit auf diese Weise kompilieren und einbinden kann.

          Dim vbel As New VBCodeProvider()
          Dim oCParams As New CompilerParameters()
          oCParams.ReferencedAssemblies.Add("System.dll")
          ' So funktioniert's.
          oCParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
          Dim oCResults As CompilerResults = Nothing
          Dim oAssy As Assembly = Nothing
          oCParams.GenerateInMemory = True
          oCParams.MainClass = "Test"
          Dim cr As System.CodeDom.Compiler.CompilerResults = vbel.CompileAssemblyFromSource(oCParams,richTextBox1.Text)
          Dim rK As Object = cr.CompiledAssembly.CreateInstance("Test")
          

          In der Variable "rK" liegt dann die kompilierte Klasse (aus dem Beispiel siehe Eröffnungspost), wobei man dann einfach mit rK.Main() direkt interagieren kann.

          :D On-The-Run-Compiler :D Kannst das gerne ausprobieren :D Habe jetzt den Fehler-Check nicht mit eingebaut.