Compare commits

...

8 Commits
2.47 ... 2.49

Author SHA1 Message Date
2dust
70dadf9964 up routing 2019-11-08 17:30:48 +08:00
2dust
9eab95e870 up test 2019-11-02 11:07:31 +08:00
2dust
f199e3bf82 Update AssemblyInfo.cs 2019-10-30 14:20:12 +08:00
2dust
7d31c2e472 up addr 2019-10-30 14:07:26 +08:00
2dust
ad406c3682 Update SpeedtestHandler.cs 2019-10-28 13:11:14 +08:00
2dust
2779670fa2 up speedtest 2019-10-27 12:55:20 +08:00
2dust
5b00bf82fb Update MainForm.cs 2019-10-24 08:42:55 +08:00
2dust
473e0cf839 Update HttpWebServerB.cs 2019-10-24 08:23:32 +08:00
16 changed files with 313 additions and 83 deletions

View File

@@ -41,6 +41,7 @@ namespace v2rayN.Base
{
if (!listener.Pending())
{
Thread.Sleep(100);
continue;
}

View File

@@ -35,6 +35,7 @@ namespace v2rayN.Forms
Utils.ClearTempPath();
v2rayHandler.V2rayStop();
HttpProxyHandle.Update(config, true);
HttpProxyHandle.CloseHttpAgent(config);
PACServerHandle.Stop();
@@ -88,7 +89,7 @@ namespace v2rayN.Forms
e.Cancel = true;
HideForm();
return;
}
}
}
private void MainForm_Resize(object sender, EventArgs e)
@@ -108,24 +109,24 @@ namespace v2rayN.Forms
//config.uiItem.mainQRCodeWidth = splitContainer1.SplitterDistance;
}
private const int WM_QUERYENDSESSION = 0x0011;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_QUERYENDSESSION:
Utils.SaveLog("Windows shutdown UnsetProxy");
ConfigHandler.ToJsonFile(config);
statistics?.SaveToFile();
ProxySetting.UnsetProxy();
m.Result = (IntPtr)1;
break;
default:
base.WndProc(ref m);
break;
}
}
//private const int WM_QUERYENDSESSION = 0x0011;
//protected override void WndProc(ref Message m)
//{
// switch (m.Msg)
// {
// case WM_QUERYENDSESSION:
// Utils.SaveLog("Windows shutdown UnsetProxy");
// ConfigHandler.ToJsonFile(config);
// statistics?.SaveToFile();
// ProxySetting.UnsetProxy();
// m.Result = (IntPtr)1;
// break;
// default:
// base.WndProc(ref m);
// break;
// }
//}
#endregion
#region listview menu
@@ -404,7 +405,7 @@ namespace v2rayN.Forms
}
v2rayHandler.LoadV2ray(config);
Global.reloadV2ray = false;
ConfigHandler.ToJsonFile(config);
ConfigHandler.SaveConfig(ref config, false);
ChangeSysAgent(config.sysAgentEnabled);
DisplayToolStatus();
@@ -415,7 +416,7 @@ namespace v2rayN.Forms
/// </summary>
private void CloseV2ray()
{
ConfigHandler.ToJsonFile(config);
ConfigHandler.SaveConfig(ref config, false);
ChangeSysAgent(false);
@@ -592,44 +593,43 @@ namespace v2rayN.Forms
private void menuPingServer_Click(object sender, EventArgs e)
{
GetLvSelectedIndex();
ClearTestResult();
var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "ping", UpdateSpeedtestHandler);
Speedtest("ping");
}
private void menuTcpingServer_Click(object sender, EventArgs e)
{
GetLvSelectedIndex();
ClearTestResult();
var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "tcping", UpdateSpeedtestHandler);
Speedtest("tcping");
}
private void menuRealPingServer_Click(object sender, EventArgs e)
{
if (!config.sysAgentEnabled)
{
UI.Show(UIRes.I18N("NeedHttpGlobalProxy"));
return;
}
//if (!config.sysAgentEnabled)
//{
// UI.Show(UIRes.I18N("NeedHttpGlobalProxy"));
// return;
//}
UI.Show(UIRes.I18N("SpeedServerTips"));
//UI.Show(UIRes.I18N("SpeedServerTips"));
GetLvSelectedIndex();
ClearTestResult();
var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "realping", UpdateSpeedtestHandler);
Speedtest("realping");
}
private void menuSpeedServer_Click(object sender, EventArgs e)
{
if (!config.sysAgentEnabled)
{
UI.Show(UIRes.I18N("NeedHttpGlobalProxy"));
return;
}
//if (!config.sysAgentEnabled)
//{
// UI.Show(UIRes.I18N("NeedHttpGlobalProxy"));
// return;
//}
UI.Show(UIRes.I18N("SpeedServerTips"));
//UI.Show(UIRes.I18N("SpeedServerTips"));
Speedtest("speedtest");
}
private void Speedtest(string actionType)
{
GetLvSelectedIndex();
var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "speedtest", UpdateSpeedtestHandler);
ClearTestResult();
var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, actionType, UpdateSpeedtestHandler);
}
private void menuExport2ClientConfig_Click(object sender, EventArgs e)
@@ -1004,11 +1004,11 @@ namespace v2rayN.Forms
}
private void menuExit_Click(object sender, EventArgs e)
{
{
this.Visible = false;
this.Close();
this.Close();
Application.Exit();
}
@@ -1234,6 +1234,7 @@ namespace v2rayN.Forms
break;
}
}
ConfigHandler.SaveConfig(ref config, false);
DisplayToolStatus();
}
@@ -1399,7 +1400,7 @@ namespace v2rayN.Forms
private void tsbPromotion_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start(Global.PromotionUrl);
System.Diagnostics.Process.Start($"{Global.PromotionUrl}?t={DateTime.Now.Ticks}");
}
#endregion

