当前位置: 首页>>代码示例>>C#>>正文


C# BuildResult.AddResultsForTarget方法代码示例

本文整理汇总了C#中Microsoft.Build.Execution.BuildResult.AddResultsForTarget方法的典型用法代码示例。如果您正苦于以下问题:C# BuildResult.AddResultsForTarget方法的具体用法?C# BuildResult.AddResultsForTarget怎么用?C# BuildResult.AddResultsForTarget使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Microsoft.Build.Execution.BuildResult的用法示例。


在下文中一共展示了BuildResult.AddResultsForTarget方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: TestSimpleBuildRequest

        public void TestSimpleBuildRequest()
        {
            BuildRequestConfiguration configuration = CreateTestProject(1);
            try
            {
                TestTargetBuilder targetBuilder = (TestTargetBuilder)_host.GetComponent(BuildComponentType.TargetBuilder);
                IConfigCache configCache = (IConfigCache)_host.GetComponent(BuildComponentType.ConfigCache);

                configCache.AddConfiguration(configuration);

                BuildRequest request = CreateNewBuildRequest(1, new string[1] { "target1" });
                BuildRequestEntry entry = new BuildRequestEntry(request, configuration);
                BuildResult result = new BuildResult(request);
                result.AddResultsForTarget("target1", GetEmptySuccessfulTargetResult());
                targetBuilder.SetResultsToReturn(result);

                _requestBuilder.BuildRequest(GetNodeLoggingContext(), entry);
                WaitForEvent(_buildRequestCompletedEvent, "Build Request Completed");
                Assert.Equal(BuildRequestEntryState.Complete, entry.State);
                Assert.Equal(entry, _buildRequestCompleted_Entry);
                Assert.Equal(BuildResultCode.Success, _buildRequestCompleted_Entry.Result.OverallResult);
            }
            finally
            {
                DeleteTestProject(configuration);
            }
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:27,代码来源:RequestBuilder_Tests.cs

示例2: TaskHost_Tests

        /// <summary>
        /// Set up and initialize before each test is run
        /// </summary>
        ///
        public TaskHost_Tests()
        {
            LoggingServiceFactory loggingFactory = new LoggingServiceFactory(LoggerMode.Synchronous, 1);

            _loggingService = loggingFactory.CreateInstance(BuildComponentType.LoggingService) as LoggingService;

            _customLogger = new MyCustomLogger();
            _mockHost = new MockHost();
            _mockHost.LoggingService = _loggingService;

            _loggingService.RegisterLogger(_customLogger);
            _elementLocation = ElementLocation.Create("MockFile", 5, 5);

            BuildRequest buildRequest = new BuildRequest(1 /* submissionId */, 1, 1, new List<string>(), null, BuildEventContext.Invalid, null);
            BuildRequestConfiguration configuration = new BuildRequestConfiguration(1, new BuildRequestData("Nothing", new Dictionary<string, string>(), "4.0", new string[0], null), "2.0");

            configuration.Project = new ProjectInstance(ProjectRootElement.Create());

            BuildRequestEntry entry = new BuildRequestEntry(buildRequest, configuration);

            BuildResult buildResult = new BuildResult(buildRequest, false);
            buildResult.AddResultsForTarget("Build", new TargetResult(new TaskItem[] { new TaskItem("IamSuper", configuration.ProjectFullPath) }, TestUtilities.GetSkippedResult()));
            _mockRequestCallback = new MockIRequestBuilderCallback(new BuildResult[] { buildResult });
            entry.Builder = (IRequestBuilder)_mockRequestCallback;

            _taskHost = new TaskHost(_mockHost, entry, _elementLocation, null /*Dont care about the callback either unless doing a build*/);
            _taskHost.LoggingContext = new TaskLoggingContext(_loggingService, BuildEventContext.Invalid);
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:32,代码来源:TaskHost_Tests.cs

示例3: TestAddAndRetrieveResults

        public void TestAddAndRetrieveResults()
        {
            ResultsCache cache = new ResultsCache();
            BuildRequest request = new BuildRequest(1 /* submissionId */, 0, 1, new string[1] { "testTarget" }, null, BuildEventContext.Invalid, null); BuildResult result = new BuildResult(request);
            result.AddResultsForTarget("testTarget", TestUtilities.GetEmptyFailingTargetResult());
            cache.AddResult(result);

            BuildResult retrievedResult = cache.GetResultForRequest(request);

            Assert.True(AreResultsIdentical(result, retrievedResult));
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:11,代码来源:ResultsCache_Tests.cs

示例4: TestSimpleStateProgression

        public void TestSimpleStateProgression()
        {
            // Start in Ready
            BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" });
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary<string, string>(), "foo", new string[0], null), "2.0");
            BuildRequestEntry entry = new BuildRequestEntry(request, config);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Ready);
            Assert.AreEqual(entry.Request, request);
            Assert.IsNull(entry.Result);

            // Move to active.  Should not be any results yet.
            IDictionary<int, BuildResult> results = entry.Continue();
            Assert.AreEqual(entry.State, BuildRequestEntryState.Active);
            Assert.IsNull(entry.Result);
            Assert.IsNull(results);

            // Wait for results, move to waiting.
            BuildRequest waitingRequest = CreateNewBuildRequest(2, new string[1] { "bar" });
            entry.WaitForResult(waitingRequest);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);
            Assert.AreEqual(entry.Request, request);
            Assert.IsNull(entry.Result);

            // Provide the results, move to ready.
            BuildResult requiredResult = new BuildResult(waitingRequest);
            requiredResult.AddResultsForTarget("bar", TestUtilities.GetEmptySucceedingTargetResult());
            entry.ReportResult(requiredResult);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Ready);
            Assert.AreEqual(entry.Request, request);
            Assert.IsNull(entry.Result);

            // Continue the build, move to active.
            results = entry.Continue();
            Assert.AreEqual(entry.State, BuildRequestEntryState.Active);
            Assert.IsNull(entry.Result);
            Assert.AreEqual(results.Count, 1);
            Assert.IsTrue(results.ContainsKey(requiredResult.NodeRequestId));
            Assert.AreEqual(results[requiredResult.NodeRequestId], requiredResult);

            // Complete the build, move to completed.
            BuildResult result = new BuildResult(request);
            result.AddResultsForTarget("foo", TestUtilities.GetEmptySucceedingTargetResult());
            entry.Complete(result);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Complete);
            Assert.IsNotNull(entry.Result);
            Assert.AreEqual(entry.Result, result);
        }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:47,代码来源:BuildRequestEntry_Tests.cs

