Compare commits

...

5 commits

Author SHA1 Message Date
DHR60
d940c6f5a8
Merge d6c81c3a9c into b54c67d6f1 2025-09-09 20:25:29 +08:00
2dust
b54c67d6f1 up 7.14.9
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows desktop (Avalonia UI) / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run
2025-09-09 20:18:55 +08:00
2dust
b49486cc23 Update ProfilesSelectWindow.axaml 2025-09-09 20:00:00 +08:00
JieXu
b95830b3d5
Update package-rhel.sh package-debian.sh MainWindowViewModel.cs (#7910)
* Update package-rhel.sh

* Update package-rhel.sh

* Update package-rhel.sh

* Update package-rhel.sh

* Update MainWindowViewModel.cs

* Update package-rhel.sh

* Update package-debian.sh
2025-09-09 19:51:10 +08:00
DHR60
d6c81c3a9c PreCheck 2025-09-07 19:03:20 +08:00
14 changed files with 454 additions and 49 deletions

View file

@ -28,7 +28,7 @@ Package: v2rayN
Version: $Version
Architecture: $Arch2
Maintainer: https://github.com/2dust/v2rayN
Depends: desktop-file-utils
Depends: desktop-file-utils, xdg-utils
Description: A GUI client for Windows and Linux, support Xray core and sing-box-core and others
EOF

View file

@ -1,11 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail
# ===== Require Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS OR Ubuntu/Debian ====
# == Require Red Hat Enterprise Linux/FedoraLinux/RockyLinux/AlmaLinux/CentOS OR Ubuntu/Debian ==
if [[ -r /etc/os-release ]]; then
. /etc/os-release
case "$ID" in
rhel|rocky|almalinux|centos|ubuntu|debian)
rhel|rocky|almalinux|fedora|centos|ubuntu|debian)
echo "[OK] Detected supported system: $NAME $VERSION_ID"
;;
*)
@ -390,25 +390,30 @@ download_mihomo() {
chmod +x "$outroot/bin/mihomo/mihomo" || true
}
# Move geo files to a unified path: outroot/bin/xray/
# Move geo files to a unified path: outroot/bin
unify_geo_layout() {
local outroot="$1"
mkdir -p "$outroot/bin/xray"
local srcs=( \
"$outroot/bin/geosite.dat" \
"$outroot/bin/geoip.dat" \
"$outroot/bin/geoip-only-cn-private.dat" \
"$outroot/bin/Country.mmdb" \
"$outroot/bin/geoip.metadb" \
mkdir -p "$outroot/bin"
local names=( \
"geosite.dat" \
"geoip.dat" \
"geoip-only-cn-private.dat" \
"Country.mmdb" \
"geoip.metadb" \
)
for s in "${srcs[@]}"; do
if [[ -f "$s" ]]; then
mv -f "$s" "$outroot/bin/xray/$(basename "$s")"
for n in "${names[@]}"; do
# If file exists under bin/xray/, move it up to bin/
if [[ -f "$outroot/bin/xray/$n" ]]; then
mv -f "$outroot/bin/xray/$n" "$outroot/bin/$n"
fi
# If file already in bin/, leave it as-is
if [[ -f "$outroot/bin/$n" ]]; then
:
fi
done
}
# Download geo/rule assets; then unify to bin/xray/
# Download geo/rule assets; then unify to bin/
download_geo_assets() {
local outroot="$1"
local bin_dir="$outroot/bin"
@ -442,7 +447,7 @@ download_geo_assets() {
"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-geosite/$f" || true
done
# Unify to bin/xray/
# Unify to bin/
unify_geo_layout "$outroot"
}
@ -480,7 +485,7 @@ download_v2rayn_bundle() {
rm -rf "$nested_dir"
fi
# Unify to bin/xray/
# Unify to bin/
unify_geo_layout "$outroot"
echo "[+] Bundle extracted to $outroot"
@ -610,7 +615,7 @@ Source0: __PKGROOT__.tar.gz
# Runtime dependencies (Avalonia / X11 / Fonts / GL)
Requires: libX11, libXrandr, libXcursor, libXi, libXext, libxcb, libXrender, libXfixes, libXinerama, libxkbcommon
Requires: fontconfig, freetype, cairo, pango, mesa-libEGL, mesa-libGL
Requires: fontconfig, freetype, cairo, pango, mesa-libEGL, mesa-libGL, xdg-utils
%description
v2rayN Linux for Red Hat Enterprise Linux
@ -629,25 +634,13 @@ https://github.com/2dust/v2rayN
install -dm0755 %{buildroot}/opt/v2rayN
cp -a * %{buildroot}/opt/v2rayN/
# Launcher (prefer native ELF first, then DLL fallback; also create Geo symlinks for the user)
# Launcher (prefer native ELF first, then DLL fallback)
install -dm0755 %{buildroot}%{_bindir}
cat > %{buildroot}%{_bindir}/v2rayn << 'EOF'
#!/usr/bin/bash
set -euo pipefail
DIR="/opt/v2rayN"
# --- Symlink GEO files into user's XDG dir (first-run convenience) ---
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
USR_GEO_DIR="$XDG_DATA_HOME/v2rayN/bin"
SYS_XRAY_DIR="$DIR/bin/xray"
mkdir -p "$USR_GEO_DIR"
for f in geosite.dat geoip.dat geoip-only-cn-private.dat Country.mmdb; do
if [[ -f "$SYS_XRAY_DIR/$f" && ! -e "$USR_GEO_DIR/$f" ]]; then
ln -s "$SYS_XRAY_DIR/$f" "$USR_GEO_DIR/$f" || true
fi
done
# --- end GEO ---
# Prefer native apphost
if [[ -x "$DIR/v2rayN" ]]; then exec "$DIR/v2rayN" "$@"; fi

View file

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>7.14.8</Version>
<Version>7.14.9</Version>
</PropertyGroup>
<PropertyGroup>

View file

@ -114,6 +114,33 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Core &apos;{0}&apos; does not support network type &apos;{1}&apos;. 的本地化字符串。
/// </summary>
public static string CoreNotSupportNetwork {
get {
return ResourceManager.GetString("CoreNotSupportNetwork", resourceCulture);
}
}
/// <summary>
/// 查找类似 Core &apos;{0}&apos; does not support protocol &apos;{1}&apos;. 的本地化字符串。
/// </summary>
public static string CoreNotSupportProtocol {
get {
return ResourceManager.GetString("CoreNotSupportProtocol", resourceCulture);
}
}
/// <summary>
/// 查找类似 Core &apos;{0}&apos; does not support protocol &apos;{1}&apos; when using transport &apos;{2}&apos;. 的本地化字符串。
/// </summary>
public static string CoreNotSupportProtocolTransport {
get {
return ResourceManager.GetString("CoreNotSupportProtocolTransport", resourceCulture);
}
}
/// <summary>
/// 查找类似 Note that custom configuration relies entirely on your own configuration and does not work with all settings. If you want to use the system proxy, please modify the listening port manually. 的本地化字符串。
/// </summary>
@ -2040,6 +2067,24 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Proxy chained node alias &apos;{0}&apos; does not exist. 的本地化字符串。
/// </summary>
public static string ProxyChainedNodeTagNotExist {
get {
return ResourceManager.GetString("ProxyChainedNodeTagNotExist", resourceCulture);
}
}
/// <summary>
/// 查找类似 Proxy chained node remark &apos;{0}&apos; refers to an outbound that does not support config type &apos;{1}&apos;. 的本地化字符串。
/// </summary>
public static string ProxyChainedNodeTagNotSupportConfigType {
get {
return ResourceManager.GetString("ProxyChainedNodeTagNotSupportConfigType", resourceCulture);
}
}
/// <summary>
/// 查找类似 Global hotkey {0} registration failed, reason: {1} 的本地化字符串。
/// </summary>
@ -2103,6 +2148,24 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Routing rule references outbound remark &apos;{0}&apos;, but no outbound with this remark exists. 的本地化字符串。
/// </summary>
public static string RoutingRuleOutboundTagNotExist {
get {
return ResourceManager.GetString("RoutingRuleOutboundTagNotExist", resourceCulture);
}
}
/// <summary>
/// 查找类似 Routing rule outbound remark &apos;{0}&apos; refers to an outbound that does not support config type &apos;{1}&apos;. 的本地化字符串。
/// </summary>
public static string RoutingRuleOutboundTagNotSupportConfigType {
get {
return ResourceManager.GetString("RoutingRuleOutboundTagNotSupportConfigType", resourceCulture);
}
}
/// <summary>
/// 查找类似 Run as Admin 的本地化字符串。
/// </summary>

View file

@ -1515,4 +1515,25 @@
<data name="TbSelectProfile" xml:space="preserve">
<value>Select Profile</value>
</data>
<data name="CoreNotSupportNetwork" xml:space="preserve">
<value>Core '{0}' does not support network type '{1}'.</value>
</data>
<data name="CoreNotSupportProtocolTransport" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}' when using transport '{2}'.</value>
</data>
<data name="CoreNotSupportProtocol" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}'.</value>
</data>
<data name="RoutingRuleOutboundTagNotExist" xml:space="preserve">
<value>Routing rule references outbound remark '{0}', but no outbound with this remark exists.</value>
</data>
<data name="ProxyChainedNodeTagNotSupportConfigType" xml:space="preserve">
<value>Proxy chained node remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
<data name="ProxyChainedNodeTagNotExist" xml:space="preserve">
<value>Proxy chained node alias '{0}' does not exist.</value>
</data>
<data name="RoutingRuleOutboundTagNotSupportConfigType" xml:space="preserve">
<value>Routing rule outbound remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
</root>

View file

@ -1515,4 +1515,25 @@
<data name="TbSelectProfile" xml:space="preserve">
<value>Select Profile</value>
</data>
<data name="CoreNotSupportNetwork" xml:space="preserve">
<value>Core '{0}' does not support network type '{1}'.</value>
</data>
<data name="CoreNotSupportProtocolTransport" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}' when using transport '{2}'.</value>
</data>
<data name="CoreNotSupportProtocol" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}'.</value>
</data>
<data name="RoutingRuleOutboundTagNotExist" xml:space="preserve">
<value>Routing rule references outbound remark '{0}', but no outbound with this remark exists.</value>
</data>
<data name="ProxyChainedNodeTagNotSupportConfigType" xml:space="preserve">
<value>Proxy chained node remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
<data name="ProxyChainedNodeTagNotExist" xml:space="preserve">
<value>Proxy chained node alias '{0}' does not exist.</value>
</data>
<data name="RoutingRuleOutboundTagNotSupportConfigType" xml:space="preserve">
<value>Routing rule outbound remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
</root>

