PowerShell Script to Create Visual Studio Project Template Extension Zip Issue

前端 未结 1 970
-上瘾入骨i
-上瘾入骨i 2021-01-19 14:45

I\'m trying to write a PowerShell script to write a Visual Studio extension which will simply add a project template. Here is a trimmed down version of the script to demonst

相关标签:
1条回答
  • 2021-01-19 15:31

    For some reason, [System.IO.Compression.ZipFile]::CreateFromDirectory will not create a zip/vsix file that works correctly, even though it will show as installed. The template does not show in the new project UI.

    Use 7zip instead to create zip files.

    While I tried to investigate this issue, I did not like that the code was not using fully qualified paths, and the strings were hard to look at. I refactored your code a bit.

    Based on my testing, this now works as expected.

    CODE

    <#
    http://stackoverflow.com/questions/40462544/powershell-script-to-create-visual-studio-project-template-extension-zip-issue
    
    For some reason, [System.IO.Compression.ZipFile]::CreateFromDirectory will not create a zip/vsix file that works correctly,
    even though it will show as installed.  The template does not show in the new project UI.
    
    Use 7zip instead to create zip files.
    #>
    
    Set-StrictMode -Version Latest
    $VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
    
    # Makes debugging from ISE easier.
    if ($PSScriptRoot -eq "")
    {
        $root = Split-Path -Parent $psISE.CurrentFile.FullPath
    }
    else
    {
        $root = $PSScriptRoot
    }
    
    Set-Location $root
    
    <#
    Create a zip file with items under Path in the root of the zip file.
    #>
    function New-ZipFile([string]$Path, [string]$FileName)
    {
        $zipExe = 'C:\Program Files\7-Zip\7z.exe'
        $currentLocation = Get-Location
        Set-Location $Path
        & $zipExe a -tzip $FileName * -r
        Set-Location $currentLocation
    }
    
    # Create temporary directories for the zip archives
    
    "Extension", "Template" | % {New-Item (Join-Path $root $_) -ItemType Directory}
    
    # Build up the contents of the template file
    
    $templateContent = @'
    <?xml version="1.0" encoding="utf-8"?>
    <VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" xmlns:sdk="http://schemas.microsoft.com/developer/vstemplate-sdkextension/2010">
        <TemplateData>
            <Name>MyExtension</Name>
            <Description>MyExtension</Description>
            <Icon>MyExtension.ico</Icon>
            <ProjectType>CSharp</ProjectType>
            <ProjectSubType></ProjectSubType>
            <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>
            <SortOrder>1000</SortOrder>
            <TemplateID>61251892-9605-4816-846b-858352383c38</TemplateID>
            <CreateNewFolder>true</CreateNewFolder>
            <DefaultName>MyExtension</DefaultName>
            <ProvideDefaultName>true</ProvideDefaultName>
        </TemplateData>
        <TemplateContent>
            <Project File="MyExtension.csproj" ReplaceParameters="true"></Project>
        </TemplateContent>
    </VSTemplate>
    '@
    
    # Save the template file
    
    $templateContent | Out-File (Join-Path $root "Template\MyExtension.vstemplate") -Encoding "UTF8" #-NoNewline
    
    # Build up the contents of the proj file
    
    $projContent = @'
    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
        <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProductVersion>
        </ProductVersion>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{403C08FA-9E44-4A8A-A757-1662142E1334}</ProjectGuid>
        <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
        <OutputType>Library</OutputType>
        <AppDesignerFolder>Properties</AppDesignerFolder>
        <RootNamespace>$safeprojectname$</RootNamespace>
        <AssemblyName>$safeprojectname$</AssemblyName>
        <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
        <UseIISExpress>false</UseIISExpress>
        <IISExpressSSLPort />
        <IISExpressAnonymousAuthentication />
        <IISExpressWindowsAuthentication />
        <IISExpressUseClassicPipelineMode />
        </PropertyGroup>
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <DebugSymbols>true</DebugSymbols>
        <DebugType>full</DebugType>
        <Optimize>false</Optimize>
        <OutputPath>bin\</OutputPath>
        <DefineConstants>DEBUG;TRACE</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
        </PropertyGroup>
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
        <DebugType>pdbonly</DebugType>
        <Optimize>true</Optimize>
        <OutputPath>bin\</OutputPath>
        <DefineConstants>TRACE</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
        </PropertyGroup>
        <ItemGroup>
        <Reference Include="Microsoft.CSharp" />
        <Reference Include="System.ServiceModel" />
        <Reference Include="System.Transactions" />
        <Reference Include="System.Web.DynamicData" />
        <Reference Include="System.Web.Entity" />
        <Reference Include="System.Web.ApplicationServices" />
        <Reference Include="System.ComponentModel.DataAnnotations" />
        <Reference Include="System" />
        <Reference Include="System.Data" />
        <Reference Include="System.Core" />
        <Reference Include="System.Data.DataSetExtensions" />
        <Reference Include="System.Web.Extensions" />
        <Reference Include="System.Xml.Linq" />
        <Reference Include="System.Drawing" />
        <Reference Include="System.Web" />
        <Reference Include="System.Xml" />
        <Reference Include="System.Configuration" />
        <Reference Include="System.Web.Services" />
        <Reference Include="System.EnterpriseServices" />
        </ItemGroup>
        <PropertyGroup>
        <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
        <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
        </PropertyGroup>
        <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
        <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
        <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
        <ProjectExtensions>
        <VisualStudio>
            <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
            <WebProjectProperties>
                <UseIIS>False</UseIIS>
                <AutoAssignPort>True</AutoAssignPort>
                <DevelopmentServerPort>58060</DevelopmentServerPort>
                <DevelopmentServerVPath>/</DevelopmentServerVPath>
                <IISUrl>
                </IISUrl>
                <NTLMAuthentication>False</NTLMAuthentication>
                <UseCustomServer>True</UseCustomServer>
                <CustomServerUrl>http://localhost/</CustomServerUrl>
                <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
            </WebProjectProperties>
            </FlavorProperties>
        </VisualStudio>
        </ProjectExtensions>
        <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
            Other similar extension points exist, see Microsoft.Common.targets.
        <Target Name="BeforeBuild">
        </Target>
        <Target Name="AfterBuild">
        </Target>
        -->
    </Project>
    '@
    
    # Save the proj file
    
    $projContent | Out-File (Join-Path $root "Template\MyExtension.csproj") -Encoding "UTF8" #-NoNewline
    
    # Create the template zip file
    
    New-Item (Join-Path $root "Extension\ProjectTemplates\CSharp\Web\1033") -ItemType Directory
    New-ZipFile (Join-Path $root "Template") (Join-Path $root "Extension\ProjectTemplates\CSharp\Web\1033\MyExtension.zip")
    
    # Create a content types xml file (an error will be thrown if this does not exist)
    
    $conentTypesContent = @'
    <?xml version="1.0" encoding="utf-8"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="vsixmanifest" ContentType="text/xml" /><Default Extension="zip" ContentType="application/zip" /></Types>
    '@
    
    # Save the content types file
    
    $conentTypesContent | Out-File -literalPath (Join-Path $root "Extension\[Content_Types].xml") -Encoding "UTF8" #-NoNewline
    
    # Now create an extension manifest for the visual studio template
    
    $extensionContent = @'
    <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
        <Metadata>
            <Identity Id="MyExtension - 1" Version="0.1.0" Language="en-US" Publisher="MyExtension.net Ltd" />
            <DisplayName>MyExtension Project Template</DisplayName>
            <Description xml:space="preserve">MyExtension Project Template Extension</Description>
        </Metadata>
        <Installation>
            <InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[14.0]" />
        </Installation>
        <Dependencies>
            <Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" Version="[4.5,)" />
        </Dependencies>
        <Assets>
            <Asset Type="Microsoft.VisualStudio.ProjectTemplate" Path="ProjectTemplates" />
        </Assets>
    </PackageManifest>
    '@
    
    # Save the extension file
    
    $extensionContent | Out-File (Join-Path $root "Extension\extension.vsixmanifest") -Encoding "UTF8" #-NoNewline
    
    # Create the extension zip file
    
    New-ZipFile (Join-Path $root "Extension") (Join-Path $root "MyExtension.vsix")
    
    # Delete the temporary directories
    "Extension", "Template" | % {Remove-Item (Join-Path $root $_) -Recurse -Force}
    
    0 讨论(0)
提交回复
热议问题