View File

@@ -44,7 +44,7 @@ namespace v2rayN.Forms
chkudpEnabled.Checked = config.inbound[0].udpEnabled;
chksniffingEnabled.Checked = config.inbound[0].sniffingEnabled;
txtlocalPort2.Text = "socks + 1";
txtlocalPort2.Text = $"{config.inbound[0].localPort + 1}";
cmbprotocol2.Text = Global.InboundHttp;
if (config.inbound.Count > 1)
@@ -127,7 +127,7 @@ namespace v2rayN.Forms
cbFreshrate.DisplayMember = "Text";
cbFreshrate.ValueMember = "ID";
switch(config.statisticsFreshRate)
switch (config.statisticsFreshRate)
{
case (int)Global.StatisticsFreshRate.quick:
cbFreshrate.SelectedItem = cbSource[0];
@@ -369,10 +369,14 @@ namespace v2rayN.Forms
private void btnSetDefRountingRule_Click(object sender, EventArgs e)
{
txtUseragent.Text = Utils.GetEmbedText(Global.CustomRoutingFileName + Global.agentTag);
txtUserdirect.Text = Utils.GetEmbedText(Global.CustomRoutingFileName + Global.directTag);
txtUserblock.Text = Utils.GetEmbedText(Global.CustomRoutingFileName + Global.blockTag);
var lstUrl = new List<string>();
lstUrl.Add(Global.CustomRoutingListUrl + "proxy");
lstUrl.Add(Global.CustomRoutingListUrl + "direct");
lstUrl.Add(Global.CustomRoutingListUrl + "block");
lstUrl.Add(Global.CustomRoutingListUrl + Global.agentTag);
lstUrl.Add(Global.CustomRoutingListUrl + Global.directTag);
lstUrl.Add(Global.CustomRoutingListUrl + Global.blockTag);
var lstTxt = new List<TextBox>();
lstTxt.Add(txtUseragent);
@@ -415,7 +419,13 @@ namespace v2rayN.Forms
class ComboItem
{
public int ID { get; set; }
public string Text { get; set; }
public int ID
{
get; set;
}
public string Text
{
get; set;
}
}
}

View File

@@ -25,6 +25,8 @@ namespace v2rayN
/// </summary>
public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
public const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";
/// <summary>
/// PromotionUrl
/// </summary>
@@ -61,6 +63,8 @@ namespace v2rayN
/// </summary>
public const string BlankPacFileName = "v2rayN.Sample.BlankPac.txt";
public const string CustomRoutingFileName = "v2rayN.Sample.custom_routing_";
/// <summary>
/// 默认加密方式
@@ -96,7 +100,7 @@ namespace v2rayN
/// 阻止 tag值
/// </summary>
public const string blockTag = "block";
/// <summary>
///
/// </summary>
@@ -170,32 +174,50 @@ namespace v2rayN
/// <summary>
/// 是否需要重启服务V2ray
/// </summary>
public static bool reloadV2ray { get; set; }
public static bool reloadV2ray
{
get; set;
}
/// <summary>
/// 是否开启全局代理(http)
/// </summary>
public static bool sysAgent { get; set; }
public static bool sysAgent
{
get; set;
}
/// <summary>
/// socks端口
/// </summary>
public static int socksPort { get; set; }
public static int socksPort
{
get; set;
}
/// <summary>
/// http端口
/// </summary>
public static int httpPort { get; set; }
public static int httpPort
{
get; set;
}
/// <summary>
/// PAC端口
/// </summary>
public static int pacPort { get; set; }
public static int pacPort
{
get; set;
}
/// <summary>
///
/// </summary>
public static int statePort { get; set; }
public static int statePort
{
get; set;
}
#endregion

View File

@@ -121,6 +121,10 @@ namespace v2rayN.Handler
//{
// config.pacPort = 8888;
//}
if (Utils.IsNullOrEmpty(config.urlGFWList))
{
config.urlGFWList = Global.GFWLIST_URL;
}
if (config.subItem == null)
{
@@ -303,9 +307,9 @@ namespace v2rayN.Handler
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int SaveConfig(ref Config config)
public static int SaveConfig(ref Config config, bool reload = true)
{
Global.reloadV2ray = true;
Global.reloadV2ray = reload;
ToJsonFile(config);
@@ -316,7 +320,7 @@ namespace v2rayN.Handler
/// 存储文件
/// </summary>
/// <param name="config"></param>
public static void ToJsonFile(Config config)
private static void ToJsonFile(Config config)
{
Utils.ToJsonFile(config, Utils.GetPath(configRes));
}
@@ -515,11 +519,11 @@ namespace v2rayN.Handler
{
string newFileName = string.Empty;
newFileName = string.Format("{0}.json", Utils.GetGUID());
newFileName = Path.Combine(Utils.GetTempPath(), newFileName);
//newFileName = Path.Combine(Utils.GetTempPath(), newFileName);
try
{
File.Copy(fileName, newFileName);
File.Copy(fileName, Path.Combine(Utils.GetTempPath(), newFileName));
}
catch
{
@@ -579,7 +583,7 @@ namespace v2rayN.Handler
vmessItem.address = vmessItem.address.TrimEx();
vmessItem.id = vmessItem.id.TrimEx();
vmessItem.security = vmessItem.security.TrimEx();
if (index >= 0)
{
//修改

View File

@@ -140,6 +140,8 @@ namespace v2rayN.Handler
Global.reloadV2ray = true;
_v2rayHandler.LoadV2ray(_config, _selecteds);
Thread.Sleep(5000);
var httpPort = _config.GetLocalPort("speedtest");
for (int k = 0; k < _selecteds.Count; k++)
{
@@ -191,6 +193,8 @@ namespace v2rayN.Handler
Global.reloadV2ray = true;
_v2rayHandler.LoadV2ray(_config, _selecteds);
Thread.Sleep(5000);
string url = Global.SpeedTestUrl;
testCounter = 0;
if (downloadHandle2 == null)
@@ -238,7 +242,7 @@ namespace v2rayN.Handler
var httpPort = _config.GetLocalPort("speedtest");
index = _selecteds[index];
testCounter++;
var webProxy = new WebProxy(Global.Loopback, httpPort + index);
downloadHandle2.DownloadFileAsync(_config, url, webProxy);
@@ -252,7 +256,7 @@ namespace v2rayN.Handler
try
{
IPHostEntry ipHostInfo = System.Net.Dns.Resolve(url);
IPHostEntry ipHostInfo = System.Net.Dns.GetHostEntry(url);
IPAddress ipAddress = ipHostInfo.AddressList[0];
var timer = new Stopwatch();

View File

@@ -655,7 +655,7 @@ namespace v2rayN.Handler
if (!v2rayConfig.routing.rules.Exists(item => { return item.outboundTag == tag; }))
{
var apiRoutingRule = new Mode.RulesItem();
apiRoutingRule.inboundTag = tag;
apiRoutingRule.inboundTag = new List<string> { tag };
apiRoutingRule.outboundTag = tag;
apiRoutingRule.type = "field";
v2rayConfig.routing.rules.Add(apiRoutingRule);
@@ -688,11 +688,21 @@ namespace v2rayN.Handler
return -1;
}
string addressFileName = config.address();
if (File.Exists(fileName))
{
File.Delete(fileName);
}
string addressFileName = config.address();
if (!File.Exists(addressFileName))
{
addressFileName = Path.Combine(Utils.GetTempPath(), addressFileName);
}
if (!File.Exists(addressFileName))
{
msg = UIRes.I18N("FailedGenDefaultConfiguration");
return -1;
}
File.Copy(addressFileName, fileName);
msg = string.Format(UIRes.I18N("SuccessfulConfiguration"), config.getSummary());
@@ -1430,7 +1440,7 @@ namespace v2rayN.Handler
v2rayConfig.outbounds.Add(v2rayConfigCopy.outbounds[0]);
var rule = new Mode.RulesItem();
rule.inboundTag = inbound.tag;
rule.inboundTag = new List<string> { inbound.tag };
rule.outboundTag = v2rayConfigCopy.outbounds[0].tag;
rule.type = "field";
v2rayConfig.routing.rules.Add(rule);

View File

@@ -29,13 +29,13 @@ namespace v2rayN.HttpProxyHandler
}
}
private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";
private static readonly IEnumerable<char> IgnoredLineBegins = new[] { '!', '[' };
public void UpdatePACFromGFWList(Config config)
{
string url = GFWLIST_URL;
string url = Global.GFWLIST_URL;
if (!Utils.IsNullOrEmpty(config.urlGFWList))
{
url = config.urlGFWList;

View File

@@ -310,7 +310,7 @@ namespace v2rayN.Mode
/// </summary>
public string port { get; set; }
public string inboundTag { get; set; }
public List<string> inboundTag { get; set; }
/// <summary>
///
/// </summary>

View File

@@ -33,4 +33,4 @@ using System.Runtime.InteropServices;
// 方法是按如下所示使用“*”:
//[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyVersion("1.0.0")]
[assembly: AssemblyFileVersion("2.47")]
[assembly: AssemblyFileVersion("2.49")]

View File

@@ -76,7 +76,7 @@
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"inboundTag": "api",
"inboundTag": ["api"],
"outboundTag": "api",
"type": "field"
}

View File

@@ -0,0 +1 @@
geosite:category-ads,

View File

@@ -0,0 +1,132 @@
domain:12306.com,
domain:51ym.me,
domain:52pojie.cn,
domain:8686c.com,
domain:abercrombie.com,
domain:adobesc.com,
domain:air-matters.com,
domain:air-matters.io,
domain:airtable.com,
domain:akadns.net,
domain:apache.org,
domain:api.crisp.chat,
domain:api.termius.com,
domain:appshike.com,
domain:appstore.com,
domain:aweme.snssdk.com,
domain:bababian.com,
domain:battle.net,
domain:beatsbydre.com,
domain:bet365.com,
domain:bilibili.cn,
domain:ccgslb.com,
domain:ccgslb.net,
domain:chunbo.com,
domain:chunboimg.com,
domain:clashroyaleapp.com,
domain:cloudsigma.com,
domain:cloudxns.net,
domain:cmfu.com,
domain:culturedcode.com,
domain:dct-cloud.com,
domain:didialift.com,
domain:douyutv.com,
domain:duokan.com,
domain:dytt8.net,
domain:easou.com,
domain:ecitic.net,
domain:eclipse.org,
domain:eudic.net,
domain:ewqcxz.com,
domain:fir.im,
domain:frdic.com,
domain:fresh-ideas.cc,
domain:godic.net,
domain:goodread.com,
domain:haibian.com,
domain:hdslb.net,
domain:hollisterco.com,
domain:hongxiu.com,
domain:hxcdn.net,
domain:images.unsplash.com,
domain:img4me.com,
domain:ipify.org,
domain:ixdzs.com,
domain:jd.hk,
domain:jianshuapi.com,
domain:jomodns.com,
domain:jsboxbbs.com,
domain:knewone.com,
domain:kuaidi100.com,
domain:lemicp.com,
domain:letvcloud.com,
domain:lizhi.io,
domain:localizecdn.com,
domain:lucifr.com,
domain:luoo.net,
domain:mai.tn,
domain:maven.org,
domain:miwifi.com,
domain:moji.com,
domain:moke.com,
domain:mtalk.google.com,
domain:mxhichina.com,
domain:myqcloud.com,
domain:myunlu.com,
domain:netease.com,
domain:nfoservers.com,
domain:nssurge.com,
domain:nuomi.com,
domain:ourdvs.com,
domain:overcast.fm,
domain:paypal.com,
domain:paypalobjects.com,
domain:pgyer.com,
domain:qdaily.com,
domain:qdmm.com,
domain:qin.io,
domain:qingmang.me,
domain:qingmang.mobi,
domain:qqurl.com,
domain:rarbg.to,
domain:rrmj.tv,
domain:ruguoapp.com,
domain:sm.ms,
domain:snwx.com,
domain:soku.com,
domain:startssl.com,
domain:store.steampowered.com,
domain:symcd.com,
domain:teamviewer.com,
domain:tmzvps.com,
domain:trello.com,
domain:trellocdn.com,
domain:ttmeiju.com,
domain:udache.com,
domain:uxengine.net,
domain:weather.bjango.com,
domain:weather.com,
domain:webqxs.com,
domain:weico.cc,
domain:wenku8.net,
domain:werewolf.53site.com,
domain:windowsupdate.com,
domain:wkcdn.com,
domain:workflowy.com,
domain:xdrig.com,
domain:xiaojukeji.com,
domain:xiaomi.net,
domain:xiaomicp.com,
domain:ximalaya.com,
domain:xitek.com,
domain:xmcdn.com,
domain:xslb.net,
domain:xteko.com,
domain:yach.me,
domain:yixia.com,
domain:yunjiasu-cdn.net,
domain:zealer.com,
domain:zgslb.net,
domain:zimuzu.tv,
domain:zmz002.com,
domain:samsungdm.com,

View File

@@ -0,0 +1,33 @@
geosite:google,
geosite:github,
geosite:netflix,
geosite:steam,
geosite:telegram,
geosite:tumblr,
geosite:speedtest,
geosite:bbc,
domain:gvt1.com,
domain:textnow.com,
domain:twitch.tv,
domain:wikileaks.org,
domain:naver.com,
91.108.4.0/22,
91.108.8.0/22,
91.108.12.0/22,
91.108.20.0/22,
91.108.36.0/23,
91.108.38.0/23,
91.108.56.0/22,
149.154.160.0/20,
149.154.164.0/22,
149.154.172.0/22,
74.125.0.0/16,
173.194.0.0/16,
172.217.0.0/16,
216.58.200.0/24,
216.58.220.0/24,
91.108.56.116,
91.108.56.0/24,
109.239.140.0/24,
149.154.167.0/24,
149.154.175.0/24,

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Grpc.Tools" version="2.23.0" targetFramework="net46" developmentDependency="true" />
<package id="Grpc.Tools" version="2.24.0" targetFramework="net46" developmentDependency="true" />
</packages>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.props')" />
<Import Project="..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -150,6 +150,12 @@
<Compile Include="Forms\MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Forms\RoutingRuleSettingForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\RoutingRuleSettingForm.Designer.cs">
<DependentUpon>RoutingRuleSettingForm.cs</DependentUpon>
</Compile>
<Compile Include="Forms\SubSettingForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -286,6 +292,9 @@
<DependentUpon>QRCodeControl.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\RoutingRuleSettingForm.resx">
<DependentUpon>RoutingRuleSettingForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\SubSettingControl.resx">
<DependentUpon>SubSettingControl.cs</DependentUpon>
</EmbeddedResource>
@@ -340,6 +349,9 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Sample\custom_routing_block" />
<EmbeddedResource Include="Sample\custom_routing_direct" />
<EmbeddedResource Include="Sample\custom_routing_proxy" />
<Protobuf Include="Protos\Statistics.proto" />
<None Include="Resources\abp.js.gz" />
<None Include="Resources\grpc_csharp_ext.x64.dll.gz" />
@@ -434,12 +446,12 @@
<Import Project="..\packages\Grpc.Core.2.23.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.2.23.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.props'))" />
<Error Condition="!Exists('..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.props'))" />
<Error Condition="!Exists('..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.targets'))" />
</Target>
<Import Project="..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.targets" Condition="Exists('..\packages\Grpc.Tools.2.23.0\build\Grpc.Tools.targets')" />
<Import Project="..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.targets" Condition="Exists('..\packages\Grpc.Tools.2.24.0\build\Grpc.Tools.targets')" />
<!-- 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">