View file

@ -1515,4 +1515,25 @@
<data name="TbSelectProfile" xml:space="preserve">
<value>Select Profile</value>
</data>
<data name="CoreNotSupportNetwork" xml:space="preserve">
<value>Core '{0}' does not support network type '{1}'.</value>
</data>
<data name="CoreNotSupportProtocolTransport" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}' when using transport '{2}'.</value>
</data>
<data name="CoreNotSupportProtocol" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}'.</value>
</data>
<data name="RoutingRuleOutboundTagNotExist" xml:space="preserve">
<value>Routing rule references outbound remark '{0}', but no outbound with this remark exists.</value>
</data>
<data name="ProxyChainedNodeTagNotSupportConfigType" xml:space="preserve">
<value>Proxy chained node remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
<data name="ProxyChainedNodeTagNotExist" xml:space="preserve">
<value>Proxy chained node alias '{0}' does not exist.</value>
</data>
<data name="RoutingRuleOutboundTagNotSupportConfigType" xml:space="preserve">
<value>Routing rule outbound remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
</root>

View file

@ -1515,4 +1515,25 @@
<data name="TbSelectProfile" xml:space="preserve">
<value>Select Profile</value>
</data>
<data name="CoreNotSupportNetwork" xml:space="preserve">
<value>Core '{0}' does not support network type '{1}'.</value>
</data>
<data name="CoreNotSupportProtocolTransport" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}' when using transport '{2}'.</value>
</data>
<data name="CoreNotSupportProtocol" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}'.</value>
</data>
<data name="RoutingRuleOutboundTagNotExist" xml:space="preserve">
<value>Routing rule references outbound remark '{0}', but no outbound with this remark exists.</value>
</data>
<data name="ProxyChainedNodeTagNotSupportConfigType" xml:space="preserve">
<value>Proxy chained node remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
<data name="ProxyChainedNodeTagNotExist" xml:space="preserve">
<value>Proxy chained node alias '{0}' does not exist.</value>
</data>
<data name="RoutingRuleOutboundTagNotSupportConfigType" xml:space="preserve">
<value>Routing rule outbound remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
</root>

