添加项目

master
bicijinlian 4 years ago
parent e3e23d3117
commit 6c6e4acf33

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="MySQLConnectString" connectionString="server=127.0.0.1;port=3306;user=root;password=yt-461400;database=wi_cloud;Sslmode=None;Character Set=utf8;" />
</connectionStrings>
<appSettings>
<!--建筑编码-->
<add key="BuildingCode" value="jiedaobianma###############*x1234"/>
<!--传输加密公钥-->
<add key="PublicKey" value="AAAAB3NzaC1yc2EAAAADAQABAAACAQCxcQJ6eC/oZX+biQYn3grMgZlxXmCjnJvPao7rUxTK2Nk/zNjWTB28kjI55cyjKp5GjP3O6wwjzNyMSXaMXFH5KThqcX1wyC8ZOw+y+uwBKsYphu5qdElaFUWi+LCmo+Tj7Tk12DvW+5u20/Q8Ky24XwJ2TXv1ll1oqvKwhRci76b3yrhB8/wCaWPGi9FZQcL5ZbJIradHCmEujtxLNtdo8uaPiwfqW53O8aBpY9fsUJTiR+YfwG1NNh48aiMBrqnInU8VC+xJ2tAsvxCi3yP42GQbE2GC9sADChTq/zNJtA/TlC3Sjezp9+Anqfx4T//kUnzIyqXQ3PbA8iIwrd5qOugwxklW5pvnDOO0FNAlnRuD5ooJHQlZM9c2vMGbh4EXIOpO7TJL9zqAQ8M4a8kBELKjEDKyMgOdmSGhLt91z5irdJ9WBGr97QgoQaTf5r1GnoN5xjgkuiM3vbYHLLXnGJGGcXicQ21bIZTIp8g33WXP/QhNDiNcVncvzNwpHW9VKQqhXtVgmpl+ykBqH5tH40aMnzpa5Q2bamkGzIoLC376/+Vqn9NhfSChhmXMiJetbf4DqqXqCsBo3+NfCNvSDcCK2x3HsqsimiQL+GEO9DiS+Qg29+AzQn+qBp+CN+7oMKR75sQHGtgrEjqvh37zJ7Cj91EL+3aQrQY6gJ9OSQ=="/>
<!--定时器Cron表达式-->
<add key="Cron" value="0/10 * * * * ?"/>
</appSettings>
</configuration>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,42 @@
using System;
using Topshelf;
using System.Security.Cryptography.X509Certificates;
namespace TopshelfStudy.NetCoreDemo
{
class Program
{
static void Main(string[] args)
{
var topshelfExitCode = HostFactory.Run(config =>
{
//使用NLog日志
config.UseNLog(NLog.LogManager.LogFactory);
//服务配置
config.Service<TopshelfService>(s =>
{
s.ConstructUsing(name => new TopshelfService());
s.WhenStarted(tc => tc.Start());
s.WhenStopped(tc => tc.Stop());
});
//运行服务帐户
config.RunAsLocalSystem();
//服务名(所有服务中唯一)
config.SetServiceName("AIoT.Service.Demo");
//服务显示名
config.SetDisplayName("AIoT服务测试");
//服务描述
config.SetDescription("这是一个AIoT服务测试例子使用Topshelf类库方便调试");
});
//退出码
Environment.ExitCode = (int)Convert.ChangeType(topshelfExitCode, topshelfExitCode.GetTypeCode());
}
}
}

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Quartz;
using Quartz.Listener;
namespace TopshelfStudy.NetCoreDemo
{
/// <summary>
/// Quartz作业监听器
/// </summary>
public class CustomJobListener : IJobListener
{
public readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public virtual string Name => nameof(CustomJobListener);
public CustomJobListener()
{
}
/// <summary>
/// 执行前
/// </summary>
public Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
logger.Info("作业,执行前!");
return Task.CompletedTask;
}
/// <summary>
/// 执行后
/// </summary>
public Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
{
logger.Info($"作业{context.JobDetail.Key.Name},执行后!");
return Task.CompletedTask;
}
/// <summary>
/// 被否决执行
/// </summary>
public Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
logger.Info("作业,被否决执行!");
return Task.CompletedTask;
}
}
}

