Создать решение Visual Studio .NET с помощью сценария оболочки? - PullRequest
0 голосов
/ 29 августа 2018

Тонна моих проектов, над которыми я работаю, начинается с той же базовой компоновки. Мне было интересно, есть ли способ автоматизировать первоначальное создание проекта. Я хочу создать решение и все внутренние проекты с помощью скрипта. Кроме того, я хочу иметь возможность создать git-репозиторий для этого проекта.

Я надеялся, что есть способ сделать этот проект в сценарии оболочки или что-то в этом роде. Если это невозможно, есть ли способ создать шаблон, который можно использовать для создания решения?

Я провел тонну поиска, или я не знаю, как правильно сформулировать свой поиск, или я не могу ничего найти. Я видел нечто похожее на создание Java-проекта в IntelliJ.

1 Ответ

0 голосов
/ 29 августа 2018

Вот кое-что, с чего можно начать. Он работает только с проектами C # и переименовывает все пространства имен существующего решения. Вы можете клонировать каталог, и он выполняет простой поиск и замену. Вам также следует переименовать руководство проекта.

<#
.SYNOPSIS
  Renames all the filenames and namespaces of an existing solution or project

.DESCRIPTION
  When a new visual studio solution is cloned, the namespaces usually need
  to be changed, as well as the filenames.

  This script does all that on an existing solution directory.

.PARAMETER Path
  Path to the solution file e.g. MyCompany.MyApp\MyCompany.MyApp.sln

.PARAMETER OldNamespace
  Original namespace of the solution e.g. MyCompany.MyApp

.PARAMETER NewNamespace
  New namespace to replace the original namespace with e.g. MyCompany.NewApp

.INPUTS
  <Inputs if any, otherwise state None>

.OUTPUTS
  <Outputs if any, otherwise state None - example: Log file stored in C:\Windows\Temp\<name>.log>

.NOTES
  Version:        1.0
  Author:         Chui Tey
  Creation Date:  15-08-2018
  Purpose/Change: Initial script development

.EXAMPLE
  .\Rename-Solution.ps1 -Path .\MyCompany.MyApp\MyCompany.MyApp.sln MyCompany.OldApp MyCompany.MyApp [-Verbose]
#>

[CmdletBinding(SupportsShouldProcess)]
param
(
    [Parameter(Mandatory)]
    [string]
    $Path,

    [Parameter(Mandatory)]
    $OldNamespace,

    [Parameter(Mandatory)]
    $NewNamespace
)

#---------------------------------------------------------[Initialisations]--------------------------------------------------------

$ErrorActionPreference = "Stop"

$SolutionPath = $Path
$SolutionDirectory = (Get-Item $SolutionPath).DirectoryName

Write-Verbose "`$SolutionPath=`"$SolutionPath`""
Write-Verbose "`$SolutionDirectory=`"$SolutionDirectory`""

If (-Not (Test-Path $SolutionPath -PathType Leaf))
{
    Write-Error "SolutionPath $SolutionPath not present"
}

If (-Not $SolutionPath.EndsWith(".sln"))
{
    Write-Error "SolutionPath must end with '.sln'"
}

If ($OldNamespace -cnotlike "*.*")
{
    Write-Error "OldNamespace parameter must contain period e.g. 'MyCompany.MyApp'"
}

If ($NewNamespace -cnotlike "*.*")
{
    Write-Error "NewNamespace parameter must contain period e.g. 'MyCompany.MyApp'"
}

#-----------------------------------------------------------[Functions]------------------------------------------------------------


Function Rename-Namespaces
{
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(ValueFromPipeline=$True, Mandatory)] $Item,
        [string] $OldNamespace,
        [string] $NewNamespace
    )

    Process
    {
        $OldContent = (Get-Content -Path $item.FullName -Raw)
        If ($OldContent -cmatch $OldNamespace)
        {
            If ($PSCmdlet.ShouldProcess($item.FullName, "Rename-Namespaces"))
            {
                Write-Verbose "Rename-Namespace $($item.FullName)"
                $NewContent = $OldContent -creplace $OldNamespace,$NewNamespace

                # Don't use Set-Content as it appends a new line
                #Set-Content -Path $Item.FullName -Value $NewContent
                [System.IO.File]::WriteAllText($Item.FullName, $NewContent)
            }
        }
    }
}

Function Get-FilesToRenameNamespace
{
    $items = Get-ChildItem -Path $SolutionDirectory -Recurse -File -Filter "*.csproj" 
    $items

    $items = Get-ChildItem -Path $SolutionDirectory -Recurse -File -Filter "*.cs" 
    $items

    $items = Get-ChildItem -Path $SolutionDirectory -Recurse -File -Filter "*.asax" 
    $items

    $items = Get-ChildItem -Path $SolutionDirectory -Recurse -File -Filter "*.cshtml" 
    $items

    $items = Get-ChildItem -Path $SolutionDirectory -Recurse -File -Filter "*.config" 
    $items

    $items = Get-ChildItem -Path $SolutionDirectory -Recurse -File -Filter "*.targets" 
    $items
}

Function Rename-Project($SolutionDirectory, $OldNamespace, $NewNamespace)
{
    Write-Verbose "Renaming csproj"
    Get-ChildItem -ErrorAction SilentlyContinue -File -Recurse -Path $SolutionDirectory -Filter "*$OldNamespace*.csproj" `
    | ForEach-Object {
        $NewName = $_.Name -replace $OldNamespace,$NewNamespace
        Rename-Item -Path $_.FullName $NewName
    }

    Write-Verbose "Renaming directories"
    Get-ChildItem -ErrorAction SilentlyContinue -Directory -Recurse -Path $SolutionDirectory -Filter "*$OldNamespace*" `
    | ForEach-Object {
        $NewName = $_.Name -replace $OldNamespace,$NewNamespace
        Rename-Item -Path $_.FullName $NewName
    }

    Write-Verbose "Renaming project names in sln"
    $OldContent = Get-Content $SolutionPath
    $NewContent = $OldContent -replace $OldNamespace,$NewNamespace
    Set-Content -Path $SolutionPath -Value $NewContent
}