View file

@ -1512,4 +1512,25 @@
<data name="TbSelectProfile" xml:space="preserve">
<value>选择配置文件</value>
</data>
<data name="CoreNotSupportNetwork" xml:space="preserve">
<value>核心 '{0}' 不支持网络类型 '{1}'。</value>
</data>
<data name="CoreNotSupportProtocolTransport" xml:space="preserve">
<value>核心 '{0}' 在使用传输方式 '{2}' 时不支持协议 '{1}'。</value>
</data>
<data name="CoreNotSupportProtocol" xml:space="preserve">
<value>核心 '{0}' 不支持协议 '{1}'。</value>
</data>
<data name="RoutingRuleOutboundTagNotExist" xml:space="preserve">
<value>路由规则引用了出站别名 '{0}',但不存在具有该别名的出站。</value>
</data>
<data name="ProxyChainedNodeTagNotSupportConfigType" xml:space="preserve">
<value>代理链节点别名 '{0}' 引用的出站不支持配置类型 '{1}'。</value>
</data>
<data name="ProxyChainedNodeTagNotExist" xml:space="preserve">
<value>代理链节点别名 '{0}' 不存在。</value>
</data>
<data name="RoutingRuleOutboundTagNotSupportConfigType" xml:space="preserve">
<value>路由规则出站别名 '{0}' 引用的出站不支持配置类型 '{1}'。</value>
</data>
</root>

