Before
After
Convert Projects Image
Fix Converted Project Files
Code Converter 2013
Introduction
This is a Code Converter that uses four different DLL files from around the .NET community. The DLL files I used are FastColoredTextBox.dll, ConversionWrapper.dll, ICSharpCode.NRefactory.dll, and rsp.ConVert.dll. I came up with this Idea mainly from the FastColoredTextBox
. Then I discovered the VS Addin (CodeConvert
), both can be found here on CodeProject
. I use the same DLL that the VS add-in uses. The ICSharpCode.NRefactory DLL can be found at their website. FastColoredTextBox
is used for the syntax coloring. CodeConvert
is referenced and does just as it says. The ICSharpCode.NRefactory DLL accompanies the CodeConvert.dll file.
rspConVert.dll is a remake of Deniz Ezen's Econ.NetVert.Dll. I stripped out the asp.net part as I could not get it to work. I also re-edited some of his code to work with my program. I added Project Conversions and Post fix for the files of the project conversion.
Background
There are a lot of code converters out there, but, 99 percent of them are web-based and 1 or 2 are Visual Studio Addins. The addins, I must say, definitely have an advantage over the web-based converters and they probably have a slight advantage over this one also, but, you do not have to open Visual Studio and you do not have to keep switching back and forth between your app and the Internet. You can open any *.cs, or *.vb file and convert it, and then use it in Visual Studio at a later time if needed by saving it as a text file or a *.cs, *.vb file using NotePad++.
The Code
I cannot think of very much to write when the whole program consists of 79 lines of code without the whitespace, but I'll give it a try. CodeConvert.dll only converts *.cs and *.vb files. It doesn't do snippets, such as, subs or functions by themselves. Whole files only.
Now let's take a look at the code below.
buttonClearAllCode_Click
Here we set each TextBox
to String.Empty
.
buttonCopyCSharpCode_Click
Here we add the txtCSharp.Text
to the Clipboard
.
buttonCopyVBCode_Click
Here we add the txtVBnet.Text
to the Clipboard
.
buttonConvertCSharpToVB_Click
This is where all the work is done for converting C# to VB. In the CodeConversionHelper
class in the ICSharpCode.NRefactory DLL, there are three functions that take care of the conversions. These are:
Public Shared Function ConvertCSharpToVB(ByVal sourceCode As String) As String
Public Shared Function ConvertVBToCSharp(ByVal sourceCode As String) As String
Private Shared Function GenerateCode(ByVal sourceCode As String, ByVal language As SupportedLanguage) As String
In the buttonConvertCSharpToVB_Click
event, we call the function ConvertCSharpToVB(txtCSharp.Text)
. This, then calls the function GenerateCode(ByVal sourceCode As String, ByVal language As SupportedLanguage)
. The source code would be txtCSharp.Text
and the supported language would be CSharp
. The GenerateCode
function, then calls on 6 more classes that are in the ICSharpCode.NRefactory dll
which is indeed beyond the scope of this article. The GenerateCode
source follows...
Private Shared Function GenerateCode(ByVal sourceCode As String, ByVal language As SupportedLanguage) As String
Using parser As IParser = ParserFactory.CreateParser(language, New StringReader(sourceCode))
parser.Parse
If (parser.Errors.Count = 0) Then
Dim visitor As IOutputAstVisitor
Dim specials As IList(Of ISpecial) = New ISpecial(0 - 1) {}
If (language = SupportedLanguage.CSharp) Then
visitor = New VBNetOutputVisitor
Else
visitor = New CSharpOutputVisitor
End If
Using SpecialNodesInserter.Install(specials, visitor)
parser.CompilationUnit.AcceptVisitor(visitor, Nothing)
End Using
Return visitor.Text
End If
Dim builder As New StringBuilder
Return parser.Errors.ErrorOutput
End Using
End Function
buttonConvertVBtoCSharp_Click
This is where all the work is done for converting VB to C#. It calls the same three functions as the buttonConvertCSharpToVB_Click
event. Please see above.
OpenToolStripMenuItem_Click
When the OpenFileDialog
appears, and we select a file to open, the program knows where to input the selected file. If it is a *.cs
file it will be opened in the txtCSharp TextBox
and the same for a *.vb
file in the txtVBnet TextBox
. First, the file gets read and then inserted.
frmConverter_FormClosing
Here we just Dispose
of the TextBoxes
.
frmConverter_Load
If the window is maximized or normal we set the SplitterDistance
in in the center of the form.
frmConverter_SizeChanged
We do the same thing in this sub for the SplitterDistance
, except we set panel1Collapsed
to True
when minimised. This stops an exception from being thrown. This meaning that the SplitterDistance
cannot be (-1).
The whole program is pasted below:
Imports CodeConvert.ConversionLoader
Imports CodeConvert
Imports ICSharpCode.NRefactory
Imports System
Imports System.IO
Imports System.Text
Imports System.Environment
Imports FastColoredTextBoxNS
Public Class frmConverter
Private Sub buttonClearAllCode_Click(sender As Object, _
e As System.EventArgs) Handles buttonClearAllCode.Click
txtCSharp.Text = String.Empty
txtVBnet.Text = String.Empty
End Sub
Private Sub buttonCopyCSharpCode_Click(sender As Object, _
e As System.EventArgs) Handles buttonCopyCSharpCode.Click
My.Computer.Clipboard.SetText(txtCSharp.Text)
End Sub
Private Sub buttonCopyVBCode_Click(sender As Object, _
e As System.EventArgs) Handles buttonCopyVBCode.Click
My.Computer.Clipboard.SetText(txtVBnet.Text)
End Sub
Private Sub buttonConvertCSharpToVB_Click(sender As Object, _
e As System.EventArgs) Handles buttonConvertCSharpToVB.Click
Me.txtVBnet.Text = ConvertCSharpToVB(txtCSharp.Text)
txtVBnet.Text &= vbCrLf & vbCrLf & "'Converted By: CodeConverter 2011 Conversion Utility!"
End Sub
Private Sub buttonConvertVBtoCSharp_Click(sender As Object, _
e As System.EventArgs) Handles buttonConvertVBtoCSharp.Click
Me.txtCSharp.Text = ConvertVBToCSharp(txtVBnet.Text)
txtCSharp.Text &= vbCrLf & vbCrLf & "//Converted By: CodeConverter 2011 Conversion Utility!"
End Sub
Private Sub OpenToolStripMenuItem_Click(sender As Object, _
e As System.EventArgs) Handles OpenToolStripMenuItem.Click
Dim fName As String
ofd.Filter = "C-Sharp Files (*.cs)|*.cs|VB Files (*.vb)|*.vb"
If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
fName = ofd.FileName
If fName.EndsWith(".cs") Then
txtCSharp.Language = Language.CSharp
txtCSharp.Text = File.ReadAllText(fName)
buttonConvertCSharpToVB.Enabled = True
buttonConvertVBtoCSharp.Enabled = False
buttonCopyVBCode.Enabled = True
buttonCopyCSharpCode.Enabled = False
Else
txtVBnet.Text = File.ReadAllText(fName)
txtVBnet.Language = Language.VB
buttonConvertCSharpToVB.Enabled = False
buttonConvertVBtoCSharp.Enabled = True
buttonCopyVBCode.Enabled = False
buttonCopyCSharpCode.Enabled = True
End If
End If
End Sub
Private Sub frmConverter_FormClosing(sender As Object, _
e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
txtCSharp.Dispose()
txtVBnet.Dispose()
End Sub
Private Sub frmConverter_Load(sender As Object, _
e As System.EventArgs) Handles Me.Load
If Me.WindowState = FormWindowState.Maximized Then
sc1.SplitterDistance = ((sc1.Width / 2) - (sc1.SplitterWidth / 2))
Else
sc1.SplitterDistance = ((sc1.Width / 2) - (sc1.SplitterWidth / 2))
End If
End Sub
Private Sub frmConverter_SizeChanged(sender As Object, _
e As System.EventArgs) Handles Me.SizeChanged
If Me.WindowState = FormWindowState.Maximized Then
txtCSharp.BackgroundImageLayout = ImageLayout.Stretch
txtVBnet.BackgroundImageLayout = ImageLayout.Stretch
sc1.Panel1Collapsed = False
sc1.SplitterDistance = ((sc1.Width / 2) - (sc1.SplitterWidth / 2))
ElseIf Me.WindowState = FormWindowState.Minimized Then
sc1.Panel1Collapsed = True
Else
txtCSharp.BackgroundImageLayout = ImageLayout.Center
txtVBnet.BackgroundImageLayout = ImageLayout.Center
sc1.Panel1Collapsed = False
sc1.SplitterDistance = ((sc1.Width / 2) - (sc1.SplitterWidth / 2))
End If
End Sub
Private Sub CloseToolStripMenuItem_Click(sender As System.Object, _
e As System.EventArgs) Handles CloseToolStripMenuItem.Click
Application.Exit()
End Sub
End Class
Not All Errors are Created Equal
Not all errors can be fixed right now. As with all man-made things nothing is 100% reliable. So for now we have todo this manually to the example that follows...for now.
Implements Interface
C# does not require adding the implement statement after the required subs or functions. For now this will have to be done manually in VBnet
. C# also does not require the ( Handles
) statement, but it does display an Error message stating this fact when converting VB to C# and does the same for the Implements
clauses.
AddHandler, AddressOf....Updated
In C#, an Addhandler Statement
looks something like this... ( Sub.Event += New(SomeTypeOfEventArgs)Sub_Event
) When Converting from C#, this is probably seen as an addition. After fiddling around with Expresso, I finally came up with a regex string that finds the C# code Sub.Event += New(SomeTypeOfEventArgs)Sub_Event
. Here is how we fix the AddHandler, AddressOf
statement in VB from C# that has been eluding all code converters until now.
Private Sub VBFixIt()
Dim m As Match
Dim strMatch As String
Dim txtVBNetText As String = txtVBnet.Text
lblStatus4.Text = "Please Wait...Conversion Started!!!"
Dim regexStr As String = "\b\w+.+=\sNew\s\w+\(\w+_\w+\)"
Dim remregexStr As String = "\b\w+.-=\sNew\s\w+\(\w+_\w+\)"
Dim patternIsInteger As String = "\bAs\sObject\s\=\s(\d+.|\w+.SelectedIndex)"
Dim patternClass As String = "\bAs\sObject\s\=\sNew\s\w+\(\)"
Dim patternTryCast As String = "\bAs\sObject\s\=\sTryCast\(e.Argument\,\s\w+\)"
Dim patternSystemEventArgs As String = "\b\w+_(AcceptsTabChanged|AutoSizeChanged|" & _
"BackColorChanged|BackgroundImageChanged|BackgroundImageLayoutChanged" _
& "|BindingContextChanged|BorderStyleChanged|" & _
"CausesValidationChanged|Click|ClientSizeChanged|ContextMenuChanged" _
& "|ContextMenuStripChanged|CursorChanged|" & _
"DataSourceChanged|DisplayMemberChanged|Disposed|DockChanged|DoubleClick|DragLeave" _
& "|DropDown|DropDownClosed|DropDownStyleChanged|" & _
"EnabledChanged|FormatInfoChanged|FormatStringChanged|FormattingEnabledChanged" _
& "|Enter|FontChanged|ForeColorChanged|GotFocus|" & _
"HandleCreated|HandleDestroyed|HideSelectionChanged|ImeModeChanged|Leave|LocationChanged" _
& "|LostFocus|MarginChanged|MouseCaptureChanged|" & _
"Move|ModifiedChanged|MultilineChanged|PaddingChanged|ParentChanged|RegionChanged" _
& "|ReadOnlyChanged|Resize|RightToLeftChanged|" & _
"SizeChanged|StyleChanged|SystemColorsChanged|TabIndexChanged" _
& "|TabStopChanged|TextChanged|TextAlignChanged|" & _
"Validated|VisibleChanged|ValueMemberChanged|Load|FormClosed|MouseEnter" _
& "|MouseHover|MouseLeave|SelectionChangeCommitted|" & _
"SelectedIndexChanged|SelectedItemChanged|SelectedValueChanged)" & _
"\((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\s(EventArgs|" & _
"System\.EventArgs)\)|sender\sAs\sObject\,\se\sAs\s(EventArgs|System\.EventArgs)\))"
Dim patternComponentModelCancelEventArgs As String = "\b\w+_Validating\((ByVal\ssender\sAs\sObject\," & _
"\sByVal\se\sAs\sSystem\.ComponentModel\.CancelEventArgs\)|" & _
"sender\sAs\sObject\,\se\sAs\sSystem\.ComponentModel\.CancelEventArgs)\)"
Dim patternMeasureItemEventArgs As String = "\b\w+_MeasureItem\((ByVal\" & _
"ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\" & _
".MeasureItemEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".Windows\.Forms\.MeasureItemEventArgs)\)"
Dim patternListControlConvertEventArgs As String = "\b\w+_Format\((ByVal\" & _
"ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\." & _
"ListControlConvertEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".Windows\.Forms\.ListControlConvertEventArgs)\)"
Dim patternDrawItemEventArgs As String = "\b\w+_DrawItem\((ByVal\ssender" & _
"\sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.DrawItemEventArgs\)" & _
"|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.DrawItemEventArgs)\)"
Dim patternQueryPageSettingsEventArgs As String = "\b\w+_QueryPageSettings\" & _
"((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Drawing\.Printing\" & _
".QueryPageSettingsEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".Drawing\.Printing\.QueryPageSettingsEventArgs)\)"
Dim patternPrintPageEventArgs As String = "\b\w+_PrintPage\((ByVal\" & _
"ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Drawing\.Printing\" & _
".PrintPageEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\.Drawing\.Printing\.PrintPageEventArgs)\)"
Dim patternPrintEventArgs As String = "\b\w+_(BeginPrint|EndPrint)\" & _
"((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Drawing\.Printing\" & _
".PrintEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\.Drawing\.Printing\.PrintEventArgs)\)"
Dim patternQueryAccessibilityHelpEventArgs As String = "\b\w+_QueryAccessibilityHelp\" & _
"((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sSystem.Windows.Forms." & _
"QueryAccessibilityHelpEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".Windows\.Forms\.QueryAccessibilityHelpEventArgs)\)"
Dim patternQueryContinueDragEventArgs As String = "\b\w+_QueryContinueDrag\" & _
"((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sSystem.Windows.Forms." & _
"QueryContinueDragEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".Windows\.Forms\.QueryContinueDragEventArgs)\)"
Dim patternCancelEventArgs As String = "\b\w+_Validating\((ByVal\ssender\" & _
"sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.CancelEventArgs\)|" & _
"sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.CancelEventArgs)\)"
Dim patternFormClosingEventArgs As String = "\b\w+_FormClosing\((ByVal\ssender\" & _
"sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.FormClosingEventArgs\)" & _
"|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.FormClosingEventArgs)\)"
Dim patternPreviewKeyDownEventArgs As String = "\b\w+_PreviewKeyDown\((ByVal\" & _
"ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\." & _
"PreviewKeyDownEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".Windows\.Forms\.PreviewKeyDownEventArgs)\)"
Dim patternPaintEventArgs As String = "\b\w+_Paint\((ByVal\ssender\" & _
"sAs\sObject\,|sender\sAs\sObject\,)\s(ByVal\se\sAs\sSystem\.Windows\" & _
".Forms\.PaintEventArgs\)|e\sAs\sSystem\.Windows\.Forms\.PaintEventArgs)\)"
Dim patternLayoutEventArgs As String = "\b\w+_HelpRequested\((ByVal\ssender\" & _
"sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.LayoutEventArgs\)|" & _
"sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.LayoutEventArgs)\)"
Dim patternControlAddedRemoved As String = "\b\w+_(ControlAdded|ControlRemoved)" & _
"\((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\" & _
".ControlEventArgs\)|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.ControlEventArgs)\)"
Dim patternChangeUICues As String = "\b\w+_ChangeUICues\((ByVal\ssender\sAs\" & _
"sObject\,\sByVal\se\sAs\sSystem\.Window\s.Forms\.UICuesEventArgs\)|" & _
"sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.UICuesEventArgs)\)"
Dim patternGiveFeedback As String = "\b\w+_GiveFeedback\((ByVal\ssender\sAs\" & _
"sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.GiveFeedbackEventArgs\)" & _
"|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.GiveFeedbackEventArgs)\)"
Dim patternHelpRequested As String = "\b\w+_HelpRequested\((ByVal\ssender\sAs\" & _
"sObject\,\sByVal\shlpevent\sAs\sSystem\.Windows\.Forms\.HelpEventArgs\)|" & _
"sender\sAs\sObject\,\shlpevent\sAs\sSystem\.Windows\.Forms\.HelpEventArgs)\)"
Dim patternInvalidated As String = "\b\w+_Invalidated\((ByVal\ssender\sAs\" & _
"sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.InvalidateEventArgs\)" & _
"|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.InvalidateEventArgs)\)"
Dim patternCheckChanged As String = "\b\w+_CheckChanged\((ByVal\ssender\sAs\" & _
"sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.CheckChangedEventArgs\)" & _
"|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.CheckChangedEventArgs)\)"
Dim patternBackgroundWorker As String = "\b\w+_(DoWork|ProgressChanged|" & _
"RunWorkerCompleted)\((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\" & _
".ComponentModel\.(DoWorkEventArgs|ProgressChangedEventArgs|" & _
"RunWorkerCompletedEventArgs)\)|sender\sAs\sObject\,\se\sAs\sSystem\" & _
".ComponentModel\.(DoWorkEventArgs|ProgressChangedEventArgs|RunWorkerCompletedEventArgs))\)"
Dim patternMouseEventArgs As String = "\b\w+_(MouseUp|MouseDown|MouseMove)\" & _
"((ByVal\ssender\sAs\sObject\,\sByVal\se\sAs\sMouseEventArgs\)|" & _
"sender\sAs\sObject\,\se\sAs\sMouseEventArgs)\)"
Dim patternKeysUpDown As String = "\b\w+_(KeyUp|KeyDown)\(ByVal\ssender\sAs\" & _
"sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.KeyEventArgs\)|" & _
"sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.KeyEventArgs\)"
Dim patternKeyPress As String = "\b\w+_KeyPress\((ByVal\ssender\sAs\sObject\," & _
"\sByVal\se\sAs\s(System\.Windows\.Forms\.KeyPressEventArgs|KeyPressEventArgs)" & _
"\)|sender\sAs\sObject\,\se\sAs\s(System\.Windows\.Forms\" & _
".KeyPressEventArgs|KeyPressEventArgs))\)"
Dim patternDragDropEnter As String = "\b\w+_(DragDrop|DragEnter)\((ByVal\" & _
"ssender\sAs\sObject\,\sByVal\se\sAs\sSystem\.Windows\.Forms\.DragEventArgs\)" & _
"|sender\sAs\sObject\,\se\sAs\sSystem\.Windows\.Forms\.DragEventArgs)\)"
End Sub
After using ICsharp.NRefactory.dll for the conversion, I do a POST conversion fix using regex strings to fix the currently converted VB code. I also added a lot of post fixes on this upgrade. I still have along way to go to finish the post fixes, I keep coding away at it. I'll eventually finish.!!!
If you do not have the apps and DLLs below, Please get them as you will need them. They are all free.
Points of Interest
History
Added some extra subs that do post fix on the current code. Removed the picture that is probably crushing a nerve in some or all who downloaded the app before. Sorry for that flub.
The VBFixIt Sub
now has over 14,500 to 15,000 POST Conversion fixes using regex strings
- Uploaded 09-26-2011
- Uploaded 10-04-2011
- Uploaded 04-03-2012
- Uploaded 04-05-2012
- Uploaded 04-08-2012
- Uploaded 04-12-2012, Fixed some mental errors in the regex strings.
- Uploaded 04-18-2012, Changed the UI a little and added more regex strings.
This is suppose to be the last update. It probably wont be. I have completed adding all the toolbox components EVENTARGS, about 15,000 of them and still adding as I find different ways C# programmers are writing certain pieces of code (AddHandler
, RemoveHandler
, BeginEnvoke
, ...). If any C# programmers find different ways to write pieces of code, please e-mail me with you code attached so I can add it to the app. I hope you all will enjoy this application and hope it brings you's some very good use.
If there is anything in this article that sounds somewhat redundant, it probably is, so please do not leave a message stating this as I already know.