提交 acbcef3c 编写于 作者: J Jared Parsons 提交者: GitHub

Merge pull request #20924 from jaredpar/fix-publish

Restructure how assets are published
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26616.2
VisualStudioVersion = 15.0.26621.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{A41D1B99-F489-4C43-BBDF-96D61B19A6B9}"
EndProject
......@@ -375,6 +375,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpCodeStyleTests", "src
EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "BasicCodeStyleTests", "src\CodeStyle\VisualBasic\Tests\BasicCodeStyleTests.vbproj", "{E512C6C1-F085-4AD7-B0D9-E8F1A0A2A510}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoslynPublish", "src\Tools\RoslynPublish\RoslynPublish.csproj", "{2D36C343-BB6A-4CB5-902B-E2145ACCB58F}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Compilers\VisualBasic\BasicAnalyzerDriver\BasicAnalyzerDriver.projitems*{2523d0e6-df32-4a3e-8ae0-a19bffae2ef6}*SharedItemsImports = 4
......@@ -1001,6 +1003,10 @@ Global
{E512C6C1-F085-4AD7-B0D9-E8F1A0A2A510}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E512C6C1-F085-4AD7-B0D9-E8F1A0A2A510}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E512C6C1-F085-4AD7-B0D9-E8F1A0A2A510}.Release|Any CPU.Build.0 = Release|Any CPU
{2D36C343-BB6A-4CB5-902B-E2145ACCB58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D36C343-BB6A-4CB5-902B-E2145ACCB58F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D36C343-BB6A-4CB5-902B-E2145ACCB58F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D36C343-BB6A-4CB5-902B-E2145ACCB58F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -1179,6 +1185,7 @@ Global
{9FF1205F-1D7C-4EE4-B038-3456FE6EBEAF} = {DC014586-8D07-4DE6-B28E-C0540C59C085}
{5018D049-5870-465A-889B-C742CE1E31CB} = {DC014586-8D07-4DE6-B28E-C0540C59C085}
{E512C6C1-F085-4AD7-B0D9-E8F1A0A2A510} = {DC014586-8D07-4DE6-B28E-C0540C59C085}
{2D36C343-BB6A-4CB5-902B-E2145ACCB58F} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {604E6B91-7BC0-4126-AE07-D4D2FEFC3D29}
......
......@@ -40,6 +40,7 @@
<MicrosoftDiaSymReaderNativeVersion>1.6.0-beta2-25304</MicrosoftDiaSymReaderNativeVersion>
<MicrosoftDiaSymReaderPortablePdbVersion>1.3.0</MicrosoftDiaSymReaderPortablePdbVersion>
<MicrosoftDotNetIBCMerge>4.7.2-alpha-00001</MicrosoftDotNetIBCMerge>
<MicrosoftDotNetVersionToolsVersion>1.0.27-prerelease-01811-02</MicrosoftDotNetVersionToolsVersion>
<MicrosoftIdentityModelClientsActiveDirectoryVersion>3.13.8</MicrosoftIdentityModelClientsActiveDirectoryVersion>
<MicrosoftInternalPerformanceCodeMarkersDesignTimeVersion>15.0.26507-alpha</MicrosoftInternalPerformanceCodeMarkersDesignTimeVersion>
<MicrosoftInternalVisualStudioShellInterop140DesignTimeVersion>14.3.25407-alpha</MicrosoftInternalVisualStudioShellInterop140DesignTimeVersion>
......
{
"branches": {
"master": {
"nugetKind": "PerBuildPreRelease",
"version": "2.6.*",
"nuget": [ "https://dotnet.myget.org/F/roslyn/api/v2/package" ],
"vsix": [ "https://dotnet.myget.org/F/roslyn/vsix/upload" ],
"channels": [ "dev15.5", "dev15.5p1" ]
},
"dev/jaredpar/fix-publish": {
"nugetKind": "PerBuildPreRelease",
"version": "2.6.*",
"nuget": [ "https://dotnet.myget.org/F/roslyn/api/v2/package" ],
"vsix": [ "https://dotnet.myget.org/F/roslyn/vsix/upload" ],
"channels": [ "publish-test" ]
}
},
"releases": {
"dev15.5": {
"nugetKind": "Release",
"version": "2.3.*",
"nuget": [ "https://api.nuget.org/v3/index.json" ],
"vsix": [ "https://dotnet.myget.org/F/roslyn/vsix/upload" ],
"channels": [ "dev15.3" ]
}
}
}
......@@ -206,6 +206,7 @@ function Build-ExtraSignArtifacts() {
Run-MSBuild "Templates\Templates.sln /p:VersionType=Release"
Run-MSBuild "DevDivInsertionFiles\DevDivInsertionFiles.sln"
Copy-Item -Force "Vsix\myget_org-extensions.config" $configDir
}
finally {
Pop-Location
......
......@@ -8,7 +8,8 @@
<ScriptArgs></ScriptArgs>
<ScriptArgs Condition="'$(Configuration)' == 'Release'">-release</ScriptArgs>
<ScriptArgs Condition="'$(BUILD_SOURCEBRANCH)' != ''">$(ScriptArgs) -branch $(BUILD_SOURCEBRANCH)</ScriptArgs>
<ScriptArgs Condition="'$(RoslynNuGetApiKey)' != ''">$(ScriptArgs) -nugetApiKey $(RoslynNuGetApiKey)</ScriptArgs>
<ScriptArgs Condition="'$(RoslynNuGetApiKey)' != ''">$(ScriptArgs) -myGetApiKey $(RoslynNuGetApiKey)</ScriptArgs>
<ScriptArgs Condition="'$(RoslynGitHubToken)' != ''">$(ScriptArgs) -gitHubUserName $(RoslynGitHubUserName) -gitHubToken $(RoslynGitHubToken) -gitHubEmail $(RoslynGitHubEmail)</ScriptArgs>
<ScriptArgs Condition="'$(SkipTest)' != 'true'">$(ScriptArgs) -testDesktop</ScriptArgs>
<ScriptArgs Condition="'$(SkipPublish)' != 'true'">$(ScriptArgs) -publish</ScriptArgs>
</PropertyGroup>
......
......@@ -6,11 +6,17 @@ param (
[string]$msbuildDir = "",
[switch]$cibuild = $false,
[string]$branchName = "master",
[string]$nugetApiKey = "",
[string]$assemblyVersion = "42.42.42.4242",
[switch]$testDesktop = $false,
[switch]$publish = $false,
[switch]$help = $false,
# Credentials
[string]$myGetApiKey = "",
[string]$nugetApiKey = "",
[string]$gitHubUserName = "",
[string]$gitHubToken = "",
[string]$gitHubEmail = "",
[parameter(ValueFromRemainingArguments=$true)] $badArgs)
Set-StrictMode -version 2.0
......@@ -71,7 +77,6 @@ function Build-InsertionItems() {
Run-MSBuild "DevDivVsix\CompilersPackage\Microsoft.CodeAnalysis.Compilers.vsmanproj $extraArgs"
Run-MSBuild "DevDivVsix\MicrosoftCodeAnalysisLanguageServices\Microsoft.CodeAnalysis.LanguageServices.vsmanproj $extraArgs"
Run-MSBuild "..\Dependencies\Microsoft.NetFX20\Microsoft.NetFX20.nuget.proj"
Copy-Item -Force "Vsix\myget_org-extensions.config" $configDir
}
finally {
Pop-Location
......@@ -139,7 +144,7 @@ try {
Get-Process vbcscompiler -ErrorAction SilentlyContinue | Stop-Process
if ($publish) {
Exec-Block { & .\publish-assets.ps1 -binariesPath $configDir -branchName $branchName -apiKey $nugetApiKey -test:$(-not $official) }
Exec-Block { & .\publish-assets.ps1 -configDir $configDir -branchName $branchName -mygetApiKey $mygetApiKey -nugetApiKey $nugetApiKey -gitHubUserName $githubUserName -gitHubToken $gitHubToken -gitHubEmail $gitHubEmail -test:$(-not $official) }
}
Exec-Block { & .\copy-insertion-items.ps1 -binariesPath $configDir -test:$(-not $official) }
......
<#
.SYNOPSIS
Performs any post-test actions needed on the Roslyn build systems.
.PARAMETER UploadNuGets
If true, upload NuGets to MyGet.
# Publishes our build assets to nuget, myget, dotnet/versions, etc ..
#
# The publish operation is best visioned as an optional yet repeatable post build operation. It can be
# run anytime after build or automatically as a post build step. But it is an operation that focuses on
# build outputs and hence can't rely on source code from the build being available
#
# Repeatable is important here because we have to assume that publishes can and will fail with some
# degree of regularity.
[CmdletBinding(PositionalBinding=$false)]
Param(
# Standard options
[string]$configDir = "",
[string]$branchName = "",
[string]$releaseName = "",
[switch]$test,
# Credentials
[string]$gitHubUserName = "",
[string]$gitHubToken = "",
[string]$gitHubEmail = "",
[string]$nugetApiKey = "",
[string]$myGetApiKey = ""
)
Set-StrictMode -version 2.0
$ErrorActionPreference="Stop"
.PARAMETER UploadVsixes
If true, upload Vsixes to MyGet.
function Get-PublishKey([string]$uploadUrl) {
$url = New-Object Uri $uploadUrl
switch ($url.Host) {
"dotnet.myget.org" { return $myGetApiKey }
"api.nuget.org" { return $nugetApiKey }
default { throw "Cannot determine publish key for $uploadUrl" }
}
}
.PARAMETER binariesPath
The root directory where the build outputs are written.
# Publish the NuGet packages to the specified URL
function Publish-NuGet([string]$packageDir, [string]$uploadUrl) {
Push-Location $packageDir
try {
Write-Host "Publishing $(Split-Path -leaf $packageDir) to $uploadUrl"
$packages = [xml](Get-Content "$packageDir\myget_org-packages.config")
$apiKey = Get-PublishKey $uploadUrl
foreach ($package in $packages.packages.package) {
$nupkg = $package.id + "." + $package.version + ".nupkg"
Write-Host " Publishing $nupkg"
if (-not (Test-Path $nupkg)) {
throw "$nupkg does not exist"
}
.PARAMETER branchName
The name of the branch that is being built.
if (-not $test) {
Exec-Console $nuget "push $nupkg -Source $uploadUrl -ApiKey $apiKey -NonInteractive -Verbosity quiet"
}
}
}
finally {
Pop-Location
}
}
.PARAMETER test
Whether or not to just test this script vs. actually publish
function Publish-Vsix([string]$uploadUrl) {
Push-Location $configDir
try {
Write-Host "Publishing VSIX to $uploadUrl"
$apiKey = Get-PublishKey $uploadUrl
$extensions = [xml](Get-Content (Join-Path $configDir "myget_org-extensions.config"))
foreach ($extension in $extensions.extensions.extension) {
$vsix = Join-Path $extension.path ($extension.id + ".vsix")
if (-not (Test-Path $vsix)) {
throw "VSIX $vsix does not exist"
}
#>
Param(
[string]$binariesPath = $null,
[string]$branchName = $null,
[string]$apiKey = $null,
[switch]$test
Write-Host " Publishing '$vsix'"
if (-not $test) {
$response = Invoke-WebRequest -Uri $uploadUrl -Headers @{"X-NuGet-ApiKey"=$apiKey} -ContentType 'multipart/form-data' -InFile $vsix -Method Post -UseBasicParsing
if ($response.StatusCode -ne 201) {
throw "Failed to upload VSIX extension: $vsix. Upload failed with Status code: $response.StatusCode"
}
}
}
}
finally {
Pop-Location
}
}
)
set-strictmode -version 2.0
$ErrorActionPreference="Stop"
function Publish-Channel([string]$packageDir, [string]$name) {
$publish = Join-Path $configDir "Exes\RoslynPublish\RoslynPublish.exe"
$args = "-nugetDir $packageDir -channel $name -gu $gitHubUserName -gt $gitHubToken -ge $githubEmail"
Write-Host "Publishing $packageDir to channel $name"
if (-not $test) {
Exec-Console $publish $args
}
}
try
{
Write-Host "Starting PostTest script..."
# We need to remove 'refs/heads/' from the beginning of the string
$branchName = $branchName -Replace "^refs/heads/"
switch ($branchName)
{
"dev15.3.x" { }
"master" { }
default
{
if (-not $test)
{
Write-Host "Branch $branchName is not supported for publishing"
exit 1
# Do basic verification on the values provided in the publish configuration
function Test-Entry($publishData, [switch]$isBranch) {
if ($isBranch) {
if ($publishData.nuget -ne $null) {
$kind = $publishData.nugetKind;
if ($kind -ne "PerBuildPreRelease") {
throw "Branches are only allowed to publish PerBuildPreRelease"
}
}
}
}
# MAIN BODY
Stop-Process -Name "vbcscompiler" -Force -ErrorAction SilentlyContinue
# Publish a given entry: branch or release.
function Publish-Entry($publishData, [switch]$isBranch) {
Test-Entry $publishData -isBranch:$isBranch
$packageDir = Join-Path $nugetDir $publishData.nugetKind
# Load in the NuGet.exe information
. "$PSScriptRoot\..\..\..\build\scripts\LoadNuGetInfo.ps1"
write-host "NuGet.exe path is $nugetexe"
$exitCode = 0
# First publish the NuGet packages to the specified feeds
foreach ($url in $publishData.nuget) {
Publish-NuGet $packageDir $url
}
Write-Host "Uploading NuGet packages..."
# Next publish the VSIX to the specified feeds
$vsixData = $publishData.vsix
if ($vsixData -ne $null) {
Publish-Vsix $vsixData
}
$nugetPath = Join-Path $binariesPath "NuGet\PerBuildPreRelease"
# Finally get our channels uploaded to versions
foreach ($channel in $publishData.channels) {
Publish-Channel $packageDir $channel
}
[xml]$packages = Get-Content "$nugetPath\myget_org-packages.config"
exit 0
}
$sourceUrl = "https://dotnet.myget.org/F/roslyn/api/v2/package"
pushd $nugetPath
foreach ($package in $packages.packages.package)
{
$nupkg = $package.id + "." + $package.version + ".nupkg"
Write-Host " Uploading '$nupkg' to '$sourceUrl'"
if (-not (test-path $nupkg))
{
Write-Error "NuGet $nupkg does not exist"
$exitCode = 6
}
function Test-Member($obj, [string]$name) {
$value = Get-Member -Name $name -InputObject $obj
return $value -ne $null
}
if (-not $test)
{
& "$NuGetExe" push "$nupkg" `
-Source $sourceUrl `
-ApiKey $apiKey `
-NonInteractive `
-Verbosity quiet
if ($LastExitCode -ne 0)
{
Write-Error "Failed to upload NuGet package: $nupkg"
$exitCode = 3
}
}
# This script is interested in the short branch name: master, dev15.x, etc ... But several
# of our publish operations specify fully branch names like /refs/heads/master. Normalizing
# those out to the short branch name here.
function Normalize-BranchName([string]$branchName) {
switch -regex ($branchName) {
"refs/heads/(.*)" { return $matches[1] }
"refs/pull/\d*/(.*)" { return $matches[1] }
default { return $branchName }
}
popd
}
Write-Host "Uploading VSIX extensions..."
try {
. (Join-Path $PSScriptRoot "..\..\..\build\scripts\build-utils.ps1")
$nuget = Ensure-NuGet
$nugetDir = Join-Path $configDir "NuGet"
$vsixPath = $binariesPath
if ($configDir -eq "") {
Write-Host "Must provide the build output with -configDir"
exit 1
}
[xml]$extensions = Get-Content "$vsixPath\myget_org-extensions.config"
# TODO: use the live file
$publishFilePath = Join-Path $repoDir "build\config\PublishData.json"
$data = ConvertFrom-Json (Get-Content -raw $publishFilePath)
pushd $vsixPath
foreach ($extension in $extensions.extensions.extension)
{
$vsix = join-path $extension.path ($extension.id + ".vsix")
if (-not (test-path $vsix))
{
Write-Error "VSIX $vsix does not exist"
$exitCode = 6
if ($branchName -ne "" -and $releaseName -ne "") {
Write-Host "Can only specify -branchName or -releaseName, not both"
exit 1
}
elseif ($branchName -ne "") {
$branchName = Normalize-BranchName $branchName
if (-not (Test-Member $data.branches $branchName)) {
Write-Host "$branchName is not listed for publishing"
exit 0
}
$requestUrl = "https://dotnet.myget.org/F/roslyn/vsix/upload"
Write-Host " Uploading '$vsix' to '$requestUrl'"
if (-not $test)
{
$response = Invoke-WebRequest -Uri $requestUrl -Headers @{"X-NuGet-ApiKey"=$apiKey} -ContentType 'multipart/form-data' -InFile $vsix -Method Post -UseBasicParsing
if ($response.StatusCode -ne 201)
{
Write-Error "Failed to upload VSIX extension: $vsix. Upload failed with Status code: $response.StatusCode"
$exitCode = 4
}
}
Publish-Entry $data.branches.$branchName -isBranch:$true
}
popd
Write-Host "Completed PostTest script with an exit code of '$exitCode'"
elseif ($releaseName -ne "") {
if (-not (Test-Member $data.releases $releaseName)) {
Write-Host "$releaseName is not a valid release"
exit 1
}
exit $exitCode
Publish-Entry $data.releases.$releaseName -isBranch:$false
}
else {
Write-Host "Need to specify -branchName or -releaseName"
exit 1
}
}
catch [exception]
{
write-host $_.Exception
exit -1
catch {
Write-Host $_
Write-Host $_.Exception
Write-Host $_.ScriptStackTrace
exit 1
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.0.0.0" newVersion="4.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Mono.Options;
using Microsoft.DotNet.VersionTools.Automation;
namespace RoslynPublish
{
internal static class Program
{
internal static int Main(string[] args)
{
try
{
return Go(args).GetAwaiter().GetResult();
}
catch (Exception ex)
{
Console.WriteLine($"Error updating versions: {ex.Message}");
Console.WriteLine(ex.StackTrace);
return 1;
}
}
private static async Task<int> Go(string[] args)
{
string gitHubUserName = null;
string gitHubEmail = null;
string gitHubToken = null;
string channel = null;
string nugetDir = null;
string owner = "dotnet";
var optionSet = new OptionSet
{
{"c|channel=", "Roslyn channel to update", v => channel = v },
{"gu|gitHubUserName=", "Github User Name for publish", v => gitHubUserName = v },
{"gt|gitHubToken=", "Github token for publish", v => gitHubToken = v },
{"ge|gitHubEmail=", "Github email for publish", v => gitHubEmail = v },
{"nd|nugetDir=", "Directory containing NuGet packages", v => nugetDir = v },
{"o|owner=", "Version repo to update (default dotnet)", v => owner = v }
};
if (!TryParse(optionSet, args))
{
optionSet.WriteOptionDescriptions(Console.Out);
return 1;
}
var gitHubAuth = new GitHubAuth(authToken: gitHubToken, user: gitHubUserName, email: gitHubEmail);
var updater = new GitHubVersionsRepoUpdater(gitHubAuth, owner, "versions");
var packages = Directory.EnumerateFiles(nugetDir, searchPattern: "*.nupkg");
var versionsPath = $"build-info/dotnet/roslyn/{channel}";
await updater.UpdateBuildInfoAsync(
packages,
versionsPath,
updateLatestPackageList: true,
updateLatestVersion: true,
updateLastBuildPackageList: true);
return 0;
}
private static bool TryParse(OptionSet optionSet, string[] args)
{
var parseSucceed = true;
try
{
var rest = optionSet.Parse(args);
if (rest.Count != 0)
{
Console.WriteLine($"Unexpected values: {rest[0]}");
parseSucceed = false;
}
}
catch (OptionException e)
{
Console.WriteLine(e.Message);
parseSucceed = false;
}
return parseSucceed;
}
}
}
# RoslynPublish
Command line wrapper on top of Microsoft.DotNet.VersionTools that allows for updating of
information on dotnet/versions. Takes the following arguments:
- gitHubUserName: User name to log in with
- gitHubToken: Token to log in with
- gitHubEmail: Email to make the edits with
- nugetDir: directory containing NuGet packages to upload
- channel: channel to write new information to on dotnet/versions
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\build\Targets\SettingsSdk.props" />
<PropertyGroup>
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
<PlatformTarget>AnyCPU</PlatformTarget>
<OutputType>Exe</OutputType>
<RootNamespace>RoslynPublish</RootNamespace>
<AssemblyName>RoslynPublish</AssemblyName>
<TargetFramework>net462</TargetFramework>
<RuntimeIdentifiers>win7</RuntimeIdentifiers>
<SignAssembly>false</SignAssembly>
<AutomaticBindingRedirects>true</AutomaticBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WindowsBase" />
<PackageReference Include="Microsoft.DotNet.VersionTools" Version="$(MicrosoftDotNetVersionToolsVersion)" />
<PackageReference Include="Mono.Options" Version="$(MonoOptionsVersion)" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="README.md" />
</ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" />
</Project>

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26621.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoslynPublish", "RoslynPublish.csproj", "{9C0660D9-48CA-40E1-BABA-8F6A1F11FE10}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9C0660D9-48CA-40E1-BABA-8F6A1F11FE10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C0660D9-48CA-40E1-BABA-8F6A1F11FE10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C0660D9-48CA-40E1-BABA-8F6A1F11FE10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C0660D9-48CA-40E1-BABA-8F6A1F11FE10}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {641B8FE5-2E96-4EC9-8036-EFF4F8DB2149}
EndGlobalSection
EndGlobal
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册