Создание шаблонов проекта C++ в Visual Studio
От: CoolCmd Россия  
Дата: 16.08.10 12:25
Оценка:
Добрый.

Как известно, в Visual Studio можно создавать шаблоны проекта только для C#, любители C++ в пролете. Нижеприведенный макрос позволяет решить проблему. С его помощью можно создавать полностью настроенные проекты в течении полуминуты, экономя кучу времени и нервных клеток.

Как это работает. Создается solution ProjectTemplates, в нем плодятся проекты, которые в будущем будут использоваться в качестве шаблонов. В них добавляются исходники, ресурсы, property sheets и т.д. После этого создается пустое solution или открывается существующее и запускается макрос AddCppProjectFromTemplate(). В нем задается имя добавляемого проекта, выбирается нужный шаблон и файлы из него копируются в текущее solution. Файлы при необходимости переименовываются, а в их содержимом имя шаблона меняется на имя создаваемого проекта. В файле vcxproj так же меняется GUID проекта.

Замечания.

Option Strict Off
Option Explicit On

Imports System
Imports EnvDTE
Imports System.Diagnostics

Public Module MegaCoolModule
    '
    ' AddCppProjectFromTemplate()
    ' Revision: 1
    '
    Private Const conVisualCPlusPlusProject As String = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
    Private Const conTemplateSolutionFolder As String = "..\ProjectTemplates"
    Private Const conProjectExtension As String = ".vcxproj"

    Private Function GetTemplateProjectFile() As String
        Dim astrProjectFiles() As String = IO.Directory.GetFiles( _
          IO.Path.Combine(IO.Path.GetDirectoryName(DTE.Solution.FullName), conTemplateSolutionFolder), _
          "*" & conProjectExtension, IO.SearchOption.AllDirectories)

        If astrProjectFiles.Length = 0 Then
            Return ""
        End If

        Dim strMenu As String = ""
        For i As Integer = 0 To astrProjectFiles.Length - 1
            strMenu &= vbCrLf & i + 1 & ":  " & IO.Path.GetFileNameWithoutExtension(astrProjectFiles(i))
        Next

        Dim strProjectFile As String = ""
        Do
            Dim strProjectIndex As String = InputBox("Введите номер шаблона." & strMenu)

            If Len(strProjectIndex) = 0 Then
                Exit Do
            End If

            Try
                strProjectFile = astrProjectFiles(CInt(strProjectIndex) - 1)
            Catch
            End Try
        Loop While Len(strProjectFile) = 0

        Return strProjectFile
    End Function

    Private Function GetProjectName(ByVal strPrompt As String) As String
        Dim strProjectName As String = ""
        Do
            strProjectName = InputBox(strPrompt, , strProjectName)

            If Len(strProjectName) = 0 Then
                Return strProjectName
            End If

            Dim achrInvalidChars() As Char = {"&"c, "#"c, "%"c}
            If strProjectName.IndexOfAny(IO.Path.GetInvalidFileNameChars()) >= 0 _
            Or strProjectName.IndexOfAny(achrInvalidChars) >= 0 Then
                MsgBox("Имя проекта содержит недопустимые символы", MsgBoxStyle.Exclamation)
                Continue Do
            End If

            Dim astrReservedNames() As String = {".", "..", "CON", "COM1", "COM2", "COM3", "AUX", "LPT1", "LPT2", "PRN", "NUL"}
            If Array.IndexOf(astrReservedNames, strProjectName) >= 0 Then
                MsgBox("Вы ввели зарезервированное имя", MsgBoxStyle.Exclamation)
                Continue Do
            End If

            For Each objProject As Project In DTE.Solution.Projects
                If String.Compare(objProject.Name, strProjectName, True) = 0 Then
                    MsgBox("Solution уже содержит проект с указанным именем", MsgBoxStyle.Exclamation)
                    Continue Do
                End If
            Next

            Return strProjectName
        Loop
    End Function

    Private Sub ParseAndCopyFile(ByVal strSourceFile As String, ByVal strDestinationFile As String, ByVal strTemplateProjectName As String, ByVal strNewProjectName As String)
        Const conProjectGuidPattern As String = "(?!<ProjectGuid>\{).{36}(?=\}</ProjectGuid>)"

        ' Если в файле нет BOM, то будет использована кодировка ANSI
        Dim objEncoding As Text.Encoding = Text.Encoding.GetEncoding(0, New Text.EncoderExceptionFallback, New Text.DecoderExceptionFallback)

        Trace.WriteLine("ParseAndCopyFile() file: " & strSourceFile)
        Dim objReader As New IO.StreamReader(strSourceFile, objEncoding, True)
        Dim strFileContent As String = objReader.ReadToEnd()
        objEncoding = objReader.CurrentEncoding
        Trace.WriteLine(String.Format("ParseAndCopyFile() encoding: {0} ({1})", objEncoding.EncodingName, objEncoding.CodePage))
        objReader.Close()

        strFileContent = strFileContent.Replace(strTemplateProjectName, strNewProjectName)

        If IO.Path.GetExtension(strSourceFile) = conProjectExtension Then
            Dim strModifiedFileContent As String = Text.RegularExpressions.Regex.Replace(strFileContent, _
              conProjectGuidPattern, UCase(Guid.NewGuid().ToString()), _
              Text.RegularExpressions.RegexOptions.IgnoreCase)
            Trace.Assert(strModifiedFileContent <> strFileContent)
            strFileContent = strModifiedFileContent
        End If

        Dim objWriter As New IO.StreamWriter(strDestinationFile, False, objEncoding)
        objWriter.Write(strFileContent)
        objWriter.Close()
    End Sub

    Public Sub AddCppProjectFromTemplate()
        ' Файлы с указанными расширениями не будет добавлены в создаваемый проект
        Dim astrSkipExtensions() As String = {".aps", ".sdf", ".opensdf", ".ipch", ".sln", ".suo"}
        ' В файлах с указанными расширениями будет производиться замена текста
        Dim astrParseExtensions() As String = {conProjectExtension, ".filters", ".user", ".manifest", ".c", ".cpp", ".h", ".inc", ".inl", ".rc", ".rc2", ".def", ".asm", ".cmd", ".bat", ".txt", ".ini"}

        If Not DTE.Solution.IsOpen() Then
            MsgBox("Перед вызовом макроса необходимо открыть solution, в которое будет добавлен проект", MsgBoxStyle.Critical)
            Return
        End If

        Dim strTemplateProjectFile As String = GetTemplateProjectFile()
        If Len(strTemplateProjectFile) = 0 Then
            Return
        End If
        Dim strTemplateProjectName As String = IO.Path.GetFileNameWithoutExtension(strTemplateProjectFile)

        Dim strNewProjectName As String = GetProjectName("Введите имя создаваемого проекта.")
        If Len(strNewProjectName) = 0 Then
            Return
        End If

        Dim idMBResult As MsgBoxResult = MsgBox("Создать для проекта папку? Нажмите «Нет» что бы использовать папку solution.", MsgBoxStyle.Question + MsgBoxStyle.YesNoCancel)
        If idMBResult = MsgBoxResult.Cancel Then
            Return
        End If

        Dim strSourceFolder As String = IO.Path.GetDirectoryName(strTemplateProjectFile)
        Dim strDestinationFolder As String = IO.Path.GetDirectoryName(DTE.Solution.FullName)
        If idMBResult = MsgBoxResult.Yes Then
            strDestinationFolder = IO.Path.Combine(strDestinationFolder, strNewProjectName)
            IO.Directory.CreateDirectory(strDestinationFolder)
        End If

        For Each strSourceFile As String In IO.Directory.GetFiles(strSourceFolder)
            Dim strSourceExtension As String = LCase(IO.Path.GetExtension(strSourceFile))

            If Array.IndexOf(astrSkipExtensions, strSourceExtension) >= 0 Then
                Continue For
            End If

            Dim strDestinationFile As String = IO.Path.Combine(strDestinationFolder, _
              IO.Path.GetFileNameWithoutExtension(strSourceFile).Replace(strTemplateProjectName, strNewProjectName) & _
              strSourceExtension)

            If Array.IndexOf(astrParseExtensions, strSourceExtension) >= 0 Then
                ParseAndCopyFile(strSourceFile, strDestinationFile, strTemplateProjectName, strNewProjectName)
            Else
                IO.File.Copy(strSourceFile, strDestinationFile, True)
            End If
        Next

        Try
            DTE.Solution.AddFromFile(IO.Path.Combine(strDestinationFolder, strNewProjectName & conProjectExtension), False)
        Catch ex As Exception
            MsgBox("Файлы проекта были успешно скопированы в папку " & strDestinationFolder & ", но во время добавления проекта в solution возникла ошибка. Попробуйте добавить проект вручную. Описание ошибки: " & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub
End Module
простите, я убил небо
visual studio 2010 2008 project template macro
Re: Создание шаблонов проекта C++ в Visual Studio
От: Sni4ok  
Дата: 16.08.10 12:30
Оценка:
Здравствуйте, CoolCmd, Вы писали:

CC>Как известно, в Visual Studio можно создавать шаблоны проекта только для C#, любители C++ в пролете.


для c++ есть cmake, так что такое там нафиг не здалось.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.