示例5: TestAddAndRetrieveResultsByConfiguration

        public void TestAddAndRetrieveResultsByConfiguration()
        {
            ResultsCache cache = new ResultsCache();
            BuildRequest request = new BuildRequest(1 /* submissionId */, 0, 1, new string[1] { "testTarget" }, null, BuildEventContext.Invalid, null);
            BuildResult result = new BuildResult(request);
            result.AddResultsForTarget("testTarget", TestUtilities.GetEmptyFailingTargetResult());
            cache.AddResult(result);

            request = new BuildRequest(1 /* submissionId */, 0, 1, new string[1] { "otherTarget" }, null, BuildEventContext.Invalid, null);
            result = new BuildResult(request);
            result.AddResultsForTarget("otherTarget", TestUtilities.GetEmptySucceedingTargetResult());
            cache.AddResult(result);

            BuildResult retrievedResult = cache.GetResultsForConfiguration(1);

            Assert.True(retrievedResult.HasResultsForTarget("testTarget"));
            Assert.True(retrievedResult.HasResultsForTarget("otherTarget"));
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:18,代码来源:ResultsCache_Tests.cs

示例6: TestNoCompleteToWaiting

        public void TestNoCompleteToWaiting()
        {
            Assert.Throws<InternalErrorException>(() =>
            {
                BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" });
                BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary<string, string>(), "foo", new string[0], null), "2.0");
                BuildRequestEntry entry = new BuildRequestEntry(request, config);
                Assert.Equal(entry.State, BuildRequestEntryState.Ready);

                entry.Continue();
                Assert.Equal(entry.State, BuildRequestEntryState.Active);

                BuildResult requiredResult = new BuildResult(request);
                requiredResult.AddResultsForTarget("foo", TestUtilities.GetEmptySucceedingTargetResult());
                entry.Complete(requiredResult);
                Assert.Equal(entry.State, BuildRequestEntryState.Complete);

                BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" });
                entry.WaitForResult(waitingRequest1);
            }
           );
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:22,代码来源:BuildRequestEntry_Tests.cs

