C# 以管理员方式启动程序全解析

引言

在 Windows 应用程序开发的领域中,C# 语言凭借其强大的功能和广泛的适用性,被众多开发者所青睐。然而,在实际的开发过程里,我们常常会遭遇这样的情况:程序需要访问特定的系统资源,像是系统文件夹、注册表项等,或者执行一些具有系统管理性质的特定操作,比如安装服务、修改系统环境变量。在这些场景下,若程序以普通用户权限运行,往往会因为权限不足而导致操作失败,抛出各种令人头疼的异常。

为了攻克这一难题,让程序能够顺利地执行这些受限操作,以管理员方式启动程序就成为了关键的解决方案。这不仅能够确保程序具备足够的权限来访问所需资源,还能为应用的稳定运行和功能实现提供坚实保障。

在接下来的内容中,我将深入且详尽地为大家介绍在 C# 中实现以管理员方式启动程序的多种方法。不仅会有清晰的代码示例,还会对每一行代码进行细致入微的解析,力求让大家能够透彻地理解这一技术的核心要点,从而在实际项目开发中能够灵活、高效地运用,打造出更加健壮、稳定的应用程序。

一、理解管理员权限的重要性

在 Windows 系统的庞大生态中,权限体系犹如精密的齿轮,有条不紊地控制着程序对系统资源的访问。而管理员权限,无疑是其中最为关键的一环,掌握着众多关键资源的 “生杀大权”。像是系统文件夹,这里存放着系统运行所必需的核心文件,对其进行访问和修改往往需要管理员权限的加持。因为随意的操作可能会改变系统的运行逻辑,甚至导致系统崩溃,所以普通用户权限被严格限制访问。

注册表项亦是如此,它宛如系统的 “中枢神经”,存储着各种系统配置信息、用户设置以及软件的安装信息等。许多重要的系统设置和软件配置都依赖于对注册表的准确读写。比如,要更改系统的网络连接设置、添加或删除设备驱动程序的相关配置,都需要具备管理员权限才能对注册表进行相应的操作。若以普通用户权限尝试修改,系统会无情地拒绝,抛出权限不足的错误提示。

在实际应用场景中,当我们开发的程序需要进行系统级别的操作时,管理员权限就显得尤为重要。例如,一款系统优化软件,它需要清理系统临时文件、修复系统错误、调整系统服务等操作。这些临时文件可能分布在系统的各个角落,有些处于受保护的系统文件夹中;修复系统错误可能涉及到修改注册表中的关键配置项;调整系统服务更是需要对系统服务的启动、停止、配置等进行控制,而这些操作都需要管理员权限的支持。再如,一个软件安装程序,它需要将文件复制到系统指定的目录,修改系统环境变量,以便软件能够正常运行。若没有管理员权限,这些操作根本无法完成,软件也就无法成功安装。

二、常见实现方式

(一)修改应用程序清单文件(app.manifest)

在 Visual Studio 的舞台上,我们可以通过巧妙地操作应用程序清单文件(app.manifest),让程序在启动之时就向系统坚定地请求管理员权限。

首先,在解决方案资源管理器那整齐排列的项目文件中,找到我们的项目,然后轻轻右击它,在弹出的菜单中,精准地选择 “属性” 选项。这一步,就如同打开了项目的 “设置大门”。

进入项目属性页面后,我们要找到 “应用程序” 选项卡。在这个选项卡中,有一个名为 “资源” 的区域,在这里,我们能看到一个 “查看应用程序清单” 的按钮。这就像是通往清单文件世界的钥匙,点击它,即可打开应用程序清单文件(app.manifest)。

在清单文件那密密麻麻的代码中,我们需要找到标签。这个标签就像是程序权限的 “指挥官”,它目前可能设置为level=“asInvoker”,这意味着程序将以当前用户的权限悄无声息地运行。而我们的目标,是让它以管理员权限威风凛凛地启动。所以,我们要将其修改为level=“requireAdministrator” uiAccess=“false”。

