Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Imports System
- Imports EnvDTE
- Imports EnvDTE80
- Imports EnvDTE90
- Imports System.Diagnostics
- Public Module ExtractWinFormsDesignerFile
- ' -------------------------------------------------------------------------
- ' Extract WinForms Designer File Visual Studio 2005/2008 Macro
- ' -------------------------------------------------------------------------
- ' Extracts the InitializeComponent() and Dispose() methods and control
- ' field delarations from a .NET 1.x VS 2003 project into a VS 2005/8
- ' style .NET 2.0 partial class in a *.Designer.VB file. (This tested to work
- ' with VB only.)
- '
- ' To use:
- ' * Copy the methods below into a Visual Studio Macro Module (use
- ' ALT+F11 to show the Macro editor)
- ' * Select a Windows Form in the Solution Explorer
- ' * Run the macro by showing the Macro Explorer (ALT+F8) and double
- ' clicking the 'ExtractWinFormsDesignerFile' macro.
- '
- ' Duncan Smart, InfoBasis, 2007
- ' From: http://blog.dotsmart.net/2008/05/20/converting-visual-studio-2003-winforms-to-visual-studio-20052008-partial-classes/
- ' Modified and updated by Nathan Jones, 2010
- ' See: http://www.nathanpjones.com/
- ' -------------------------------------------------------------------------
- Sub ExtractWinFormsDesignerFile()
- Dim item As ProjectItem = DTE.SelectedItems.Item(1).ProjectItem
- Dim sourceFileName As String = item.FileNames(1)
- Dim sourceDir As String = System.IO.Path.GetDirectoryName(sourceFileName)
- Dim origCode As String
- Dim bareName As String = System.IO.Path.GetFileNameWithoutExtension(sourceFileName)
- Dim newDesignerFile As String = sourceDir & "\" & bareName & ".Designer.vb"
- If IO.File.Exists(newDesignerFile) Then
- MsgBox("Designer file already exists!")
- Exit Sub
- Else
- If MsgBox("You are about to extract designer code from:" + vbCrLf + _
- vbCrLf + _
- " " + sourceFileName + vbCrLf + _
- vbCrLf + _
- "To the following file:" + vbCrLf + _
- vbCrLf + _
- " " + newDesignerFile + vbCrLf + _
- vbCrLf + _
- "MAKE SURE TO BACK UP FIRST!", _
- MsgBoxStyle.OkCancel Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Question, _
- "Confirm") = MsgBoxResult.Cancel Then Exit Sub
- End If
- origCode = System.IO.File.ReadAllText(sourceFileName)
- Dim codeClass As CodeClass
- Dim namespaceName As String
- codeClass = findClass(item.FileCodeModel.CodeElements)
- namespaceName = ""
- If codeClass.Namespace IsNot Nothing Then
- namespaceName = codeClass.Namespace.FullName
- End If
- Dim initComponentText As String
- Dim disposeText As String
- Dim fieldDecls() As String
- Try
- initComponentText = extractMember(codeClass.Members.Item("InitializeComponent"))
- Catch
- MsgBox("Error extracting InitializeComponent!")
- Exit Sub
- End Try
- Try
- disposeText = extractMember(codeClass.Members.Item("Dispose"))
- Catch
- MsgBox("Error extracting Dispose! Will restore source file.")
- System.IO.File.WriteAllText(sourceFileName, origCode)
- Exit Sub
- End Try
- Try
- fieldDecls = extractWinFormsFields(codeClass, initComponentText)
- Catch
- MsgBox("Error extracting field declares! Will restore source file.")
- System.IO.File.WriteAllText(sourceFileName, origCode)
- Exit Sub
- End Try
- Dim finalCode As String
- finalCode = IIf(namespaceName <> "", "Namespace " + namespaceName + vbCrLf + vbCrLf, "") + _
- "<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _" + vbCrLf + _
- "Partial Class " + codeClass.Name + vbCrLf + _
- " Inherits System.Windows.Forms.Form" + vbCrLf + _
- vbCrLf + _
- disposeText + vbCrLf + _
- vbCrLf + _
- fieldDecls(0) + vbCrLf + _
- vbCrLf + _
- initComponentText + vbCrLf + _
- fieldDecls(1) + vbCrLf + _
- "End Class" + vbCrLf + _
- IIf(namespaceName <> "", vbCrLf + "End Namespace" + vbCrLf, "")
- ' Now write the new designer file
- System.IO.File.WriteAllText(newDesignerFile, finalCode)
- Dim newProjItem As ProjectItem = item.ProjectItems.AddFromFile(newDesignerFile)
- Try
- newProjItem.Open()
- Catch
- End Try
- Try
- DTE.ExecuteCommand("Edit.FormatDocument")
- Catch
- End Try
- MsgBox("Code separated successfully!" + vbCrLf + _
- "You may have residual comments or code regions in the source " + vbCrLf + _
- "class that should be deleted or moved to the new Designer.vb class.", _
- MsgBoxStyle.Information, _
- "Complete")
- End Sub
- Function findClass(ByVal items As System.Collections.IEnumerable) As CodeClass
- For Each codeEl As CodeElement In items
- If codeEl.Kind = vsCMElement.vsCMElementClass Then
- Return codeEl
- ElseIf codeEl.Children.Count > 0 Then
- Dim cls As CodeClass = findClass(codeEl.Children)
- If cls IsNot Nothing Then
- Return findClass(codeEl.Children)
- End If
- End If
- Next
- Return Nothing
- End Function
- Function extractWinFormsFields(ByVal codeClass As CodeClass, ByVal initComponentsCode As String) As String()
- Dim member As CodeElement
- Dim fieldsCode As String
- Dim components As String
- Dim initComponentsCodeForComp As String = initComponentsCode.ToLower
- fieldsCode = ""
- For i As Integer = codeClass.Members.Count To 1 Step -1
- member = codeClass.Members.Item(i)
- If member.Kind = vsCMElement.vsCMElementVariable Then
- Dim field As CodeVariable = member
- If field.Type.TypeKind <> vsCMTypeRef.vsCMTypeRefArray Then
- If field.Name.ToLower = "components" Then
- ' We'll insert this separately
- components = extractMember(field)
- ElseIf initComponentsCodeForComp Like ("* Me." + field.Name + " = New *").ToLower Then
- fieldsCode = extractMember(field) + vbCrLf + _
- fieldsCode
- End If
- End If
- End If
- Next
- Return New String() {components, fieldsCode}
- End Function
- Function extractMember(ByVal memberElement As CodeElement) As String
- Dim memberStart As EditPoint = memberElement.GetStartPoint().CreateEditPoint()
- Dim memberText As String = String.Empty
- memberText += memberStart.GetText(memberElement.GetEndPoint())
- memberStart.Delete(memberElement.GetEndPoint())
- Return memberText
- End Function
- End Module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement