创建 Visual Studio 项目模板扩展 Zip 问题的 PowerShell 脚本 [英] PowerShell Script to Create Visual Studio Project Template Extension Zip Issue

查看:43
本文介绍了创建 Visual Studio 项目模板扩展 Zip 问题的 PowerShell 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个 PowerShell 脚本来编写一个 Visual Studio 扩展,该扩展将简单地添加一个项目模板.这是脚本的精简版本以演示问题:

# 添加程序集添加类型 -Assembly System.IO.Compression.FileSystem# 为 zip 档案创建临时目录[System.IO.Directory]::CreateDirectory("扩展名")[System.IO.Directory]::CreateDirectory("模板")# 构建模板文件的内容$templateContent = "<?xml version="1.0`" encoding="utf-8`"?>`r`n"$templateContent += "<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`">`r`n"$templateContent += " <TemplateData>`r`n"$templateContent += " <Name>MyExtension</Name>`r`n"$templateContent += " <Description>MyExtension</Description>`r`n"$templateContent += " <Icon>MyExtension.ico</Icon>`r`n"$templateContent += " <ProjectType>CSharp</ProjectType>`r`n"$templateContent += " <ProjectSubType></ProjectSubType>`r`n"$templateContent += " <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>`r`n"$templateContent += " <SortOrder>1000</SortOrder>`r`n"$templateContent += " <TemplateID>61251892-9605-4816-846b-858352383c38</TemplateID>`r`n"$templateContent += " <CreateNewFolder>true</CreateNewFolder>`r`n"$templateContent += " <DefaultName>MyExtension</DefaultName>`r`n"$templateContent += " <ProvideDefaultName>true</ProvideDefaultName>`r`n"$templateContent += " </TemplateData>`r`n"$templateContent += " <TemplateContent>`r`n"$templateContent += " <Project File="MyExtension.csproj`" ReplaceParameters="true`"></Project>`r`n"$templateContent += " </TemplateContent>`r`n"$templateContent += "</VSTemplate>"# 保存模板文件$templateContent |Out-File ([System.IO.Path]::Combine("Template", "MyExtension.vstemplate")) -Encoding "UTF8" -NoNewline# 构建proj文件的内容$projContent = "<?xml version="1.0`" encoding="utf-8`"?>`r`n"$projContent += "<Project ToolsVersion="4.0`" DefaultTargets="Build`" xmlns="http://schemas.microsoft.com/developer/msbuild/2003`">`r`n"$projContent += " <Import Project="`$(MSBuildExtensionsPath)\`$(MSBuildToolsVersion)\Microsoft.Common.props`" Condition="Exists('`$(MSBuildExtensionsPath)\`$(MSBuildToolsVersion)\Microsoft.Common.props')`"/>`r`n"$projContent += " `r`n"$projContent += " <Configuration Condition=`" '`$(Configuration)' == '' `">Debug</Configuration>`r`n"$projContent += " <Platform Condition=`" '`$(Platform)' == '' `">AnyCPU</Platform>`r`n"$projContent += " <ProductVersion>`r`n"$projContent += " </ProductVersion>`r`n"$projContent += " 2.0`r`n"$projContent += " <ProjectGuid>{403C08FA-9E44-4A8A-A757-1662142E1334}</ProjectGuid>`r`n"$projContent += " <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuid$projContent += " <OutputType>Library</OutputType>`r`n"$projContent += " <AppDesignerFolder>Properties</AppDesignerFolder>`r`n"$projContent += " <RootNamespace>`$safeprojectname`$</RootNamespace>`r`n"$projContent += " <AssemblyName>`$safeprojectname`$</AssemblyName>`r`n"$projContent += " <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>`r`n"$projContent += " <UseIISExpress>false</UseIISExpress>`r`n"$projContent += " <IISExpressSSLPort/>`r`n"$projContent += " <IISExpressAnonymousAuthentication/>`r`n"$projContent += " <IISExpressWindowsAuthentication/>`r`n"$projContent += " <IISExpressUseClassicPipelineMode/>`r`n"$projContent += " </PropertyGroup>`r`n"$projContent += " <PropertyGroup Condition=`" '`$(Configuration)|`$(Platform)' == 'Debug|AnyCPU' `">`r`n"$projContent += " <DebugSymbols>true</DebugSymbols>`r`n"$projContent += " <DebugType>full</DebugType>`r`n"$projContent += " <Optimize>false</Optimize>`r`n"$projContent += " <OutputPath>bin\</OutputPath>`r`n"$projContent += " <DefineConstants>DEBUG;TRACE</DefineConstants>`r`n"$projContent += " <ErrorReport>prompt</ErrorReport>`r`n"$projContent += " <WarningLevel>4</WarningLevel>`r`n"$projContent += " </PropertyGroup>`r`n"$projContent += " <PropertyGroup Condition=`" '`$(Configuration)|`$(Platform)' == 'Release|AnyCPU' `">`r`n"$projContent += " <DebugType>pdbonly</DebugType>`r`n"$projContent += " <Optimize>true</Optimize>`r`n"$projContent += " <OutputPath>bin\</OutputPath>`r`n"$projContent += " <DefineConstants>TRACE</DefineConstants>`r`n"$projContent += " <ErrorReport>prompt</ErrorReport>`r`n"$projContent += " <WarningLevel>4</WarningLevel>`r`n"$projContent += " </PropertyGroup>`r`n"$projContent += " `r`n"$projContent += " <Reference Include="Microsoft.CSharp`"/>`r`n"$projContent += " <Reference Include="System.ServiceModel`"/>`r`n"$projContent += " <Reference Include="System.Transactions`"/>`r`n"$projContent += " <Reference Include="System.Web.DynamicData`"/>`r`n"$projContent += " <Reference Include="System.Web.Entity`"/>`r`n"$projContent += " <Reference Include="System.Web.ApplicationServices`"/>`r`n"$projContent += " <Reference Include="System.ComponentModel.DataAnnotations`"/>`r`n"$projContent += " <Reference Include="System`"/>`r`n"$projContent += " <Reference Include="System.Data`"/>`r`n"$projContent += " <Reference Include="System.Core`"/>`r`n"$projContent += " <Reference Include="System.Data.DataSetExtensions`"/>`r`n"$projContent += " <Reference Include="System.Web.Extensions`"/>`r`n"$projContent += " <Reference Include="System.Xml.Linq`"/>`r`n"$projContent += " <Reference Include="System.Drawing`"/>`r`n"$projContent += " <Reference Include="System.Web`"/>`r`n"$projContent += " <Reference Include="System.Xml`"/>`r`n"$projContent += " <Reference Include="System.Configuration`"/>`r`n"$projContent += " <Reference Include="System.Web.Services`"/>`r`n"$projContent += " <Reference Include="System.EnterpriseServices`"/>`r`n"$projContent += " </ItemGroup>`r`n"$projContent += " `r`n"$projContent += " <VisualStudioVersion Condition="'`$(VisualStudioVersion)' == ''`">10.0</VisualStudioVersion>`r`n"$projContent += " <VSToolsPath Condition=`"'`$(VSToolsPath)' == ''`">`$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v`$(VisualStudioVersion)</VSToolsPath>`r`n"$projContent += " </PropertyGroup>`r`n"$projContent += " <Import Project="`$(MSBuildBinPath)\Microsoft.CSharp.targets`"/>`r`n"$projContent += " <Import Project="`$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets`" Condition=`"'`$(VSToolsPath)' != ''`"/>`r`n"$projContent += " <Import Project=`"`$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets`" Condition=`"false`"/>`r`n"$projContent += " <ProjectExtensions>`r`n"$projContent += " <VisualStudio>`r`n"$projContent += " <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}`">`r`n"$projContent += " <WebProjectProperties>`r`n"$projContent += " <UseIIS>False</UseIIS>`r`n"$projContent += " <AutoAssignPort>True</AutoAssignPort>`r`n"$projContent += " <DevelopmentServerPort>58060</DevelopmentServerPort>`r`n"$projContent += " <DevelopmentServerVPath>/</DevelopmentServerVPath>`r`n"$projContent += " `r`n"$projContent += " </IISUrl>`r`n"$projContent += " <NTLMAuthentication>False</NTLMAuthentication>`r`n"$projContent += " <UseCustomServer>True</UseCustomServer>`r`n"$projContent += " <CustomServerUrl>http://localhost/</CustomServerUrl>`r`n"$projContent += " <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>`r`n"$projContent += " </WebProjectProperties>`r`n"$projContent += " </FlavorProperties>`r`n"$projContent += " </VisualStudio>`r`n"$projContent += " </ProjectExtensions>`r`n"$projContent += " <!-- 要修改您的构建过程,请将您的任务添加到以下目标之一中并取消注释.`r`n"$projContent += " 其他类似的扩展点存在,参见 Microsoft.Common.targets.`r`n"$projContent += " <Target Name="BeforeBuild`">`r`n"$projContent += " </Target>`r`n"$projContent += " <Target Name="AfterBuild`">`r`n"$projContent += " </Target>`r`n"$projContent += " -->`r`n"$projContent += "</Project>"# 保存项目文件$projContent |Out-File ([System.IO.Path]::Combine("Template", "MyExtension.csproj")) -Encoding "UTF8" -NoNewline# 创建模板zip文件[System.IO.Directory]::CreateDirectory("Extension\ProjectTemplates\CSharp\Web\1033")[System.IO.Compression.ZipFile]::CreateFromDirectory("Template", "Extension\ProjectTemplates\CSharp\Web\1033\MyExtension.zip")# 创建content types xml文件(不存在会报错)$conentTypesContent = "<?xml version="1.0`" encoding="utf-8`"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-类型`"><默认扩展=`"vsixmanifest`" ContentType="text/xml`"/><默认扩展=`"zip`" ContentType="application/zip`"/><;/类型>"# 保存内容类型文件$conentTypesContent |Out-File -literalPath "Extension\[Content_Types].xml" -Encoding "UTF8" -NoNewline# 现在为 Visual Studio 模板创建一个扩展清单$extensionContent = "<PackageManifest Version="2.0.0`" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011`">`r`n"$extensionContent += " <元数据>`r`n"$extensionContent += " <Identity Id="MyExtension - 1`" Version="0.1.0`" Language="en-US`" Publisher="MyExtension.net Ltd`"/>`r`n"$extensionContent += " <DisplayName>MyExtension 项目模板</DisplayName>`r`n"$extensionContent += " <Description xml:space="preserve`">MyExtension 项目模板扩展</Description>`r`n"$extensionContent += " </Metadata>`r`n"$extensionContent += " <安装>`r`n"$extensionContent += " <InstallationTarget Id="Microsoft.VisualStudio.Community`" Version="[14.0]`"/>`r`n"$extensionContent += " </Installation>`r`n"$extensionContent += " <Dependencies>`r`n"$extensionContent += " <Dependency Id="Microsoft.Framework.NDP`" DisplayName="Microsoft .NET Framework`" Version="[4.5,)`"/>`r`n"$extensionContent += " </Dependencies>`r`n"$extensionContent += " <Assets>`r`n"$extensionContent += " <Asset Type="Microsoft.VisualStudio.ProjectTemplate`" Path="ProjectTemplates`"/>`r`n"$extensionContent += " </Assets>`r`n"$extensionContent += "</PackageManifest>"# 保存扩展文件$extensionContent |输出文件Extension\extension.vsixmanifest"-编码UTF8"-NoNewline# 创建扩展zip文件[System.IO.Compression.ZipFile]::CreateFromDirectory("Extension", "MyExtension.vsix")# 删除临时目录[System.IO.Directory]::Delete("Extension", $true)[System.IO.Directory]::Delete("Template", $true)