示例7: TestBuildWithNewConfiguration

        public void TestBuildWithNewConfiguration()
        {
            BuildRequestData data = new BuildRequestData(Path.GetFullPath("TestFile"), new Dictionary<string, string>(), "TestToolsVersion", new string[0], null);
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, "2.0");
            _cache.AddConfiguration(config);

            // Configure the builder to spawn build requests
            MockRequestBuilder builder = (MockRequestBuilder)_host.GetComponent(BuildComponentType.RequestBuilder);
            BuildRequestData data2 = new BuildRequestData(Path.GetFullPath("OtherFile"), new Dictionary<string, string>(), "TestToolsVersion", new string[0], null);
            BuildRequestConfiguration unresolvedConfig = new BuildRequestConfiguration(data2, "2.0");
            builder.NewRequests.Add(new FullyQualifiedBuildRequest[1] { new FullyQualifiedBuildRequest(unresolvedConfig, new string[1] { "requiredTarget1" }, true) });

            // Create the initial build request
            string[] targets = new string[3] { "target1", "target2", "target3" };
            BuildRequest request = CreateNewBuildRequest(1, targets);

            // Kick it off
            VerifyEngineStatus(BuildRequestEngineStatus.Uninitialized);
            _engine.InitializeForBuild(new NodeLoggingContext(_host.LoggingService, 0, false));
            _engine.SubmitBuildRequest(request);
            Thread.Sleep(250);
            VerifyEngineStatus(BuildRequestEngineStatus.Active);

            // Wait for the request to generate the child request with the unresolved configuration
            WaitForEvent(_newConfigurationEvent, "NewConfigurationEvent");
            Assert.Equal(Path.GetFullPath("OtherFile"), _newConfiguration_Config.ProjectFullPath);
            Assert.Equal("TestToolsVersion", _newConfiguration_Config.ToolsVersion);
            Assert.True(_newConfiguration_Config.WasGeneratedByNode);
            Thread.Sleep(250);
            VerifyEngineStatus(BuildRequestEngineStatus.Waiting);

            // Resolve the configuration
            BuildRequestConfigurationResponse response = new BuildRequestConfigurationResponse(_newConfiguration_Config.ConfigurationId, 2, 0);
            _engine.ReportConfigurationResponse(response);

            // Now wait for the actual requests to be issued.
            WaitForEvent(_newRequestEvent, "NewRequestEvent");
            Assert.Equal(2, _newRequest_Request.BuildRequests[0].ConfigurationId);
            Assert.Equal(2, _newRequest_Request.BuildRequests[0].ConfigurationId);
            Assert.Equal(1, _newRequest_Request.BuildRequests[0].Targets.Count);
            Assert.Equal("requiredTarget1", _newRequest_Request.BuildRequests[0].Targets[0]);

            // Report a result to satisfy the build request
            BuildResult result = new BuildResult(_newRequest_Request.BuildRequests[0]);
            result.AddResultsForTarget("requiredTarget1", TestUtilities.GetEmptySucceedingTargetResult());
            _engine.UnblockBuildRequest(new BuildRequestUnblocker(result));

            // Continue the request
            _engine.UnblockBuildRequest(new BuildRequestUnblocker(request.GlobalRequestId));

            // Wait for the original request to complete
            WaitForEvent(_requestCompleteEvent, "RequestComplete");
            Assert.Equal(request, _requestComplete_Request);
            Assert.Equal(BuildResultCode.Success, _requestComplete_Result.OverallResult);
            Thread.Sleep(250);
            VerifyEngineStatus(BuildRequestEngineStatus.Idle);
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:57,代码来源:BuildRequestEngine_Tests.cs

示例8: TestMixedWaitingRequests

        public void TestMixedWaitingRequests()
        {
            BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" });
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary<string, string>(), "foo", new string[0], null), "2.0");
            BuildRequestEntry entry = new BuildRequestEntry(request, config);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Ready);

            entry.Continue();
            Assert.AreEqual(entry.State, BuildRequestEntryState.Active);

            BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" });
            entry.WaitForResult(waitingRequest1);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);

            BuildRequest waitingRequest2 = CreateNewBuildRequest(-1, new string[1] { "xor" });
            entry.WaitForResult(waitingRequest2);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);

            Assert.IsNull(entry.GetRequestsToIssueIfReady(), "Entry should not be ready to issue because there are unresolved configurations");

            entry.ResolveConfigurationRequest(-1, 3);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);

            BuildResult requiredResult1 = new BuildResult(waitingRequest1);
            requiredResult1.AddResultsForTarget("bar", TestUtilities.GetEmptySucceedingTargetResult());
            entry.ReportResult(requiredResult1);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);

            BuildResult requiredResult2 = new BuildResult(waitingRequest2);
            requiredResult2.AddResultsForTarget("xor", TestUtilities.GetEmptySucceedingTargetResult());
            entry.ReportResult(requiredResult2);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Ready);
        }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:33,代码来源:BuildRequestEntry_Tests.cs