Function Rename-Solution($SolutionDirectory, $OldNamespace, $NewNamespace)
{
    Get-ChildItem -ErrorAction SilentlyContinue -File -Path $SolutionDirectory -Filter "*$OldNamespace*.sln" `
    | ForEach-Object {
        $NewName = $_.Name -replace $OldNamespace,$NewNamespace
        Rename-Item -Path $_.FullName $NewName
    }
}

#-----------------------------------------------------------[Execution]------------------------------------------------------------

Get-FilesToRenameNamespace | Rename-Namespaces -OldNamespace $OldNamespace -NewNamespace $NewNamespace

Rename-Project $SolutionDirectory $OldNamespace $NewNamespace
Rename-Solution $SolutionDirectory $OldNamespace $NewNamespace


Write-Output "End of script"

Скрипт для переименования руководств проекта.

<#
.SYNOPSIS
  Renames all the project guids in a solution so that they are unique

.DESCRIPTION
  When a new visual studio solution is cloned, project guids need to change as well.

.PARAMETER Path
  Path to the solution file e.g. MyCompany.MyApp\MyCompany.MyApp.sln

.INPUTS
  <Inputs if any, otherwise state None>

.OUTPUTS
  <Outputs if any, otherwise state None - example: Log file stored in C:\Windows\Temp\<name>.log>

.NOTES
  Version:        1.0
  Author:         Chui Tey
  Creation Date:  15-08-2018
  Purpose/Change: Initial script development

.EXAMPLE
  .\Rename-Solution.ps1 -Path .\MyCompany.MyApp [-Verbose]
#>

[CmdletBinding(SupportsShouldProcess)]
param
(
    [Parameter(Mandatory)]
    [string]
    $Path
)

#---------------------------------------------------------[Initialisations]--------------------------------------------------------

$ErrorActionPreference = "Stop"

$SolutionPath = $Path
$SolutionDirectory = (Get-Item $SolutionPath).DirectoryName

Write-Verbose "`$SolutionPath=`"$SolutionPath`""
Write-Verbose "`$SolutionDirectory=`"$SolutionDirectory`""

If (-Not (Test-Path $SolutionPath -PathType Leaf))
{
    Write-Error "SolutionPath $SolutionPath not present"
}

If (-Not $SolutionPath.EndsWith(".sln"))
{
    Write-Error "SolutionPath must end with '.sln'"
}

#-----------------------------------------------------------[Functions]------------------------------------------------------------

Function Get-ProjectGuid($SolutionPath)
{
    Get-Content $SolutionPath `
    | Where-Object { $_ -match "Project.+ `"(.+)`", `"{([0123456789ABCDEF-]+)}`"" } `
    | ForEach-Object { New-Object PsObject -Property @{ File = $Matches[1]; Guid = $Matches[2] } } `
    | Where-Object { Test-Path -PathType Leaf (Join-Path $SolutionDirectory $_.File) }
}

Function New-Type3Guid([string] $src)
{
    If ($src.Length -eq 0 -or $src -eq $null)
    {
        Write-Error "New-Type3Guid $src must not be empty"
    }

    $md5 = [System.Security.Cryptography.MD5]::Create()
    $hash = $md5.ComputeHash([System.Text.Encoding]::Default.GetBytes($src))
    $md5.Dispose()

    $newGuid = [System.Guid]::new($hash)
    Write-Verbose "New-Type3Guid $src => $newGuid"
    Return $newGuid
}

Function New-ProjectGuidMapping
{
    param
    (
        [Parameter(Mandatory)]
        [string]
        $SolutionPath
    )

    $ProjectGuidMapping = @{}
    Get-ProjectGuid $SolutionPath `
    | ForEach-Object {
        $filename = $_.File
        Write-Verbose "Calling New-Type3Guid $filename"
        $guid = New-Type3Guid $filename
        $ProjectGuidMapping[$_.Guid] = $guid.ToString().ToUpper() 
    }
    Return $ProjectGuidMapping
}

Function Rename-ProjectGuid
{
    [CmdletBinding(SupportsShouldProcess)]
    param ($ProjectGuidMapping)

    $projects = [PSObject[]] (Get-ChildItem -Recurse -File -Path $SolutionDirectory -Filter "*.csproj")
    $solutions = [PSObject[]] (Get-ChildItem -Recurse -File -Path $SolutionDirectory -Filter "*.sln")

    $items = $projects + $solutions
    ForEach ($item in $items)
    {
        $OldContent = Get-Content -Path $item.FullName

        ForEach ($Key in $ProjectGuidMapping.Keys)
        {
            Write-Verbose "Checking key $Key"
            If ($OldContent -cmatch $Key)
            {
                Write-Verbose "Matched $Key in $($Item.FullName)"
                If ($PSCmdlet.ShouldProcess($item.FullName, "Rename-ProjectGuids"))
                {
                    Write-Verbose "Rename-ProjectGuids $($item.FullName) $Key to $($ProjectGuidMapping[$Key])"
                    $NewContent = $OldContent -creplace $Key,$ProjectGuidMapping[$Key]
                    Set-Content -Path $Item.FullName -Value $NewContent
                    $OldContent = $NewContent
                }
            }
        }
    }
}

$ProjectGuidMapping = New-ProjectGuidMapping $SolutionPath
Rename-ProjectGuid $ProjectGuidMapping
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...