View file

@ -1512,4 +1512,25 @@
<data name="TbSelectProfile" xml:space="preserve">
<value>Select Profile</value>
</data>
<data name="CoreNotSupportNetwork" xml:space="preserve">
<value>Core '{0}' does not support network type '{1}'.</value>
</data>
<data name="CoreNotSupportProtocolTransport" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}' when using transport '{2}'.</value>
</data>
<data name="CoreNotSupportProtocol" xml:space="preserve">
<value>Core '{0}' does not support protocol '{1}'.</value>
</data>
<data name="RoutingRuleOutboundTagNotExist" xml:space="preserve">
<value>Routing rule references outbound remark '{0}', but no outbound with this remark exists.</value>
</data>
<data name="ProxyChainedNodeTagNotSupportConfigType" xml:space="preserve">
<value>Proxy chained node remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
<data name="ProxyChainedNodeTagNotExist" xml:space="preserve">
<value>Proxy chained node alias '{0}' does not exist.</value>
</data>
<data name="RoutingRuleOutboundTagNotSupportConfigType" xml:space="preserve">
<value>Routing rule outbound remark '{0}' refers to an outbound that does not support config type '{1}'.</value>
</data>
</root>

View file

@ -0,0 +1,211 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DynamicData;
using ServiceLib.Models;
namespace ServiceLib.Services;
/// <summary>
/// Centralized pre-checks before sensitive actions (set active profile, generate config, etc.).
/// Return (ok, msg) for VMs to decide.
/// </summary>
public class ActionPrecheckService
{
private static readonly Lazy<ActionPrecheckService> _instance = new(() => new ActionPrecheckService(AppManager.Instance.Config));
public static ActionPrecheckService Instance => _instance.Value;
private readonly Config _config;
public ActionPrecheckService(Config config)
{
_config = config;
}
private static List<string> OneMsg(string msg) => new() { msg };
public async Task<(bool ok, List<string> msgs)> CheckBeforeSetActive(string? indexId)
{
if (indexId.IsNullOrEmpty())
{
return (false, OneMsg(ResUI.PleaseSelectServer));
}
var item = await AppManager.Instance.GetProfileItem(indexId);
if (item is null)
{
return (false, OneMsg(ResUI.PleaseSelectServer));
}
return await CheckBeforeGenerateConfig(item);
}
public async Task<(bool ok, List<string> msgs)> CheckBeforeGenerateConfig(ProfileItem? item)
{
if (item is null)
{
return (false, OneMsg(ResUI.PleaseSelectServer));
}
var msgs = new List<string>();
var currentNodeMsgs = ValidateCurrentNodeAndCoreSupport(item).ToList();
if (currentNodeMsgs.Count > 0)
{
msgs.AddRange(currentNodeMsgs);
return (false, msgs);
}
msgs.AddRange(await ValidateRelatedNodesExistAndValid(item));
return (true, msgs);
}
private IEnumerable<string> ValidateCurrentNodeAndCoreSupport(ProfileItem item)
{
var coreType = AppManager.Instance.GetCoreType(item, item.ConfigType);
return ValidateNodeAndCoreSupport(item, coreType);
}
/// <summary>
/// <summary>
/// Validate whether the node and chosen core combination is supported. Returns a collection of messages to show the user.
/// An empty collection means there are no blocking errors.
/// </summary>
///
private IEnumerable<string> ValidateNodeAndCoreSupport(ProfileItem item, ECoreType? coreType = null)
{
// sing-box does not support xhttp / kcp
// sing-box does not support transports like ws/http/httpupgrade/etc. when the node is not vmess/trojan/vless
coreType ??= AppManager.Instance.GetCoreType(item, item.ConfigType);
var net = item.GetNetwork() ?? item.Network;
if (coreType == ECoreType.sing_box)
{
if (net is nameof(ETransport.kcp) or nameof(ETransport.xhttp))
{
yield return string.Format(ResUI.CoreNotSupportNetwork, nameof(ECoreType.sing_box), net);
yield break;
}
if (item.ConfigType is not (EConfigType.VMess or EConfigType.VLESS or EConfigType.Trojan))
{
if (net is nameof(ETransport.ws) or nameof(ETransport.http) or nameof(ETransport.h2) or nameof(ETransport.quic) or nameof(ETransport.httpupgrade))
{
yield return string.Format(ResUI.CoreNotSupportProtocolTransport, nameof(ECoreType.sing_box), item.ConfigType.ToString(), net);
yield break;
}
}
}
else if (coreType is ECoreType.Xray)
{
// Xray core does not support these protocols
if (item.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls)
{
yield return string.Format(ResUI.CoreNotSupportProtocol, nameof(ECoreType.Xray), item.ConfigType.ToString());
yield break;
}
}
yield break; // explicit for clarity; no blocking errors
}
/// <summary>
/// Validate that nodes related to the current node (chained/routing) exist and are valid.
/// </summary>
private async Task<IEnumerable<string>> ValidateRelatedNodesExistAndValid(ProfileItem? item)
{
var msgs = new List<string>();
msgs.AddRange(await ValidateProxyChainedNodeExistAndValid(item));
msgs.AddRange(await ValidateRoutingNodeExistAndValid(item));
return msgs;
}
private async Task<IEnumerable<string>> ValidateProxyChainedNodeExistAndValid(ProfileItem? item)
{
var msgs = new List<string>();
if (item is null)
{
return msgs;
}
// prev node and next node
var subItem = await AppManager.Instance.GetSubItem(item.Subid);
if (subItem is null)
{
return msgs;
}
var prevNode = await AppManager.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
var nextNode = await AppManager.Instance.GetProfileItemViaRemarks(subItem.NextProfile);
var coreType = AppManager.Instance.GetCoreType(item, item.ConfigType);
CollectProxyChainedNodeValidation(prevNode, subItem.PrevProfile, coreType, msgs);
CollectProxyChainedNodeValidation(nextNode, subItem.NextProfile, coreType, msgs);
return msgs;
}
private void CollectProxyChainedNodeValidation(ProfileItem? node, string tag, ECoreType coreType, List<string> msgs)
{
if (node is not null)
{
msgs.AddRange(ValidateNodeAndCoreSupport(node, coreType));
if (node.ConfigType is EConfigType.Custom)
{
msgs.Add(string.Format(ResUI.ProxyChainedNodeTagNotSupportConfigType, node.Remarks, node.ConfigType.ToString()));
}
}
else if (tag.IsNotEmpty())
{
msgs.Add(string.Format(ResUI.ProxyChainedNodeTagNotExist, tag));
}
}
private async Task<IEnumerable<string>> ValidateRoutingNodeExistAndValid(ProfileItem? item)
{
var msgs = new List<string>();
if (item is null)
{
return msgs;
}
var coreType = AppManager.Instance.GetCoreType(item, item.ConfigType);
var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing == null)
{
return msgs;
}
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var ruleItem in rules ?? [])
{
if (!ruleItem.Enabled)
{
continue;
}
var outboundTag = ruleItem.OutboundTag;
if (outboundTag.IsNullOrEmpty() || Global.OutboundTags.Contains(outboundTag))
{
continue;
}
var tagItem = await AppManager.Instance.GetProfileItemViaRemarks(outboundTag);
if (tagItem is null)
{
msgs.Add(string.Format(ResUI.RoutingRuleOutboundTagNotExist, outboundTag));
continue;
}
msgs.AddRange(ValidateNodeAndCoreSupport(tagItem, coreType));
if (tagItem.ConfigType is EConfigType.Custom)
{
msgs.Add(string.Format(ResUI.RoutingRuleOutboundTagNotSupportConfigType, outboundTag, tagItem.ConfigType.ToString()));
}
}
return msgs;
}
}

