C#修改*.exe.config配置文件已经搞定,不知道不知道有没有刷新缓存中的配置文件的方法,求大神解答

2649人阅读
在一个项目中碰到这样的一个问题,做一个WORD插件,功能在类库项目中实现了,配置信息存在类库项目的配置文件app.config中,在进行打包后,获取的配置文件中的DocType节点信息时,使用以下方法& ConfigurationManager.AppSettings["DocType"]获取的值总是获取不到,跟踪调试发现值为null,上网看到类库被应用以后,ConfigurationManager.AppSettings访问的是应用程序的配置文件而不是类库所用的配置文件了,所以只有改变策略,把app.config文件也打包到安装文件中,安装后,在安装路径中找到这个文件并进行读取相应的信息,具体的实现方法如下(.net环境下的C#代码)
//获取文件安装的路径&Assembly SampleAssembly = Assembly.GetExecutingAssembly();string FilePath = Path.GetDirectoryName(SampleAssembly.CodeBase.Substring(8)) + "//App.config";//解析配置文件获取对应的值XmlDocument xDoc = new XmlDocument();xDoc.Load(FilePath);string&&DocType = xDoc.SelectSingleNode(@"/configuration/appSettings/add[@key='DocType']").Attributes["value"].V
DocType 就是要获取的值了。
&&&&&&一般来说,.net 的exe assemly会存在一个对应的*.exe.config配置文件。当需要读取配置信息的时候,可以直接通过ConfigurationManager.AppSettings[index]来读取*.exe.config中的键值,但很少存在dll assembly需要config file的情况。假如当前dll assembly名为test.dll,如果在test.dll中调用ConfigurationManager来读取test.dll.config,那么是无法成功的!
&&&&&&当然,在dll assembly中要读取其*.dll.config这种需求非常少见。但是确要读取的话,可以采取以下方式,即强行制定其dll assembly的路径。
&&&&&&以下代码演示的是:编写一个.net dll并将其发布为一个regasm test.dll /codebase /tlb将其发布为一个DCOM,&然后通过asp页面来调用&。其中在test.dll中的公布的方法HelloWorld()需要读取其test.dll.config中的key value.&&
dll assembly代码如下:
C# version:
using&Susing&System.Collections.Gusing&System.Tusing&System.Runtime.InteropSusing&System.Cusing&System.IO;using&System.Rnamespace&AnotherDCOM{&&&&[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]&&&&public&interface&ITestClass&&&&{&&&&&&&&string&HelloWorld();&&&&}&&&&[ClassInterface(ClassInterfaceType.AutoDispatch)]&&&&public&class&SimpleClass:ITestClass&&&&{&&&&&&&&&&&&&&&&&&public&string&HelloWorld()&&&&&&&&{&&&&&&&&&&&&Assembly&&&&&&&&&&&&&System.Configuration.Configuration&&&&&&&&&&&&&ExeConfigurationFileMap&&&&&&&&&&&&&&&&&&&&&&Uri&&&&&&&&&&&&&map&=&new&ExeConfigurationFileMap();&&&&&&&&&&&&assembly&=&Assembly.GetCallingAssembly();&&&&&&&&&&&&uri&=&new&Uri(Path.GetDirectoryName(assembly.CodeBase));&&&&&&&&&&&&map.ExeConfigFilename&=&bine(uri.LocalPath,&assembly.GetName().Name&+&".dll.config");&&&&&&&&&&&&string&str=ConfigurationManager.OpenMappedExeConfiguration(map,&0).AppSettings.Settings["MyString"].V&&&&&&&&&&&&/*&&&&&&&&&&&&说明:如果采取如下的传统方法,读取config&key&&&&&&&&&&&&string&str&=&ConfigurationManager.AppSettings["MyString"];&&&&&&&&&&&&如果采取这种方式的话,&则assembly不会读取相应*.dll.config文件;by&default,只有exe&assembly的配置文件才会被load&&&&&&&&&&&&&*/&&&&&&&&&&&&if&(str&!=&null)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&return&&&&&&&&&&&&&}&&&&&&&&&&&&else&&&&&&&&&&&&{&&&&&&&&&&&&&&&&return&"Hello&World&.net&Another&DCOM,&Can't&read&config";&&&&&&&&&&&&}&&&&&&&&&&&&&&&}&&&&}}
VB.net version
Imports&SystemImports&System.Runtime.InteropServicesImports&System.ReflectionImports&System.ConfigurationImports&System.IONamespace&NetDcom&&&&&InterfaceType(ComInterfaceType.InterfaceIsIDispatch)&&Public&Interface&ITestClass&&&&&&&&Function&HelloWorld()&As&String&&&&End&Interface&&&&&ClassInterface(ClassInterfaceType.AutoDispatch),&ProgId("NetDcom.SimpleClass"),&ComVisible(True)&&Public&Class&SimpleClass&&&&&&&&Implements&ITestClass&&&&&&&&Public&Function&HelloWorld()&As&String&Implements&ITestClass.HelloWorld&&&&&&&&&&&&Dim&assembly&As&Assembly&&&&&&&&&&&&Dim&configuration&As&Configuration&&&&&&&&&&&&Dim&map&As&ExeConfigurationFileMap&&&&&&&&&&&&Dim&str&As&String&&&&&&&&&&&&Dim&uri&As&Uri&&&&&&&&&&&&map&=&New&ExeConfigurationFileMap&&&&&&&&&&&&[assembly]&=&assembly.GetCallingAssembly&&&&&&&&&&&&uri&=&New&Uri(Path.GetDirectoryName([assembly].CodeBase))&&&&&&&&&&&&map.ExeConfigFilename&=&bine(uri.LocalPath,&([assembly].GetName.Name&&&".dll.config"))&&&&&&&&&&&&str&=&ConfigurationManager.OpenMappedExeConfiguration(map,&0).AppSettings.Settings.Item("MyString").Value&&&&&&&&&&&&If&String.IsNullOrEmpty(str)&&&&True&Then&&&&&&&&&&&&&&&&HelloWorld&=&str&&&&&&&&&&&&Else&&&&&&&&&&&&&&&&HelloWorld&=&"Hello&World,&.net&DCOM(vb.net)"&&&&&&&&&&&&End&If&&&&&&&&End&Function&&&&End&ClassEnd&Namespace
app.config配置文件如下(编译后会自动生成test.dll.config文件):
&?xml&version="1.0"&encoding="utf-8"&?&&configuration&&&&appSettings&&&&&&add&key="MyString"&value="Hello&World"/&&&&&&&&/appSettings&&/configuration&
编译发布之后,运行以下command将其注册为DCOM
regasm test.dll /codebase /tlb
说明:如果.net dll要注册成为COM的话,需要几个必备的条件:
1. dll要设置相应的System.runtime.InteropServices的相应attribute,如山代码所示。
2. (C#中)assemblyinfo.cs中, comvisible要设置为true。
3. 生成dll assembly的时候,一定要选中 Register for ComInterop复选框,如下所示
然后,通过asp调用该DCOM如下:&
&%set&obj=CreateObject("AnotherDCOM.SimpleClass")Response.write&obj.HelloWorld()%&
通过procmon我们可以看到,该dll.config被争取读取了:)&
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:221458次
积分:2708
积分:2708
排名:第6260名
原创:65篇
转载:95篇
评论:29条
(1)(3)(3)(1)(1)(2)(2)(12)(2)(16)(3)(5)(5)(21)(5)(8)(36)(3)(2)(6)(24)C#笔记29:程序集及应用程序配置及App.config和YourSoft.exe.config 本章概要:
1:什么是程序集
2:程序集标识属性
3:强名称的程序集
3.1:强名称工作原理
4:配置文件
5:使用 DEVPATH 查找程序集 6:指定要使用的运行库版本 7:App.config和YourSoft.exe.config & 1:什么是程序集
&&&& 程序集是 .NET Framework 应用程序的构造块;程序集构成了部署、版本控制、重复使用、激活范围控制和安全权限的基本单元。程序集是为协同工作而生成的类型和资源的集合,这些类型和资源构成了一个逻辑功能单元。程序集向公共语言运行库提供了解类型实现所需要的信息。
&&&& 程序集属性是提供程序集相关信息的值。属性分为以下几组信息:
程序集标识属性。
信息性属性。
程序集清单属性。
强名称属性。 2:程序集标识属性
&&&& 三种属性与强名称(如果适用)一起决定程序集的标识:名称、版本和区域性。这些属性构成程序集的完整名称,并且在代码中引用程序集时需要这些属性。您可以使用属性来设置程序集的版本和区域性。编译器或 根据包含程序集清单的文件在创建程序集时设置名称值。&& &&&& 有关程序集属性的更多信息,参看
& 3:强名称的程序集
&&&& 强名称是由程序集的标识加上公钥和数字签名组成的,其中,程序集的标识包括简单文本名称、版本号和区域性信息(如果提供的话)。它使用对应的私钥从程序集文件中生成。(程序集文件包含程序集清单,其中包含组成程序集的所有文件的名称和哈希。)
&&&& 具有强名称的程序集只能使用其他具有强名称的程序集的类型。否则将会危及到该具有强名称的程序集的安全。
& 3.1:强名称工作原理 签名机制1. 用SN.exe 生成一个key文件, 这个key文件包括一个public key 和一个private key.2. 用这个key文件签名assembly时, 编译器将用private key签名程序集, 并将public key嵌入manifest中3. 编译器哈希manifest中所有的assembly内容, 并将此哈希值各自assembly的FileDef Talbe中. 4. 当如上3步处理后, 编译器将哈希PE文件的整个内容(除authenticode signature, 强名称数据, PE头), 然后将此哈希值用private key签名. 得到RSA数字签名.5. 将此数字签名嵌入到PE文件的CLR头
防修改机制1. 当签名后的assembly安装到GAC, 系统会哈希PE文件(同签名), 得到哈希值2. 系统读取PE文件中CLR头中的RSA签名, 并用public key(包含在manifest中)解密3. 比较第1步得到的哈希值和第2步得到解密值是否一致, 从而判断其是否被修改.
& 4:配置文件 &&&& 配置文件是可以按需要更改的 XML 文件。开发人员可以使用配置文件来更改设置,而不必重编译应用程序。管理员可以使用配置文件来设置策略,以便影响应用程序在计算机上运行的方式。
&&&& 配置文件更多内容查看。 & 5:使用 DEVPATH 查找程序集 &&&& 开发人员可能想确保他们正在生成的共享程序集能与多个应用程序一起正常使用。在开发周期内开发人员不用频繁地将程序集放在全局程序集缓存中,他们可以创建 DEVPATH 环境变量,让该变量指向程序集的生成输出目录。
&&&& 例如,假设您正在生成名为 MySharedAssembly 的共享程序集,且输出目录是 C:\MySharedAssembly\Debug。可以将 C:\MySharedAssembly\Debug 置于 DEVPATH 变量中。然后必须在计算机配置文件中指定
元素。该元素告诉公共语言运行库使用 DEVPATH 来查找程序集。
&&&& 共享程序集必须能够由运行库发现。 若要指定用于解析程序集引用的私有目录,请在配置文件中使用
中所述。 还可以将程序集放在应用程序目录的子目录中。有关更多信息,请参见。
&&&& 下面的示例说明如何使运行库在由 DEVPATH 环境变量所指定的目录中搜索程序集。
&configuration&
&developmentMode developerInstallation="true"/&
&/runtime&
&/configuration&
6:指定要使用的运行库版本
&?xml version ="1.0"?&
&configuration&
&supportedRuntime version="v1.1.4322" /&
&/startup&
&/configuration&
7:App.config和YourSoft.exe.config
&&&& 为了更加快速的使用配置信息而不自己写代码实现读写,我们在创建应用程序的时候应该使用App.config。创建完毕后,我们发现App.config的属性是:
&&&& 以上是创建App.config后的默认设置,不要修改这些属性,编译你的解决方案,会在输出目录中发现生成了一个YourSoft.exe.config(假设你的应用程序名为YourSoft.exe)。下面有几点需要说明:
&&&& 1:YourSoft.exe.config其实对应的就是你解决方案中的App.config。注意,千万不要以为在输出目录中它也会以App.config存在。
&&&& 2:如果“复制到输出目录”属性你设置的是“复制”或者“较新则复制”,则App.config会被复制到输出目录。千万不要以为在输出目录中的App.config对应用程序会有任何意义。运行时默认还是会去读YourSoft.exe.config。
&&&& 3:输出目录中YourSoft.exe.config的值不会自动保持和你解决方案中的App.config内容一致。你需要手动去设置YourSoft.exe.config中的值。
1.You are creating a strong-named assembly named Asse& mbly1 that will be used in multiple applications.
Assembly1 will be rebuilt frequently during the development cycle. You need to ensure that each time the& assembly is rebuilt it works correctly with each application that uses it. You need to configure the computer on which you develop Assembly1 such that each application uses the latest bu& ild of Assembly1. Which two actions should you perform? (Each correct answer presents part of the solution. Choose two.) A. Create a DEVPATH environment variable that points to the build output directory for the strong-named&&&&&&& assembly. B. Add the following XML element to the machine configuration filE.&&&&&&&&&& &developmentMode developerInstallation="true"/&
C. Add the following XML element to the machine configuration filE.&&&&&&&&& &dependentAssembly&&&&& &assemblyIdentity name="Assembly1" publicKeyToken="32ab4ba45e0a69a1" language="en-US"& version="*.*.*.*" /& &publisherPolicy apply="no" /&&&&& &/dependentAssembly& D.& Add the following XML element to the configuration file of each application that uses the strong-named&&&&&&& assembly:&& &supportedRuntime version="*.*.*.*" /&& E. Add the following XML element to the configuration file of each application that uses the strong-named&&& assembly:&&&& &dependentAssembly&&&&&& &assemblyIdentity name="Assembly1" publicKeyToken="32ab4ba45e0a69a1" language="en-US"& version="*.*.*.*" /&&&&&&&& &bindingRedirect newVersion="*.*.*.*"/&&&&& &/dependentAssembly& Answer: A, B
2.Your company uses an application named Application1 that was compiled by using the .NET Framework version 1.0. The application currently runs on a shared computer on which the .NET Framework versions 1.0 and&&&&& 1.1 are installed.&&&& You need to move the application to a new computer on which the .NET Framework versions& 1.1 and 2.0 are installed. The application is compatible with the .NET Framework 1.1, but it is incompatible with&&& the .NET Framework 2.0. You need to ensure that the application will use the .NET& Framework version 1.1 on the& new computer. What should you do?&&& A.& Add the following XML element to the application configuration file.&&&&&&& &configuration&&&&&& &startup&&&&&&&& &supportedRuntime version="1.1.4322" /&&&&&&& &startup&&&& &/configuration&
B. Add the following XML element to the application configuration file.&&&&&&& &configuration&&&&&& &runtime&&&&&&&& &assemblyBinding& xmlns="urn:schemas-microsoft-com:asm.v1"&&&&&&&&&& &dependentAssembly&&&&&&&&&&&&&& &assemblyIdentity name="Application1"& publicKeyToken="32ab4ba45e0a69a1"& culture="neutral" /&&&&&&&&&&&&&& &bindingRedirect oldVersion="1.0.3075.0" newVersion="1.1.4322.0"/&&&&&&&&&&&& &/dependentAssembly&&&&&&& &/assemblyBinding&&&& &/runtime&&& &/configuration& C. Add the following XML element to the machine configuration file.&&&&&&&&&& &configuration&&&&&& &startup&&&&&&&& &requiredRuntime version="1.1.4322" /&&&&&&&& &startup&&&& &/configuration&
D.& Add the following XML element to the machine configuration file.&&&&&&&&&& &configuration&&&&&& &runtime&&&&&&&& &assemblyBinding& xmlns="urn:schemas-microsoft-com:asm.v1"&&&& &dependentAssembly&&&&&&&&&&&&&& &assemblyIdentity name="Application1"& publicKeyToken="32ab4ba45e0a69a1"& culture="neutral" /&&&&&&&&&&&&&& &bindingRedirect oldVersion="1.0.3075.0" newVersion="1.1.4322.0"/&&&&&&&&&&&& &/dependentAssembly&&&&&&& &/assemblyBinding&&&& &/runtime&&& &/configuration& Answer: A
阅读(...) 评论()应用程序配置文件(App.config)是标准的 XML 文件,XML 标记和属性是区分大小写的。它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序。
对于一个config文件:
&?xml version="1.0" encoding="utf-8" ?&
&configuration&
&appSettings&
&add key="ServerIP" value="127.0.0.1"&&/add&
&add key="DataBase" value="WarehouseDB"&&/add&
&add key="user" value="sa"&&/add&
&add key="password" value="sa"&&/add&
&/appSettings&
&/configuration&
对config配置文件的读写类:
using System.Collections.G
using System.L
using System.T
using System.Text.RegularE
using System.C
using System.ServiceM
using System.ServiceModel.C
namespace NetUtilityLib
public static class ConfigHelper
//依据连接串名字connectionName返回数据连接字符串
public static string GetConnectionStringsConfig(string connectionName)
//指定config文件读取
string file = System.Windows.Forms.Application.ExecutableP
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(file);
string connectionString =
config.ConnectionStrings.ConnectionStrings[connectionName].ConnectionString.ToString();
return connectionS
///&summary&
///更新连接字符串
///&/summary&
///&param name="newName"&连接字符串名称&/param&
///&param name="newConString"&连接字符串内容&/param&
///&param name="newProviderName"&数据提供程序名称&/param&
public static void UpdateConnectionStringsConfig(string newName, string newConString, string newProviderName)
//指定config文件读取
string file = System.Windows.Forms.Application.ExecutableP
Configuration config = ConfigurationManager.OpenExeConfiguration(file);
bool exist = false; //记录该连接串是否已经存在
//如果要更改的连接串已经存在
if (config.ConnectionStrings.ConnectionStrings[newName] != null)
exist = true;
// 如果连接串已存在,首先删除它
if (exist)
config.ConnectionStrings.ConnectionStrings.Remove(newName);
//新建一个连接字符串实例
ConnectionStringSettings mySettings =
new ConnectionStringSettings(newName, newConString, newProviderName);
// 将新的连接串添加到配置文件中.
config.ConnectionStrings.ConnectionStrings.Add(mySettings);
// 保存对配置文件所作的更改
config.Save(ConfigurationSaveMode.Modified);
// 强制重新载入配置文件的ConnectionStrings配置节
ConfigurationManager.RefreshSection("ConnectionStrings");
///&summary&
///返回*.exe.config文件中appSettings配置节的value项
///&/summary&
///&param name="strKey"&&/param&
///&returns&&/returns&
public static string GetAppConfig(string strKey)
string file = System.Windows.Forms.Application.ExecutableP
Configuration config = ConfigurationManager.OpenExeConfiguration(file);
foreach (string key in config.AppSettings.Settings.AllKeys)
if (key == strKey)
return config.AppSettings.Settings[strKey].Value.ToString();
return null;
///&summary&
///在*.exe.config文件中appSettings配置节增加一对键值对
///&/summary&
///&param name="newKey"&&/param&
///&param name="newValue"&&/param&
public static void UpdateAppConfig(string newKey, string newValue)
string file = System.Windows.Forms.Application.ExecutableP
Configuration config = ConfigurationManager.OpenExeConfiguration(file);
bool exist = false;
foreach (string key in config.AppSettings.Settings.AllKeys)
if (key == newKey)
exist = true;
if (exist)
config.AppSettings.Settings.Remove(newKey);
config.AppSettings.Settings.Add(newKey, newValue);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
// 修改system.serviceModel下所有服务终结点的IP地址
public static void UpdateServiceModelConfig(string configPath, string serverIP)
Configuration config = ConfigurationManager.OpenExeConfiguration(configPath);
ConfigurationSectionGroup sec = config.SectionGroups["system.serviceModel"];
ServiceModelSectionGroup serviceModelSectionGroup = sec as ServiceModelSectionG
ClientSection clientSection = serviceModelSectionGroup.C
foreach (ChannelEndpointElement item in clientSection.Endpoints)
string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
string address = item.Address.ToString();
string replacement = string.Format("{0}", serverIP);
address = Regex.Replace(address, pattern, replacement);
item.Address = new Uri(address);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("system.serviceModel");
// 修改applicationSettings中App.Properties.Settings中服务的IP地址
public static void UpdateConfig(string configPath, string serverIP)
Configuration config = ConfigurationManager.OpenExeConfiguration(configPath);
ConfigurationSectionGroup sec = config.SectionGroups["applicationSettings"];
ConfigurationSection configSection = sec.Sections["DataService.Properties.Settings"];
ClientSettingsSection clientSettingsSection = configSection as ClientSettingsS
if (clientSettingsSection != null)
SettingElement element1 = clientSettingsSection.Settings.Get("DataService_SystemManagerWS_SystemManagerWS");
if (element1 != null)
clientSettingsSection.Settings.Remove(element1);
string oldValue = element1.Value.ValueXml.InnerX
element1.Value.ValueXml.InnerXml = GetNewIP(oldValue, serverIP);
clientSettingsSection.Settings.Add(element1);
SettingElement element2 = clientSettingsSection.Settings.Get("DataService_EquipManagerWS_EquipManagerWS");
if (element2 != null)
clientSettingsSection.Settings.Remove(element2);
string oldValue = element2.Value.ValueXml.InnerX
element2.Value.ValueXml.InnerXml = GetNewIP(oldValue, serverIP);
clientSettingsSection.Settings.Add(element2);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("applicationSettings");
private static string GetNewIP(string oldValue, string serverIP)
string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
string replacement = string.Format("{0}", serverIP);
string newvalue = Regex.Replace(oldValue, pattern, replacement);
测试代码如下:
class Program
static void Main(string[] args)
//string file = System.Windows.Forms.Application.ExecutablePath + ".config";
//string file1 = AppDomain.CurrentDomain.SetupInformation.ConfigurationF
string serverIP = ConfigHelper.GetAppConfig("ServerIP");
string db = ConfigHelper.GetAppConfig("DataBase");
string user = ConfigHelper.GetAppConfig("user");
string password = ConfigHelper.GetAppConfig("password");
Console.WriteLine(serverIP);
Console.WriteLine(db);
Console.WriteLine(user);
Console.WriteLine(password);
ConfigHelper.UpdateAppConfig("ServerIP", "192.168.1.11");
string newIP = ConfigHelper.GetAppConfig("ServerIP");
Console.WriteLine(newIP);
Console.ReadKey();
catch (Exception ex)
Console.WriteLine(ex.Message);
阅读(...) 评论()&&&&&&正文
C#操作应用程序配置文件
摘要:C#操作应用程序配置文件
对配置文件的一些疑问:在应用程序的目录下,有两处值得注意的地方,一个是应用程序根目录下的App.config文件,和bindebugname.exe.config 或者 binReleasename.exe.config下的配置文件。所谓操作的配置文件是其中的哪个呢?bindebug中的配置文件是在程序在编译环境中运行时从App.config得到的?第一种方法:引入System.Configuration.dll,空间System.Configuration。应用程序中执行代码:try
showData.Text = System.Configuration.ConfigurationSettings.AppSettings["ConnenctionString"];//读取文件中的节点
catch (Exception eee)
{ }App.config添加一些数据:&?xml version="1.0" encoding="utf-8" ?&
&configuration&
&supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /&
&/startup&
&appSettings&
&add key="ConnenctionString" value="111"/&
&/appSettings&
&/configuration&其中add节点中严格格式写入!!在开发环境中调试运行,改变name.exe.config中的数据。和App.config一样。向name.exe.config文件中配置:&?xml version="1.0" encoding="utf-8" ?&
&configuration&
&supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /&
&/startup&
&appSettings&
&add key="ConnenctionString" value="111"/&
&/appSettings&
&/configuration&会读取到键名为ConnenctionString的对应的值111.发现:App.config文件中的节被程序读取到时,会把App.config中的数据保存到name.exe.如果没有读取到不会保存到name.exe.config中。在name.exe.config中的修改不会变化到App.config中。
全国校区查询
新手入门点击榜
新手入门最新文章
官方新版意见收集
*您的积极反馈是我们前进的动力
官方新版意见收集
提交成功,感谢您的反馈。
我们会认真阅读和考虑每个用户的反馈。

我要回帖

更多关于 你不知道的事 陈永馨 的文章

 

随机推荐