@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using Quartz;
using Quartz.Core;
using Quartz.Listener;
using Quartz.Impl;
using Quartz.Impl.Matchers;
namespace TopshelfStudy.NetCoreDemo
{
/// <summary>
/// Quarzt调度监听器
/// </summary>
public class CustomSchedulerListener : ISchedulerListener
{
private IScheduler _scheduler;
public CustomSchedulerListener(IScheduler scheduler)
{
_scheduler = scheduler;
}
public Task JobAdded(IJobDetail jobDetail, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{jobDetail.Key} 作业:被添加,成功启用");
return Task.CompletedTask;
}
/// <summary>
/// 作业被删除
/// 删除前一次,删除后一次
/// </summary>
public Task JobDeleted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
if (_scheduler.CheckExists(jobKey).Result)
{
Console.WriteLine($"{jobKey} 作业:即将删除");
}
else
{
Console.WriteLine($"{jobKey} 作业:完成删除");
}
return Task.CompletedTask;
}
/// <summary>
/// 作业被中断
/// </summary>
public Task JobInterrupted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{jobKey} 作业:被中断");
return Task.CompletedTask;
}
/// <summary>
/// 作业被暂停
/// </summary>
public Task JobPaused(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{jobKey} 作业:被暂停");
return Task.CompletedTask;
}
/// <summary>
/// 作业被继续(取消暂停)
/// </summary>
public Task JobResumed(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{jobKey} 作业:被继续");
return Task.CompletedTask;
}
/// <summary>
/// 作业被添加到Scheduler
/// </summary>
public Task JobScheduled(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{trigger.Key} 触发器:添加到 调度器");
return Task.CompletedTask;
}
/// <summary>
/// 当一组Quartz.IJobDetails被暂停时由Quartz.IScheduler调用。
/// 如果所有组都已暂停则jobName参数将为空。
/// 如果所有作业都已暂停,则两个参数都将为空。
/// </summary>
/// <param name="jobGroup"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task JobsPaused(string jobGroup, CancellationToken cancellationToken = default(CancellationToken))
{
var jobKeys = _scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(jobGroup)).Result;
foreach (var jobKey in jobKeys)
{
}
Console.WriteLine($"{jobGroup} 作业组:被暂停");
return Task.CompletedTask;
}
public Task JobsResumed(string jobGroup, CancellationToken cancellationToken = default(CancellationToken))
{
var jobKeys = _scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(jobGroup)).Result;
Console.WriteLine($"{jobGroup} 作业组:被继续");
return Task.CompletedTask;
}
/// <summary>
/// 作业从Scheduler中删除
/// </summary>
public Task JobUnscheduled(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{triggerKey.Name} 触发器:Unscheduled");
return Task.CompletedTask;
}
public Task SchedulerError(string msg, SchedulerException cause, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"Scheduler出现错误:{msg}");
return Task.CompletedTask;
}
public Task SchedulerInStandbyMode(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
public Task SchedulerShutdown(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
public Task SchedulerShuttingdown(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
public Task SchedulerStarted(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
public Task SchedulerStarting(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
public Task SchedulingDataCleared(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
public Task TriggerFinalized(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{trigger.Key.Name}:TriggerFinalized");
return Task.CompletedTask;
}
public Task TriggerPaused(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{triggerKey.Name}:TriggerPaused");
return Task.CompletedTask;
}
public Task TriggerResumed(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{triggerKey.Name}:TriggerResumed");
return Task.CompletedTask;
}
public Task TriggersPaused(string triggerGroup, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{triggerGroup}:TriggersPaused");
return Task.CompletedTask;
}
public Task TriggersResumed(string triggerGroup, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine($"{triggerGroup}:TriggersResumed");
return Task.CompletedTask;
}
}
}

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Quartz;
using Quartz.Core;
using Quartz.Impl;
using Quartz.Listener;
namespace TopshelfStudy.NetCoreDemo
{
/// <summary>
/// Quarzt触发监听器
/// </summary>
public class CustomTriggerListener : ITriggerListener
{
public string Name { get; } = nameof(CustomTriggerListener);
public CustomTriggerListener()
{
}
/// <summary>
/// 在Quartz.ITrigger触发时由Quartz.IScheduler调用
/// 它的关联Quartz.IJobDetail已执行
/// 它的Quartz.Spi.IOperableTrigger.triggedQuartz.ICalendar方法已调用
/// </summary>
public Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine("触发器执行后");
return Task.CompletedTask;
}
/// <summary>
/// 触发器启动时执行
/// 当Quartz.ITrigger启动时由Quartz.IScheduler调用它的关联Quartz.IJobDetail即将执行。
/// 它在VetoJobExecution()方法之前调用
/// </summary>
public Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine("触发器执行前");
return Task.CompletedTask;
}
/// <summary>
/// 错过触发时调用
/// 当Quartz.ITrigger错过触发时(线程池不够且等待超时)调用时由Quartz.IScheduler调用。
/// 应该考虑这个方法花费了多少时间,因为将影响所有错过触发的触发器。
/// 如果你有很多的触发器错过触发,这可能是这个方法做了很多事情。
/// </summary>
public Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine("错过触发时间,本次任务丢失.");
return Task.CompletedTask;
}
/// <summary>
/// 在Quartz.ITrigger触发时由Quartz.IScheduler调用
/// 它的关联Quartz.IJobDetail已执行它的Quartz.Spi.IOperableTrigger.triggedQuartz.ICalendar方法已调用
/// </summary>
/// <returns>
/// true表示否决Job继续执行,false同意继续执行
/// </returns>
public Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
Console.WriteLine("触发器审核通过,继续执行.");
return Task.FromResult(false);
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Quartz;
using Quartz.Core;
namespace TopshelfStudy.NetCoreDemo
{
public class JobDemo : IJob
{
public async Task Execute(IJobExecutionContext context)
{
//模拟业务操作
string jobName = "测试作业";
Console.WriteLine($"{jobName} 开始执行");
Console.WriteLine($"{jobName} 执行中...");
await Task.Delay(0*1000);
Console.WriteLine($"{jobName} 执行完毕.");
}
}
}

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Core;
using Quartz.Impl;
namespace TopshelfStudy.NetCoreDemo
{
public static class QuartzNetExtensions
{
public static IServiceCollection AddCustomQuartz(this IServiceCollection services)
{
var config = services.BuildServiceProvider().GetRequiredService<Microsoft.Extensions.Configuration.IConfiguration>();
//配置
var option = new NameValueCollection
{
//实例名
["quartz.scheduler.instanceName"] = "MissionQuartzScheduler",
//线程数
["quartz.threadPool.threadCount"] = "10",
//线程超时
["quartz.jobStore.misfireThreshold"] = "60000",
//Job数据可以使用序列化数据而非只能使用字符串
["quartz.serializer.type"] = "json",
//配置以使用作业StoreTx
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
//将 AdoJobStore 配置为使用驱动程序委托
["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz",
//使用表前缀配置 AdoJobStore
["quartz.jobStore.tablePrefix"] = "QRTZ_",
//使用“要使用的数据源名称”配置 AdoJobStore
["quartz.jobStore.dataSource"] = "quarztDS",
//设置数据源的连接字符串
["quartz.dataSource.quarztDS.connectionString"] = config.GetConnectionString("SolutionConnection"),
//设置数据库提供程序
["quartz.dataSource.quarztDS.provider"] = "MySql",
//将 AdoJobStore 配置为将字符串用作作业数据映射值(建议)
["quartz.jobStore.useProperties"] = "false",
// 负载均衡
["quartz.jobStore.clustered"] = "true",
["quartz.scheduler.instanceId"] = "AUTO",
};
//使用quartz.config配置文件
var factory = new StdSchedulerFactory();
//或者:使用程序配置项
//var factory = new StdSchedulerFactory(option);
var scheduler = factory.GetScheduler().Result;
services.AddSingleton<ISchedulerFactory>(factory);
services.AddSingleton<IScheduler>(scheduler);
services.AddSingleton<CustomSchedulerListener>();
services.AddSingleton<CustomJobListener>();
services.AddSingleton<CustomTriggerListener>();
return services;
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
namespace TopshelfStudy.NetCoreDemo
{
public static class QuartzNetHelper
{
/// <summary>
/// 是否是有效的 cron 字符串
/// </summary>
public static bool IsValidExpression(string cron)
{
return CronExpression.IsValidExpression(cron);
}
}
}

@ -0,0 +1,4 @@
EF Core 模型生成器
Scaffold-DbContext -Connection "server=47.102.46.73;port=3306;user=root;password=213464;database=wi_cloud" -Provider "MySql.Data.EntityFrameworkCore" -Context "CloudContext" -OutputDir "Models" -force
Scaffold-DbContext -Connection "server=47.103.96.35;port=3306;user=root;password=213464;database=wi_cloud" -Provider "MySql.Data.EntityFrameworkCore" -Context "CloudContext" -OutputDir "Models" -force

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Matchers;
namespace TopshelfStudy.NetCoreDemo
{
public class TopshelfService
{
public readonly IScheduler Scheduler = new StdSchedulerFactory().GetScheduler().Result;
public readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public void Start()
{
logger.Info("服务启动");
//注册监听器
Scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener(Scheduler));
Scheduler.ListenerManager.AddJobListener(new CustomJobListener(), GroupMatcher<JobKey>.AnyGroup());
Scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());
//添加作业
JobKey jobKey = new JobKey("demo_job", "demo_job_group");
TriggerKey triggerKey = new TriggerKey("demo_trigger", "demo_trigger_group");
JobDataMap dataMape = new JobDataMap();
IJobDetail jobDetail = JobBuilder.Create<JobDemo>()
.SetJobData(dataMape)
.WithIdentity(jobKey)
.Build();
//触发器
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey)
.StartNow()
.WithCronSchedule("0/10 * * * * ? ")
.Build();
//添加到调度器
Scheduler.ScheduleJob(jobDetail, trigger);
//启动Scheduler
Scheduler.Start();
}
public void Stop()
{
if (Scheduler != null && !Scheduler.IsShutdown)
{
Scheduler.Shutdown();
}
logger.Info("Quarzt.Net 后台服务已关闭");
logger.Info("Windows 服务停止");
}
}
}

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" />
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" PrivateAssets="all" />
<PackageReference Include="NLog" Version="4.7.2" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.3" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="Topshelf" Version="4.2.1" />
<PackageReference Include="Topshelf.NLog" Version="4.2.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="Extensions\" />
<Folder Include="Models\" />
</ItemGroup>
<ItemGroup>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TopshelfStudy.NetCoreDemo
{
public static class RuntimeUtil
{
/// <summary>
/// 是否运行在Debug模式
/// </summary>
public static bool IsDebug
{
get
{
#pragma warning disable
#if DEBUG
return true;
#endif
return false;
#pragma warning restore
}
}
}
}

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
keepVariablesOnReload="true"
throwExceptions="false"
throwConfigExceptions="true"
internalLogToConsoleError="true"
internalLogLevel="Warn"
internalLogFile="${basedir}\Logs\internal-nlog.txt">
<!-- enable asp.net core layout renderers -->
<extensions>
</extensions>
<!-- the targets to write to -->
<targets>
<!--设置缓存日志-->
<!--
<default-wrapper xsi:type="BufferingWrapper" bufferSize="10"/>
-->
<!-- 所有日志 Target -->
<target xsi:type="File"
name="allfile"
fileName="${basedir}\Logs\nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
<!-- 控制台 Target -->
<target xsi:type="ColoredConsole"
name="ColoredConsoleTarget"
layout="${longdate} ${uppercase:${level}} ${message} ${exception:format=tostring}" />
<!-- Quartz.Net Target -->
<target xsi:type="File"
name="QuartzNetTarget"
fileName="${basedir}\Logs\nlog-quartz-${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message} ${exception:format=tostring}" />
</targets>
<!-- 规则到目标映射 -->
<rules>
<!--所有日志包括Microsoft框架-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<!--跳过非关键的Microsoft日志因此只记录Microsoft日志-->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<!--所有日志,控制台-->
<logger name="*" minlevel="Info" writeTo="ColoredConsoleTarget" />
<!-- Quartzj日志 -->
<logger name="Quartz.*" minlevel="Info" writeTo="QuartzNetTarget" />
</rules>
</nlog>

@ -0,0 +1,34 @@
quartz.scheduler.instanceName = DemoScheduler
quartz.threadPool.threadCount = 10
quartz.jobStore.misfireThreshold = 60000
quartz.serializer.type = json
# 数据库配置
# 配置以使用作业StoreTx
# quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz
# 将 AdoJobStore 配置为使用驱动程序委托
# quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz
# 使用表前缀配置 AdoJobStore
# quartz.jobStore.tablePrefix = QRTZ_
# 使用“要使用的数据源名称”配置 AdoJobStore
# quartz.jobStore.dataSource = myDS
# 设置数据源的连接字符串
# quartz.dataSource.myDS.connectionString = server=127.0.0.1;port=3306;user=root;password=yt-461400;database=wi_solution;Sslmode=None;Character Set=utf8;
# 设置数据库提供程序
# quartz.dataSource.myDS.provider = MySql
# 将 AdoJobStore 配置为将字符串用作作业数据映射值(建议)
# quartz.jobStore.useProperties = false
# 负载均衡
quartz.jobStore.clustered = false
quartz.scheduler.instanceId = AUTO

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30104.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TopshelfStudy.NetCoreDemo", "TopshelfStudy.NetCoreDemo\TopshelfStudy.NetCoreDemo.csproj", "{CDBC7EDE-2C69-4DC4-8D7E-E5540F2689F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CDBC7EDE-2C69-4DC4-8D7E-E5540F2689F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDBC7EDE-2C69-4DC4-8D7E-E5540F2689F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CDBC7EDE-2C69-4DC4-8D7E-E5540F2689F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDBC7EDE-2C69-4DC4-8D7E-E5540F2689F8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9AEE3FEB-F60C-4A22-9692-49B04B1F0DA5}
EndGlobalSection
EndGlobal
Loading…
Cancel
Save