修改完成后,别忘记保存这个文件。此时,我们的程序就如同穿上了 “管理员权限战甲”,每次启动时,Windows 系统都会弹出那个熟悉的用户账户控制(UAC)提示框,询问用户是否允许该程序以管理员权限运行。只要用户轻轻点击 “是”,程序就能顺利地以管理员权限开启它的征程,无阻地访问那些受限的系统资源。

(二)利用代码判断并重启程序

在 C# 的代码世界里,我们可以通过编写一段逻辑严密的代码,来实现对当前进程权限的精准判断。如果发现权限不足,就果断地以管理员身份重新启动程序,就像一位明智的指挥官,在面对资源不足的困境时,果断采取行动。

在 Program.cs 这个关键的文件中,我们开始施展代码魔法。首先,引入一系列必要的命名空间,如System、System.Diagnostics、System.Runtime.InteropServices和System.Windows.Forms。这些命名空间就像是一个个装满工具的百宝箱,为我们的代码编写提供了丰富的资源。

然后,在Program类中,我们对Main方法进行精心改造。在Main方法的起始部分,调用IsProcessElevated方法,这个方法就像是一位权限侦探,能够敏锐地判断当前进程是否已经具备管理员权限。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;internal static class Program
{[STAThread]static void Main(){if (!IsProcessElevated()){RelaunchAsAdmin();}else{Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new MainForm());}}private static bool IsProcessElevated(){WindowsIdentity identity = WindowsIdentity.GetCurrent();WindowsPrincipal principal = new WindowsPrincipal(identity);return principal.IsInRole(WindowsBuiltInRole.Administrator);}private static void RelaunchAsAdmin(){string currentExePath = Application.ExecutablePath;ShellExecute(0, "runas", currentExePath, "", "", 1);}[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern bool ShellExecute(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
}

IsProcessElevated方法的实现逻辑并不复杂。它首先通过WindowsIdentity.GetCurrent()获取当前用户的身份信息,就像是获取了一张用户的 “身份名片”。然后,利用这个身份信息创建一个WindowsPrincipal对象,这个对象就像是一个权限裁判,能够判断用户是否属于管理员角色。最后,通过调用principal.IsInRole(WindowsBuiltInRole.Administrator)来判断当前用户是否为管理员。如果返回true,那就说明当前进程已经拥有管理员权限;反之,则需要重新启动程序以获取管理员权限。

当IsProcessElevated方法返回false时,我们就会调用RelaunchAsAdmin方法。这个方法就像是一位 “重启大师”,它的任务是以管理员身份重新启动程序。在这个方法中,我们首先通过Application.ExecutablePath获取当前可执行文件的路径,这就像是找到了程序的 “家” 的位置。然后,调用ShellExecute函数,这个函数就像是一把神奇的钥匙,能够以管理员权限重新启动程序。在调用ShellExecute函数时,我们传入了一系列参数,包括窗口句柄(这里设置为 0,表示使用默认窗口)、操作(设置为 “runas”,表示以管理员身份运行)、文件名(即当前可执行文件的路径)、参数(这里为空)、目录(这里为空)和显示模式(设置为 1,表示正常显示窗口)。

在这个过程中,ShellExecute函数是一个关键的存在。它来自于shell32.dll动态链接库,我们通过DllImport特性将其引入到我们的代码中。这个函数就像是一座桥梁,连接着我们的 C# 代码和 Windows 系统的底层功能,让我们能够在代码中轻松地执行以管理员权限启动程序的操作。

通过这种方式,我们的程序就能够在启动时自动检查自身的权限。如果权限不足,就会自动以管理员身份重新启动,确保程序能够顺利地访问那些受限的系统资源,为用户提供更加稳定、强大的功能。

三、具体实现步骤详解

(一)修改应用程序清单文件的步骤

在 Visual Studio 中,修改应用程序清单文件(app.manifest)的操作虽然步骤不算繁琐,但每一步都至关重要。当我们打开项目后,需要在解决方案资源管理器中,精准地找到项目节点。这就像是在图书馆中找到特定的书架,而这个书架就是我们的项目。接着,右键点击该项目,在弹出的菜单中,我们要选择 “属性” 选项。这个操作就如同打开了项目的 “设置大门”,让我们能够进入到项目的各种配置选项中。

进入项目属性页面后,我们的目光要聚焦在 “安全性” 选项卡上。在这里,有一个名为 “启用 ClickOnce 安全设置” 的选项,它就像是一个隐藏的开关,控制着清单文件的生成。我们先勾选这个选项,这一步是为了让 Visual Studio 生成 app.manifest 文件。就像按下相机的快门,让相机生成照片一样,我们通过勾选这个选项,让 Visual Studio 生成我们需要的清单文件。

生成 app.manifest 文件后,我们需要对其进行深入的修改。在解决方案资源管理器中,找到这个刚刚生成的 app.manifest 文件,它就像是一份珍贵的文档,记录着程序的各种配置信息。双击打开它,我们会看到一系列的 XML 代码。在这些代码中,我们要找到标签,这个标签就像是程序权限的 “指挥官”,它目前可能设置为level=“asInvoker”,这意味着程序将以当前用户的权限悄无声息地运行。而我们的目标,是让它以管理员权限威风凛凛地启动。所以,我们要将其修改为level=“requireAdministrator” uiAccess=“false”。

修改完成后,我们还需要取消对 “启用 ClickOnce 安全设置” 的勾选。这一步就像是在完成拍照后,将相机的某些临时设置恢复原状一样。取消勾选是为了避免一些不必要的设置冲突,确保我们对清单文件的修改能够顺利生效。最后,别忘了保存所有的更改,就像保存一幅精心绘制的画作一样,我们保存这些修改,让程序能够按照我们的期望,在启动时请求管理员权限。

(二)代码实现的详细解析

在 Program.cs 文件中,权限判断和重启程序的代码就像是一个精密的仪器,每一行都有着独特的功能和作用。我们先看IsProcessElevated方法,它的使命是判断当前进程是否具有管理员权限。

private static bool IsProcessElevated()
{WindowsIdentity identity = WindowsIdentity.GetCurrent();WindowsPrincipal principal = new WindowsPrincipal(identity);return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

WindowsIdentity.GetCurrent()这行代码,就像是一把神奇的钥匙,它能够获取当前正在运行的进程所关联的用户身份信息。通过这把钥匙,我们打开了了解当前用户身份的大门。接着,利用获取到的WindowsIdentity对象,创建一个WindowsPrincipal对象。这个WindowsPrincipal对象就像是一个经验丰富的裁判,它能够根据用户的身份信息,判断用户是否属于特定的角色。在我们的场景中,就是判断用户是否属于管理员角色。最后,通过调用principal.IsInRole(WindowsBuiltInRole.Administrator)方法,这个裁判就会给出最终的裁决:如果当前用户属于管理员角色,就返回true,表示当前进程具有管理员权限;反之,则返回false,说明当前进程需要提升权限。

当IsProcessElevated方法返回false时,就意味着当前进程权限不足,需要以管理员身份重新启动程序。这时候,RelaunchAsAdmin方法就开始发挥作用了。

private static void RelaunchAsAdmin()
{string currentExePath = Application.ExecutablePath;ShellExecute(0, "runas", currentExePath, "", "", 1);
}

在RelaunchAsAdmin方法中,首先通过Application.ExecutablePath获取当前可执行文件的路径。这就像是找到了程序的 “家” 的位置,知道了程序在哪里。然后,调用ShellExecute函数。这个函数就像是一个强大的使者,能够与 Windows 系统进行沟通,请求以管理员身份重新启动指定的程序。在调用ShellExecute函数时,传入的参数0表示使用默认的窗口句柄,就像是使用默认的 “窗口通道” 来与系统进行交互;"runas"是操作参数,它明确地告诉系统,我们要以管理员身份运行程序,这就像是给系统下达了一个明确的指令;currentExePath则是要重新启动的可执行文件的路径,也就是我们刚刚找到的程序的 “家” 的位置;后面两个空字符串分别表示不传递参数和使用当前目录,这就像是在告诉系统,我们不需要额外的参数,也就在当前的目录下进行操作;最后的参数1表示以正常的显示模式启动程序,让程序的窗口以正常的方式展示在用户面前。

通过这样的代码实现,我们的程序就能够在启动时自动检测自身的权限。如果发现权限不足,就会果断地以管理员身份重新启动,确保程序能够顺利地访问那些受限的系统资源,为用户提供更加稳定、强大的功能。

四、案例实战

为了更直观地感受以管理员方式启动程序的实际效果,我们来构建一个具体的案例。假设我们要开发一个程序,其核心功能是向系统文件夹中写入一个重要的配置文件。这个系统文件夹由于其特殊性,对访问权限有着严格的限制,普通用户权限根本无法触及。

首先,我们着手创建一个简单的 Windows Forms 应用程序。在 Visual Studio 这个强大的开发工具中,新建一个 Windows Forms App (.NET Framework) 项目,并为它取一个富有意义的名字,比如 “SystemWriterApp”。

接着,在项目的 “MainForm.cs” 文件所对应的设计视图里,精心添加一个按钮控件。这个按钮就像是程序的 “启动引擎”,当用户点击它时,程序将尝试执行写入操作。我们将按钮的 “Text” 属性设置为 “写入系统文件夹”,这样用户一眼就能明白这个按钮的功能。

然后,双击这个按钮,进入到代码编写的世界,为其编写点击事件处理程序。在这个处理程序中,我们将实现向系统文件夹写入文件的核心逻辑。

private void button1_Click(object sender, EventArgs e)
{string systemFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.System);string filePath = Path.Combine(systemFolderPath, "config.txt");try{using (StreamWriter writer = new StreamWriter(filePath)){writer.WriteLine("这是由具有管理员权限的程序写入的配置信息。");}MessageBox.Show("文件写入成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}catch (Exception ex){MessageBox.Show($"文件写入失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}

在这段代码中,我们首先通过Environment.GetFolderPath(Environment.SpecialFolder.System)获取系统文件夹的路径,这就像是找到了系统文件夹的 “精确地址”。然后,利用Path.Combine方法将系统文件夹路径和要创建的文件名 “config.txt” 组合成完整的文件路径。

接下来,使用StreamWriter来尝试写入文件。在这个过程中,我们将一段重要的配置信息写入到文件中。如果写入成功,就通过MessageBox.Show弹出一个提示框,告诉用户 “文件写入成功!”,让用户能够及时知晓操作结果。

然而,程序运行的道路并非总是一帆风顺。如果在写入过程中遭遇权限不足等异常情况,catch块就会发挥作用。它会捕获这个异常,并通过MessageBox.Show弹出一个错误提示框,详细地告知用户 “文件写入失败” 的具体原因,也就是异常的消息内容。这样,用户就能清楚地了解到问题所在,方便进行后续的排查和处理。

到这里,程序的基本功能已经初步实现。但由于系统文件夹的访问权限限制,若不以管理员权限运行,程序在执行写入操作时必然会失败。所以,我们需要应用前面介绍的方法,让程序能够以管理员方式启动。

如果选择修改应用程序清单文件(app.manifest)的方法,我们按照之前讲解的步骤,在项目属性中找到并修改标签,将其设置为level=“requireAdministrator” uiAccess=“false”。这样,当用户启动程序时,系统就会弹出 UAC 提示框,询问用户是否允许程序以管理员权限运行。只要用户点击 “是”,程序就能顺利地获取管理员权限,进而成功地将文件写入到系统文件夹中。

若采用代码判断并重启程序的方式,我们在Program.cs文件中添加相应的权限判断和重启逻辑。就像之前展示的代码那样,通过IsProcessElevated方法判断当前进程是否具有管理员权限。如果权限不足,就调用RelaunchAsAdmin方法,以管理员身份重新启动程序。这样,程序在启动时就能自动检查权限,并在必要时以管理员权限运行,确保写入系统文件夹的操作能够顺利完成。

通过这个案例,我们可以清晰地看到以管理员方式启动程序在实际开发中的重要性和具体应用场景。它能够帮助我们突破权限限制,实现对系统资源的有效访问和操作,为用户提供更加完善和强大的功能。

五、注意事项

(一)安全性考量

在程序的权限管理领域,安全性无疑是重中之重。我们必须时刻牢记,管理员权限犹如一把双刃剑,虽然它赋予了程序强大的能力,能够访问和操作那些受保护的系统资源,但同时也带来了巨大的安全风险。一旦权限被恶意利用,后果不堪设想。

因此,在开发过程中,我们要始终秉持谨慎的态度,严格遵循最小权限原则。这意味着,只有当程序真正需要执行那些必须依赖管理员权限才能完成的关键操作时,才向用户请求管理员权限。比如,程序需要修改系统的核心配置文件,或者对系统服务进行深度的管理和控制,这些场景下请求管理员权限是合理且必要的。

然而,如果只是一些普通的文件读写操作,或者对用户个人数据的处理,这些操作完全可以在普通用户权限下安全、顺利地完成,就绝不能随意请求管理员权限。因为过多或不必要的权限请求,不仅会增加程序被攻击的风险,还可能让用户对程序的安全性产生疑虑,从而降低用户对程序的信任度。

(二)用户体验优化

用户体验是衡量一个程序优劣的重要标准,而频繁的 UAC 提示就像是在用户使用程序的道路上设置了一个个 “路障”,会极大地影响用户体验。想象一下,用户在使用程序的过程中,不断地被 UAC 提示框打断,每次都需要手动点击确认,这无疑会让用户感到烦躁和厌烦。

为了避免这种情况的发生,我们要尽可能地减少不必要的权限请求。在程序设计之初,就要进行全面而细致的规划,对程序的功能模块进行深入分析,明确哪些操作真正需要管理员权限,哪些可以在普通权限下实现。对于一些可以通过其他方式间接实现的功能,尽量避免使用管理员权限。

同时,在必须请求管理员权限时,我们也要通过巧妙的设计,提升用户体验。比如,在请求权限之前,向用户清晰地解释为什么需要这些权限,以及这些权限将如何帮助程序更好地为用户服务。可以通过弹出一个友好的提示框,用简洁明了的语言向用户说明情况,让用户能够理解并信任我们的程序。这样,当 UAC 提示框出现时,用户就不会感到突兀和困惑,从而更愿意配合我们的操作。

(三)兼容性问题

在 Windows 系统的广袤世界里,存在着各种各样的版本,从早期的 Windows XP,到如今的 Windows 11,每个版本都有其独特的特点和差异。而且,不同地区的用户使用的语言环境也各不相同。这就要求我们在开发程序时,必须高度重视兼容性问题,确保程序在各种 Windows 版本和语言环境下都能稳定、正常地运行。

在以管理员方式启动程序的实现过程中,兼容性问题尤为关键。不同版本的 Windows 系统,对 UAC 的设置和处理方式可能存在差异,这可能会导致我们的程序在某些版本上无法正常请求管理员权限,或者出现权限提升失败的情况。

为了应对这一挑战,我们要进行充分的测试。在开发过程中,尽可能地收集各种不同版本的 Windows 系统,包括 32 位和 64 位系统,在这些系统上对程序进行全面的测试。检查程序在不同系统上的权限请求是否正常,UAC 提示是否能够正确显示,程序在获得管理员权限后是否能够正常执行各项操作。

同时,还要考虑到不同语言环境的影响。确保程序在各种语言环境下,UAC 提示框和相关的提示信息都能够正确显示,并且不会出现乱码等问题。可以通过使用资源文件等方式,对不同语言环境下的文本进行统一管理和处理,从而保证程序在全球范围内的兼容性。

六、总结

在 C# 开发的领域中,以管理员方式启动程序,无疑是一把能够解锁众多强大功能的 “万能钥匙”。通过对应用程序清单文件的精细调整,以及编写逻辑缜密的代码来实现权限判断与重启,我们为程序赋予了访问系统关键资源的 “特殊权限”。这不仅极大地拓展了程序的功能边界,让我们能够开发出诸如系统管理工具、深度优化软件等具有强大功能的应用程序,还为解决各类复杂的实际问题提供了坚实有力的技术支持。

在实际的开发过程中,我们必须时刻将安全性、用户体验以及兼容性等重要因素牢记于心。合理且谨慎地使用管理员权限,就如同为程序筑牢了一道坚固的安全防线,有效避免了潜在的安全风险;优化用户体验,能够让用户在使用程序时感受到流畅与便捷,增强用户对程序的喜爱和忠诚度;而确保程序在各种 Windows 版本和语言环境下的兼容性,则如同为程序插上了翅膀,使其能够在更广阔的天地中自由翱翔,触达更多的用户群体。

我衷心地希望,通过本文对 C# 以管理员方式启动程序的全面且深入的介绍,能够为各位开发者在实际项目中提供切实可行的帮助和清晰明确的指导。让我们在 C# 开发的道路上,充分利用这一强大的技术,不断创新,不断突破,开发出更多功能强大、稳定可靠且用户体验极佳的优秀应用程序,为 Windows 应用程序的发展贡献自己的一份力量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/67615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

要获取本地的公网 IP 地址(curl ifconfig.me)

文章目录 通过命令行查询(适用于 Linux/Mac/Windows)Linux/MacWindows 注意事项 要获取本地的公网 IP 地址,可以通过以下简单的方法: 通过命令行查询(适用于 Linux/Mac/Windows) Linux/Mac 打开终端。输入…

MySQL 数据库 UDF 提权

免责声明 本博客文章仅供教育和研究目的使用。本文中提到的所有信息和技术均基于公开来源和合法获取的知识。本文不鼓励或支持任何非法活动,包括但不限于未经授权访问计算机系统、网络或数据。 作者对于读者使用本文中的信息所导致的任何直接或间接后果不承担任何责…

VUE3 vite下的axios跨域

在使用 Vite 开发时,如果你的前端项目需要请求后端 API,且后端和前端不在同一个域上,可能会遇到跨域问题。跨域是指浏览器出于安全考虑,阻止了前端网页向不同源(域名、协议、端口)发送请求。 解决跨域问题…

【数据分享】1929-2024年全球站点的逐年平均气温数据(Shp\Excel\无需转发)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标,其中又以气温指标最为常用!说到气温数据,最详细的气温数据是具体到气象监测站点的气温数据!本次我们为大家带来的就是具体到气象监…

rust学习-函数的定义与使用

rust学习-函数的定义与使用 1. 函数的基本定义2. 函数的参数多个参数 3. 返回值提前返回 4. 函数调用5. 函数的所有权和借用传递所有权借用 6. 函数作为参数和返回值函数作为参数函数作为返回值 7. 泛型函数8. 函数注释(文档注释) 1. 函数的基本定义 在R…

【Linux 源码】内核态到用户态

文章目录 1. 由来2. 流程图3. 中断3.1 概念3.2 8259A芯片3.4 中断时的栈处理3.4.1 相同特权级3.4.2 不同特权级 3.5 中断流程3.6 定位中断程序3.7 中断流程步骤总结 4. 源码4.1 move_to_user_mode4.2 0号进程4.3 TSS和LDT在GDT表排布4.4 ldt中的0x17栈段 5. 总结 1. 由来 ​ 首…

雷电9最新版安装Magisk+LSPosd(新手速通)

大家好啊!我是NiJiMingCheng 我的博客:NiJiMingCheng 在安卓系统的定制与拓展过程中,获取 ROOT 权限以及安装各类框架是进阶玩家常用的操作,这可以帮助我们实现更多系统层面的个性化功能。今天,我将为大家详细介绍如何…

【vim】vim编辑器如何设置行号

vim编辑器如何设置行号 一、**临时设置行号**二、永久设置行号2.1. **用户配置文件方式(针对当前用户)**2.2. **全局配置文件方式(谨慎使用,会影响所有用户)** 在Vim中设置行号有以下两种常见的方法: 一、…

《Linux服务与安全管理》| 邮件服务器安装和配置

《Linux服务与安全管理》| 邮件服务器安装和配置 目录 《Linux服务与安全管理》| 邮件服务器安装和配置 1.在Server01上安装dns、postfix、dovecot和telnet,并启动 2.在Server01上配置DNS服务器,设置MX资源记录 3.在server1上…

基于 K-Means 聚类分析实现人脸照片的快速分类

注:本文在创作过程中得到了 ChatGPT、DeepSeek、Kimi 的智能辅助支持,由作者本人完成最终审阅。 在 “视频是不能 P 的” 系列文章中,博主曾先后分享过人脸检测、人脸识别等相关主题的内容。今天,博主想和大家讨论的是人脸分类问题。你是否曾在人群中认错人,或是盯着熟人的…

计算机毕业设计Python电商品推荐系统 商品比价系统 电商比价系统 商品可视化 商品爬虫 机器学习 深度学习 京东爬虫 国美爬虫 淘宝爬虫 大数据

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

【银河麒麟高级服务器操作系统】业务访问慢网卡丢包现象分析及处理过程

了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:product.kylinos.cn 开发者专区:developer.kylinos.cn 文档中心:document.kylinos.cn 交流论坛:forum.kylinos.cn 服务器环境以及配置 【内核版本…

鸿蒙开发中的骨架图:提升用户体验的关键一环

大家好,我是小 z,今天要给大家分享一个提升用户体验的超实用技巧 —— 骨架图🎯 文章目录 一、什么是骨架图二、骨架图的作用三、鸿蒙开发中实现骨架图的方法1. 利用 opacity 奠定视觉基础2. animateTo 驱动动态变化3. 二者协同触发与展示 四…

owasp SQL 手工注入 - 02 (技巧)

SQL 注入分为: 布尔注入,还有union 注入,布尔注入是指" 或“ 和”,这个注入,写成语句就是OR 11 , and 这种语句。 下面重点说一下union 注入的原理: 1: 先看两个表union 的结果: mysql> select user,passwor…

第16章:Python TDD实现多币种货币运算

写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…

leetcode刷题记录(七十三)——543. 二叉树的直径

(一)问题描述 543. 二叉树的直径 - 力扣(LeetCode)543. 二叉树的直径 - 给你一棵二叉树的根节点,返回该树的 直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 r…

【esp32小程序】小程序篇02——连接git

一、创建仓库 进入gitee官网,登录(如果没有gitee账号的就自行注册一下)。 点击号-->新建仓库 填写好必填信息,然后点击“创建” 二、微信开发者工具配置 在微信开发者工具打开我们的项目。按下面的步骤依次点击 三、验证 点…

Linux的基本指令(上) -- 0基础入门

目录 知识点引入 基本指令 ls指令 pwd 命令 cd 指令 touch 指令 stat指令 mkdir 指令 tree指令 rmdir 指令 rm 命令 man 指令 which 指令 alias 指令 echo指令 输出重定向: > 追加重定向:>> cp 指令 知识点引入 1. Linux中路径用 / 作为路径分隔…

Java测试开发平台搭建(九)前端

1. 搭建前端vue环境 Vue3 安装 | 菜鸟教程 2. 创建项目 1.进入ui vue ui 2. create项目 3. 成功之后添加插件: cli-plugin-router vue-cli-plugin-vuetify 4. 添加依赖 axios 5. 点击任务开始运行 如果报错: 修改vue.config.jsconst { defineConfig }…

基于SpringBoot+Vue的智慧动物园管理系统的设计与实现

获取源码:基于SpringBootVue智慧动物园系统设计与实现: 后台和用户前台。后台包括首页、员工管理、考勤管理、部门管理、角色管理、审核管理、动物管理、演出管理、园区管理、园区设施维修、饲养管理、行为观察管理、疫苗管理、看护管理、个人中心、票务管理、收入管…