当我运行脚本时,它成功生成了一个 MyExtension.vsix 文件.当我执行该文件时,它会安装扩展,但如果我现在打开 Visual Studio 2015 并创建一个新项目,则项目模板 (C# -> Web) 不存在.

但是,如果您执行以下步骤,则它可以正常工作(请确保您已先卸载旧扩展):

  1. 将 MyExtension.vsix 文件重命名为 MyExtension.zip,然后解压到一个目录
  2. 进入该目录并选择所有文件,右键单击并选择发送到压缩文件夹
  3. 将生成的 zip 文件重命名为 MyExtension.vsix
  4. 执行此文件以安装扩展

我花了几个小时才注意到这种情况解决了这个问题.然而,这是一个黑客,从长远来看,它会变得非常乏味.我想知道是否有人知道如何更改我的 PowerShell 脚本以解决此问题.

谢谢

解决方案

由于某种原因,[System.IO.Compression.ZipFile]::CreateFromDirectory 不会创建一个正常工作的 zip/vsix 文件,即使它会显示为已安装.该模板未显示在新项目 UI 中.

改用 7zip 来创建 zip 文件.

虽然我试图调查这个问题,但我不喜欢代码没有使用完全限定的路径,而且字符串很难看.我重构了你的代码.

根据我的测试,这现在按预期工作.

代码

<预><代码><#http://stackoverflow.com/questions/40462544/powershell-script-to-create-visual-studio-project-template-extension-zip-issue出于某种原因, [System.IO.Compression.ZipFile]::CreateFromDirectory 不会创建一个正常工作的 zip/vsix 文件,即使它会显示为已安装.该模板不会显示在新项目 UI 中.改用 7zip 来创建 zip 文件.#>Set-StrictMode -Version 最新$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue# 使从 ISE 调试更容易.如果 ($PSScriptRoot -eq ""){$root = Split-Path -Parent $psISE.CurrentFile.FullPath}别的{$root = $PSScriptRoot}设置位置 $root<#创建一个 zip 文件,其中包含 zip 文件根目录中 Path 下的项目.#>function New-ZipFile([string]$Path, [string]$FileName){$zipExe = 'C:\Program Files\7-Zip\7z.exe'$currentLocation = 获取位置设置位置 $Path&$zipExe a -tzip $FileName * -r设置位置 $currentLocation}# 为 zip 档案创建临时目录扩展"、模板" |% {New-Item (Join-Path $root $_) -ItemType Directory}# 构建模板文件的内容$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"><模板数据><名称>我的分机</名称><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></模板数据><模板内容><Project File="MyExtension.csproj" ReplaceParameters="true"></Project></模板内容></VSTemplate>'@# 保存模板文件$templateContent |Out-File (Join-Path $root "Template\MyExtension.vstemplate") -Encoding "UTF8" #-NoNewline# 构建proj文件的内容$projContent = @'<?xml version="1.0" encoding="utf-8"?><Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><导入项目="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/><属性组><Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration><Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform><产品版本></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>库</OutputType><AppDesignerFolder>属性</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>调试;跟踪</DefineConstants><ErrorReport>提示</ErrorReport><WarningLevel>4</WarningLevel></PropertyGroup><PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "><DebugType>pdbonly</DebugType><Optimize>true</Optimize><OutputPath>bin\</OutputPath><DefineConstants>TRACE</DefineConstants><ErrorReport>提示</ErrorReport><WarningLevel>4</WarningLevel></PropertyGroup><项目组><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="系统"/><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"/></项目组><属性组><VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion><VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath></PropertyGroup><导入项目="$(MSBuildBinPath)\Microsoft.CSharp.targets"/><导入项目="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''"/><Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false"/><项目扩展><VisualStudio><FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"><WebProjectProperties><UseIIS>假</UseIIS><AutoAssignPort>True</AutoAssignPort><DevelopmentServerPort>58060</DevelopmentServerPort><DevelopmentServerVPath>/</DevelopmentServerVPath><IISUrl></IISUrl><NTLMAuthentication>假</NTLMAuthentication><UseCustomServer>True</UseCustomServer><CustomServerUrl>http://localhost/</CustomServerUrl><SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile></WebProjectProperties></FlavorProperties></VisualStudio></ProjectExtensions><!-- 要修改您的构建过程,请将您的任务添加到以下目标之一中并取消注释.存在其他类似的扩展点,请参阅 Microsoft.Common.targets.<目标名称="BeforeBuild"></目标><目标名称="AfterBuild"></目标>--></项目>'@# 保存项目文件$projContent |Out-File (Join-Path $root "Template\MyExtension.csproj") -Encoding "UTF8" #-NoNewline# 创建模板zip文件New-Item (Join-Path $root "Extension\ProjectTemplates\CSharp\Web\1033") -ItemType 目录New-ZipFile (Join-Path $root "Template") (Join-Path $root "Extension\ProjectTemplates\CSharp\Web\1033\MyExtension.zip")# 创建content types xml文件(不存在会报错)$conentTypesContent = @'<?xml version="1.0" encoding="utf-8"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><默认扩展名="vsixmanifest" ContentType="text/xml"/><Default Extension="zip" ContentType="application/zip"/></Types>'@# 保存内容类型文件$conentTypesContent |Out-File -literalPath (Join-Path $root "Extension\[Content_Types].xml") -Encoding "UTF8" #-NoNewline# 现在为 Visual Studio 模板创建一个扩展清单$extensionContent = @'<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011"><元数据><Identity Id="MyExtension - 1" Version="0.1.0" Language="en-US" Publisher="MyExtension.net Ltd"/><DisplayName>MyExtension 项目模板</DisplayName><Description xml:space="preserve">MyExtension 项目模板扩展</Description></元数据><安装><InstallationTarget Id="Microsoft.VisualStudio.Community" 版本="[14.0]"/></安装><依赖项><Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" Version="[4.5,)"/></依赖项><资产><Asset Type="Microsoft.VisualStudio.ProjectTemplate" Path="ProjectTemplates"/></资产></PackageManifest>'@# 保存扩展文件$extensionContent |Out-File (Join-Path $root "Extension\extension.vsixmanifest") -Encoding "UTF8" #-NoNewline# 创建扩展zip文件New-ZipFile (Join-Path $root "Extension") (Join-Path $root "MyExtension.vsix")# 删除临时目录扩展"、模板" |% {Remove-Item (Join-Path $root $_) -Recurse -Force}

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 demonstrate the problem:

# Add the assemblies

Add-Type -Assembly System.IO.Compression.FileSystem

# Create temporary directories for the zip archives

[System.IO.Directory]::CreateDirectory("Extension")
[System.IO.Directory]::CreateDirectory("Template")

# Build up the contents of the template file

$templateContent = "<?xml version=`"1.0`" encoding=`"utf-8`"?>`r`n"
$templateContent += "<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`">`r`n"
$templateContent += "    <TemplateData>`r`n"
$templateContent += "        <Name>MyExtension</Name>`r`n"
$templateContent += "        <Description>MyExtension</Description>`r`n"
$templateContent += "        <Icon>MyExtension.ico</Icon>`r`n"
$templateContent += "        <ProjectType>CSharp</ProjectType>`r`n"
$templateContent += "        <ProjectSubType></ProjectSubType>`r`n"
$templateContent += "        <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>`r`n"
$templateContent += "        <SortOrder>1000</SortOrder>`r`n"
$templateContent += "        <TemplateID>61251892-9605-4816-846b-858352383c38</TemplateID>`r`n"
$templateContent += "        <CreateNewFolder>true</CreateNewFolder>`r`n"
$templateContent += "        <DefaultName>MyExtension</DefaultName>`r`n"
$templateContent += "        <ProvideDefaultName>true</ProvideDefaultName>`r`n"
$templateContent += "    </TemplateData>`r`n"
$templateContent += "    <TemplateContent>`r`n"
$templateContent += "        <Project File=`"MyExtension.csproj`" ReplaceParameters=`"true`"></Project>`r`n"
$templateContent += "    </TemplateContent>`r`n"
$templateContent += "</VSTemplate>"

# Save the template file

$templateContent | Out-File ([System.IO.Path]::Combine("Template", "MyExtension.vstemplate")) -Encoding "UTF8" -NoNewline

# Build up the contents of the proj file

$projContent = "<?xml version=`"1.0`" encoding=`"utf-8`"?>`r`n"
$projContent += "<Project ToolsVersion=`"4.0`" DefaultTargets=`"Build`" xmlns=`"http://schemas.microsoft.com/developer/msbuild/2003`">`r`n"
$projContent += "  <Import Project=`"`$(MSBuildExtensionsPath)\`$(MSBuildToolsVersion)\Microsoft.Common.props`" Condition=`"Exists('`$(MSBuildExtensionsPath)\`$(MSBuildToolsVersion)\Microsoft.Common.props')`" />`r`n"
$projContent += "  <PropertyGroup>`r`n"
$projContent += "    <Configuration Condition=`" '`$(Configuration)' == '' `">Debug</Configuration>`r`n"
$projContent += "    <Platform Condition=`" '`$(Platform)' == '' `">AnyCPU</Platform>`r`n"
$projContent += "    <ProductVersion>`r`n"
$projContent += "    </ProductVersion>`r`n"
$projContent += "    <SchemaVersion>2.0</SchemaVersion>`r`n"
$projContent += "    <ProjectGuid>{403C08FA-9E44-4A8A-A757-1662142E1334}</ProjectGuid>`r`n"
$projContent += "    <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>`r`n"
$projContent += "    <OutputType>Library</OutputType>`r`n"
$projContent += "    <AppDesignerFolder>Properties</AppDesignerFolder>`r`n"
$projContent += "    <RootNamespace>`$safeprojectname`$</RootNamespace>`r`n"
$projContent += "    <AssemblyName>`$safeprojectname`$</AssemblyName>`r`n"
$projContent += "    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>`r`n"
$projContent += "    <UseIISExpress>false</UseIISExpress>`r`n"
$projContent += "    <IISExpressSSLPort />`r`n"
$projContent += "    <IISExpressAnonymousAuthentication />`r`n"
$projContent += "    <IISExpressWindowsAuthentication />`r`n"
$projContent += "    <IISExpressUseClassicPipelineMode />`r`n"
$projContent += "  </PropertyGroup>`r`n"
$projContent += "  <PropertyGroup Condition=`" '`$(Configuration)|`$(Platform)' == 'Debug|AnyCPU' `">`r`n"
$projContent += "    <DebugSymbols>true</DebugSymbols>`r`n"
$projContent += "    <DebugType>full</DebugType>`r`n"
$projContent += "    <Optimize>false</Optimize>`r`n"
$projContent += "    <OutputPath>bin\</OutputPath>`r`n"
$projContent += "    <DefineConstants>DEBUG;TRACE</DefineConstants>`r`n"
$projContent += "    <ErrorReport>prompt</ErrorReport>`r`n"
$projContent += "    <WarningLevel>4</WarningLevel>`r`n"
$projContent += "  </PropertyGroup>`r`n"
$projContent += "  <PropertyGroup Condition=`" '`$(Configuration)|`$(Platform)' == 'Release|AnyCPU' `">`r`n"
$projContent += "    <DebugType>pdbonly</DebugType>`r`n"
$projContent += "    <Optimize>true</Optimize>`r`n"
$projContent += "    <OutputPath>bin\</OutputPath>`r`n"
$projContent += "    <DefineConstants>TRACE</DefineConstants>`r`n"
$projContent += "    <ErrorReport>prompt</ErrorReport>`r`n"
$projContent += "    <WarningLevel>4</WarningLevel>`r`n"
$projContent += "  </PropertyGroup>`r`n"
$projContent += "  <ItemGroup>`r`n"
$projContent += "    <Reference Include=`"Microsoft.CSharp`" />`r`n"
$projContent += "    <Reference Include=`"System.ServiceModel`" />`r`n"
$projContent += "    <Reference Include=`"System.Transactions`" />`r`n"
$projContent += "    <Reference Include=`"System.Web.DynamicData`" />`r`n"
$projContent += "    <Reference Include=`"System.Web.Entity`" />`r`n"
$projContent += "    <Reference Include=`"System.Web.ApplicationServices`" />`r`n"
$projContent += "    <Reference Include=`"System.ComponentModel.DataAnnotations`" />`r`n"
$projContent += "    <Reference Include=`"System`" />`r`n"
$projContent += "    <Reference Include=`"System.Data`" />`r`n"
$projContent += "    <Reference Include=`"System.Core`" />`r`n"
$projContent += "    <Reference Include=`"System.Data.DataSetExtensions`" />`r`n"
$projContent += "    <Reference Include=`"System.Web.Extensions`" />`r`n"
$projContent += "    <Reference Include=`"System.Xml.Linq`" />`r`n"
$projContent += "    <Reference Include=`"System.Drawing`" />`r`n"
$projContent += "    <Reference Include=`"System.Web`" />`r`n"
$projContent += "    <Reference Include=`"System.Xml`" />`r`n"
$projContent += "    <Reference Include=`"System.Configuration`" />`r`n"
$projContent += "    <Reference Include=`"System.Web.Services`" />`r`n"
$projContent += "    <Reference Include=`"System.EnterpriseServices`" />`r`n"
$projContent += "  </ItemGroup>`r`n"
$projContent += "  <PropertyGroup>`r`n"
$projContent += "    <VisualStudioVersion Condition=`"'`$(VisualStudioVersion)' == ''`">10.0</VisualStudioVersion>`r`n"
$projContent += "    <VSToolsPath Condition=`"'`$(VSToolsPath)' == ''`">`$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v`$(VisualStudioVersion)</VSToolsPath>`r`n"
$projContent += "  </PropertyGroup>`r`n"
$projContent += "  <Import Project=`"`$(MSBuildBinPath)\Microsoft.CSharp.targets`" />`r`n"
$projContent += "  <Import Project=`"`$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets`" Condition=`"'`$(VSToolsPath)' != ''`" />`r`n"
$projContent += "  <Import Project=`"`$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets`" Condition=`"false`" />`r`n"
$projContent += "  <ProjectExtensions>`r`n"
$projContent += "    <VisualStudio>`r`n"
$projContent += "      <FlavorProperties GUID=`"{349c5851-65df-11da-9384-00065b846f21}`">`r`n"
$projContent += "        <WebProjectProperties>`r`n"
$projContent += "          <UseIIS>False</UseIIS>`r`n"
$projContent += "          <AutoAssignPort>True</AutoAssignPort>`r`n"
$projContent += "          <DevelopmentServerPort>58060</DevelopmentServerPort>`r`n"
$projContent += "          <DevelopmentServerVPath>/</DevelopmentServerVPath>`r`n"
$projContent += "          <IISUrl>`r`n"
$projContent += "          </IISUrl>`r`n"
$projContent += "          <NTLMAuthentication>False</NTLMAuthentication>`r`n"
$projContent += "          <UseCustomServer>True</UseCustomServer>`r`n"
$projContent += "          <CustomServerUrl>http://localhost/</CustomServerUrl>`r`n"
$projContent += "          <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>`r`n"
$projContent += "        </WebProjectProperties>`r`n"
$projContent += "      </FlavorProperties>`r`n"
$projContent += "    </VisualStudio>`r`n"
$projContent += "  </ProjectExtensions>`r`n"
$projContent += "  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. `r`n"
$projContent += "       Other similar extension points exist, see Microsoft.Common.targets.`r`n"
$projContent += "  <Target Name=`"BeforeBuild`">`r`n"
$projContent += "  </Target>`r`n"
$projContent += "  <Target Name=`"AfterBuild`">`r`n"
$projContent += "  </Target>`r`n"
$projContent += "  -->`r`n"
$projContent += "</Project>"

# Save the proj file

$projContent | Out-File ([System.IO.Path]::Combine("Template", "MyExtension.csproj")) -Encoding "UTF8" -NoNewline

# Create the template zip file

[System.IO.Directory]::CreateDirectory("Extension\ProjectTemplates\CSharp\Web\1033")
[System.IO.Compression.ZipFile]::CreateFromDirectory("Template", "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 "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`">`r`n"
$extensionContent += "    <Metadata>`r`n"
$extensionContent += "        <Identity Id=`"MyExtension - 1`" Version=`"0.1.0`" Language=`"en-US`" Publisher=`"MyExtension.net Ltd`" />`r`n"
$extensionContent += "        <DisplayName>MyExtension Project Template</DisplayName>`r`n"
$extensionContent += "        <Description xml:space=`"preserve`">MyExtension Project Template Extension</Description>`r`n"
$extensionContent += "    </Metadata>`r`n"
$extensionContent += "    <Installation>`r`n"
$extensionContent += "        <InstallationTarget Id=`"Microsoft.VisualStudio.Community`" Version=`"[14.0]`" />`r`n"
$extensionContent += "    </Installation>`r`n"
$extensionContent += "    <Dependencies>`r`n"
$extensionContent += "        <Dependency Id=`"Microsoft.Framework.NDP`" DisplayName=`"Microsoft .NET Framework`" Version=`"[4.5,)`" />`r`n"
$extensionContent += "    </Dependencies>`r`n"
$extensionContent += "    <Assets>`r`n"
$extensionContent += "        <Asset Type=`"Microsoft.VisualStudio.ProjectTemplate`" Path=`"ProjectTemplates`" />`r`n"
$extensionContent += "    </Assets>`r`n"
$extensionContent += "</PackageManifest>"

# Save the extension file

$extensionContent | Out-File "Extension\extension.vsixmanifest" -Encoding "UTF8" -NoNewline

# Create the extension zip file

[System.IO.Compression.ZipFile]::CreateFromDirectory("Extension", "MyExtension.vsix")

# Delete the temporary directories
[System.IO.Directory]::Delete("Extension", $true)
[System.IO.Directory]::Delete("Template", $true)

When I run the script it successfully produces a MyExtension.vsix file. When I execute that file it installs the extension but if I now open Visual Studio 2015 and create a new project the project template (C# -> Web) doesn't exist.

However if you do the following steps then it works fine (make sure you have uninstalled the old extension first):

  1. Rename the MyExtension.vsix file to MyExtension.zip and then extract to a directory
  2. Go into that directory and select all the files, right click and select Send to Compressed Folder
  3. Rename the generated zip file to MyExtension.vsix
  4. Execute this file to install the extension

It's taken me hours to even notice this scenario fixes the issue. However this is a hack and in the long run it's going to become quite tedious. I was wondering if anyone knew how my PowerShell script can be changed to fix this.

Thanks

解决方案

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}

这篇关于创建 Visual Studio 项目模板扩展 Zip 问题的 PowerShell 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