View file

@ -488,7 +488,7 @@ public class MainWindowViewModel : MyReactiveObject
}
else if (Utils.IsLinux())
{
ProcUtils.ProcessStart("nautilus", path);
ProcUtils.ProcessStart("xdg-open", path);
}
else if (Utils.IsOSX())
{

View file

@ -594,6 +594,16 @@ public class ProfilesViewModel : MyReactiveObject
return;
}
var (ok, msgs) = await ActionPrecheckService.Instance.CheckBeforeSetActive(indexId);
if (msgs.Count > 0)
{
NoticeManager.Instance.Enqueue(msgs.First());
}
if (!ok)
{
return;
}
if (await ConfigHandler.SetDefaultServerIndex(_config, indexId) == 0)
{
await RefreshServers();
@ -757,6 +767,16 @@ public class ProfilesViewModel : MyReactiveObject
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
return;
}
var (ok, msgs) = await ActionPrecheckService.Instance.CheckBeforeGenerateConfig(item);
if (msgs.Count > 0)
{
NoticeManager.Instance.Enqueue(msgs.First());
}
if (!ok)
{
return;
}
if (blClipboard)
{
var result = await CoreConfigHandler.GenerateClientConfig(item, null);

View file

@ -38,9 +38,10 @@
<WrapPanel Margin="4" DockPanel.Dock="Top">
<ListBox
x:Name="lstGroup"
Margin="4,0"
Margin="{StaticResource MarginLr4}"
DisplayMemberBinding="{Binding Remarks}"
ItemsSource="{Binding SubItems}">
ItemsSource="{Binding SubItems}"
Theme="{DynamicResource ButtonRadioGroupListBox}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
@ -89,20 +90,11 @@
Binding="{Binding ConfigType}"
Header="{x:Static resx:ResUI.LvServiceType}"
Tag="ConfigType" />
<DataGridTemplateColumn SortMemberPath="Remarks" Tag="Remarks">
<DataGridTemplateColumn.Header>
<TextBlock Text="{x:Static resx:ResUI.LvRemarks}" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Margin="8,0" Orientation="Horizontal">
<TextBlock Text="{Binding Remarks}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Width="120"
Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}"
Tag="Remarks" />
<DataGridTextColumn
Width="120"
Binding="{Binding Address}"