示例9: TestResultsWithNoMatch1

        public void TestResultsWithNoMatch1()
        {
            BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" });
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary<string, string>(), "foo", new string[0], null), "2.0");
            BuildRequestEntry entry = new BuildRequestEntry(request, config);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Ready);

            entry.Continue();
            Assert.AreEqual(entry.State, BuildRequestEntryState.Active);

            BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" });
            entry.WaitForResult(waitingRequest1);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);

            BuildRequest randomRequest = CreateNewBuildRequest(3, new string[0]);
            BuildResult requiredResult = new BuildResult(randomRequest);
            requiredResult.AddResultsForTarget("bar", TestUtilities.GetEmptySucceedingTargetResult());
            entry.ReportResult(requiredResult);
            Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting);
        }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:20,代码来源:BuildRequestEntry_Tests.cs

示例10: TestRequestWithReferenceCancelled

        public void TestRequestWithReferenceCancelled()
        {
            BuildRequestConfiguration configuration = CreateTestProject(1);
            try
            {
                TestTargetBuilder targetBuilder = (TestTargetBuilder)_host.GetComponent(BuildComponentType.TargetBuilder);
                IConfigCache configCache = (IConfigCache)_host.GetComponent(BuildComponentType.ConfigCache);
                FullyQualifiedBuildRequest[] newRequest = new FullyQualifiedBuildRequest[1] { new FullyQualifiedBuildRequest(configuration, new string[1] { "testTarget2" }, true) };
                targetBuilder.SetNewBuildRequests(newRequest);
                configCache.AddConfiguration(configuration);

                BuildRequest request = CreateNewBuildRequest(1, new string[1] { "target1" });
                BuildRequestEntry entry = new BuildRequestEntry(request, configuration);
                BuildResult result = new BuildResult(request);
                result.AddResultsForTarget("target1", GetEmptySuccessfulTargetResult());
                targetBuilder.SetResultsToReturn(result);

                _requestBuilder.BuildRequest(GetNodeLoggingContext(), entry);
                WaitForEvent(_newBuildRequestsEvent, "New Build Requests");
                Assert.Equal(_newBuildRequests_Entry, entry);
                ObjectModelHelpers.AssertArrayContentsMatch(_newBuildRequests_FQRequests, newRequest);

                BuildResult newResult = new BuildResult(_newBuildRequests_BuildRequests[0]);
                newResult.AddResultsForTarget("testTarget2", GetEmptySuccessfulTargetResult());
                entry.ReportResult(newResult);

                _requestBuilder.ContinueRequest();
                Thread.Sleep(500);
                _requestBuilder.CancelRequest();

                WaitForEvent(_buildRequestCompletedEvent, "Build Request Completed");
                Assert.Equal(BuildRequestEntryState.Complete, entry.State);
                Assert.Equal(entry, _buildRequestCompleted_Entry);
                Assert.Equal(BuildResultCode.Failure, _buildRequestCompleted_Entry.Result.OverallResult);
            }
            finally
            {
                DeleteTestProject(configuration);
            }
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:40,代码来源:RequestBuilder_Tests.cs

示例11: TestBuildWithChildren

        public void TestBuildWithChildren()
        {
            BuildRequestData data = new BuildRequestData("TestFile", new Dictionary<string, string>(), "TestToolsVersion", new string[0], null);
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, "2.0");
            _cache.AddConfiguration(config);

            // Configure the builder to spawn build requests
            MockRequestBuilder builder = (MockRequestBuilder)_host.GetComponent(BuildComponentType.RequestBuilder);
            builder.NewRequests.Add(new FullyQualifiedBuildRequest[1] { new FullyQualifiedBuildRequest(config, new string[1] { "requiredTarget1" }, true) });

            // Create the initial build request
            string[] targets = new string[3] { "target1", "target2", "target3" };
            BuildRequest request = CreateNewBuildRequest(1, targets);

            // Kick it off
            VerifyEngineStatus(BuildRequestEngineStatus.Uninitialized);
            _engine.InitializeForBuild(new NodeLoggingContext(_host.LoggingService, 0, false));
            _engine.SubmitBuildRequest(request);
            Thread.Sleep(250);
            VerifyEngineStatus(BuildRequestEngineStatus.Active);

            // Wait for the new requests to be spawned by the builder
            WaitForEvent(_newRequestEvent, "NewRequestEvent");
            Assert.Equal(1, _newRequest_Request.BuildRequests[0].ConfigurationId);
            Assert.Equal(1, _newRequest_Request.BuildRequests[0].Targets.Count);
            Assert.Equal("requiredTarget1", _newRequest_Request.BuildRequests[0].Targets[0]);

            // Wait for a moment, because the build request engine thread may not have gotten around
            // to going to the waiting state.
            Thread.Sleep(250);
            VerifyEngineStatus(BuildRequestEngineStatus.Waiting);

            // Report a result to satisfy the build request
            BuildResult result = new BuildResult(_newRequest_Request.BuildRequests[0]);
            result.AddResultsForTarget("requiredTarget1", TestUtilities.GetEmptySucceedingTargetResult());
            _engine.UnblockBuildRequest(new BuildRequestUnblocker(result));

            // Continue the request.
            _engine.UnblockBuildRequest(new BuildRequestUnblocker(request.GlobalRequestId));

            // Wait for the original request to complete
            WaitForEvent(_requestCompleteEvent, "RequestComplete");
            Assert.Equal(request, _requestComplete_Request);
            Assert.Equal(BuildResultCode.Success, _requestComplete_Result.OverallResult);

            VerifyEngineStatus(BuildRequestEngineStatus.Idle);
        }
开发者ID:cameron314,项目名称:msbuild,代码行数:47,代码来源:BuildRequestEngine_Tests.cs

示例12: TestMergeResultsBad3

        public void TestMergeResultsBad3()
        {
            BuildRequest request = CreateNewBuildRequest(1, new string[0]);
            BuildResult result = new BuildResult(request);
            result.AddResultsForTarget("foo", TestUtilities.GetEmptySucceedingTargetResult());

            BuildRequest request2 = CreateNewBuildRequest(2, new string[0]);
            BuildResult result2 = new BuildResult(request2);
            result2.AddResultsForTarget("bar", TestUtilities.GetEmptySucceedingTargetResult());

            result.MergeResults(result2);
        }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:12,代码来源:BuildResult_Tests.cs

示例13: TestHasResultsForTarget

        public void TestHasResultsForTarget()
        {
            BuildRequest request = CreateNewBuildRequest(1, new string[0]);
            BuildResult result = new BuildResult(request);
            result.AddResultsForTarget("foo", TestUtilities.GetEmptySucceedingTargetResult());

            Assert.IsTrue(result.HasResultsForTarget("foo"));
            Assert.IsFalse(result.HasResultsForTarget("bar"));
        }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:9,代码来源:BuildResult_Tests.cs

示例14: TestAddResultsInvalid3

 public void TestAddResultsInvalid3()
 {
     BuildRequest request = CreateNewBuildRequest(1, new string[0]);
     BuildResult result = new BuildResult(request);
     result.AddResultsForTarget(null, TestUtilities.GetEmptySucceedingTargetResult());
 }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:6,代码来源:BuildResult_Tests.cs

示例15: TestMergeResults

        public void TestMergeResults()
        {
            BuildRequest request = CreateNewBuildRequest(1, new string[0]);
            BuildResult result = new BuildResult(request);
            result.AddResultsForTarget("foo", TestUtilities.GetEmptySucceedingTargetResult());

            BuildResult result2 = new BuildResult(request);
            result.AddResultsForTarget("bar", TestUtilities.GetEmptyFailingTargetResult());

            result.MergeResults(result2);
            Assert.AreEqual(TargetResultCode.Success, result["foo"].ResultCode);
            Assert.AreEqual(TargetResultCode.Failure, result["bar"].ResultCode);

            BuildResult result3 = new BuildResult(request);
            result.MergeResults(result3);

            BuildResult result4 = new BuildResult(request);
            result4.AddResultsForTarget("xor", TestUtilities.GetEmptySucceedingTargetResult());
            result.MergeResults(result4);
            Assert.AreEqual(TargetResultCode.Success, result["foo"].ResultCode);
            Assert.AreEqual(TargetResultCode.Failure, result["bar"].ResultCode);
            Assert.AreEqual(TargetResultCode.Success, result["xor"].ResultCode);
        }
开发者ID:JamesLinus,项目名称:msbuild,代码行数:23,代码来源:BuildResult_Tests.cs


注:本文中的Microsoft.Build.Execution.BuildResult.AddResultsForTarget方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。