当前位置: 首页 > news >正文

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 应用程序的发展贡献自己的一份力量。

相关文章:

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

引言 在 Windows 应用程序开发的领域中,C# 语言凭借其强大的功能和广泛的适用性,被众多开发者所青睐。然而,在实际的开发过程里,我们常常会遭遇这样的情况:程序需要访问特定的系统资源,像是系统文件夹、注…...

CSS:语法、样式表、选择器

目录 一、语法 二、创建 外部样式表 内部样式表 内联样式 三、选择器 ID选择器 类选择器 伪类选择器 :hover a:link a:active a:visited 属性选择器 伪元素选择器 ::first-letter ::first-line ::selection ::placeholder ::before 和::after 通配选择器 标…...

python轻量级框架-flask

简述 Flask 是 Python 生态圈中一个基于 Python 的Web 框架。其轻量、模块化和易于扩展的特点导致其被广泛使用,适合快速开发 Web 应用以及构建小型到中型项目。它提供了开发 Web 应用最基础的工具和组件。之所以称为微框架,是因为它与一些大型 Web 框架…...

SQL和MySQL以及DAX的日期表生成?数字型日期?将生成的日期表插入到临时表或者实体表中

几种生成日期表的方法 如何用SQL语句生成日期表呢? 如何用MySQL语句生成日期表呢? 如何用DAX语句生成日期表呢? 1. MySQL生成日期表 1.1 日期格式:yyyy-MM-dd 字符型 2024-01-02 -- 生成日期表 WITH RECURSIVE temp_dateTable …...

文件下载时利用redis的队列模式顺序下载文件,防止多文件任务下载导致OOM

1、controller层控制 Resourceprivate RedissonClient redissonClient;Slf4j Service public class CustomerSettlementExportServiceImpl implements ICustomerSettlementExportService { /*** 文件加入队列顺序导出** param pubFileExportList 参数* return 结果*/public Aja…...

第13章:Python TDD完善货币加法运算(二)

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

两份PDF文档,如何比对差异,快速定位不同之处?

PDF文档比对是通过专门的工具或软件,自动检测两个PDF文件之间的差异,并以可视化的方式展示出来。这些差异可能包括文本内容的修改、图像的变化、表格数据的调整、格式的改变等。比对工具通常会标记出新增、删除或修改的部分,帮助用户快速定位…...

ESP-Skainet语音唤醒技术,设备高效语音识别方案,个性化交互应用

在当今数字化、智能化飞速发展的时代,物联网(IoT)与人工智能(AI)的深度融合正在重塑我们的生活和工作方式。 在智能家居的生态系统中,语音唤醒技术不仅能够为用户提供个性化的服务,还能通过定制…...

地图:nuxt3高德地图简单使用 / nuxt2 + amap

一、官方网站 JS API 安全密钥使用-基础-进阶教程-地图 JS API 2.0 | 高德地图API 二、使用 2.1、创建应用 2.2、添加key&#xff0c;得到key值 2.3、nuxt3项目 引入amap 2.4、pages/map.vue <template><div class"container"><div id"map-co…...

走进DevOps:让开发与运维齐头并进

引言&#xff1a;开发与运维的“世纪和解” 还记得那些年&#xff0c;开发人员总是埋头写代码&#xff0c;然后甩手交给运维去部署&#xff0c;仿佛是把热山芋扔给别人。而运维呢&#xff0c;总是默默承受着系统崩溃、服务停机的风险&#xff0c;直到某一天他们终于忍不住咆哮&…...

力扣动态规划-5【算法学习day.99】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…...

LLM(3) : 浏览器录制16K的音频并上传到后端

可被阿里云[qwen-audio-asr]大模型识别 HTML <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>录音并上传</title></head><body><button id"recordButton">开始/停…...

PyTorch使用教程(13)-一文搞定模型的可视化和训练过程监控

一、简介 在现代深度学习的研究和开发中&#xff0c;模型的可视化和监控是不可或缺的一部分。PyTorch&#xff0c;作为一个流行的深度学习框架&#xff0c;通过其丰富的生态系统提供了多种工具来满足这一需求。其中&#xff0c;torch.utils.tensorboard 是一个强大的接口&…...

服务器日志自动上传到阿里云OSS备份

背景 公司服务器磁盘空间有限&#xff0c;只能存近15天日志&#xff0c;但是有时需要查看几个月前的日志&#xff0c;需要将服务器日志定时备份到某个地方&#xff0c;需要查询的时候有地方可查。 针对这个问题&#xff0c;想到3个解决方法&#xff1a; 1、买一个配置比较低…...

树莓派学习

飞书&#xff1a;https://hi06pny1nlj.feishu.cn/docx/GYsMdth7ooNlbJx8zBDcdbcPnec?fromfrom_copylink csdn&#xff1a;https://blog.csdn.net/qq_41685627/article/details/145250576 基础工作 安装和部署 1.1 树莓派三种连接电脑的方式 https://blog.csdn.net/weixin…...

NestJS中实现注入多个实现了同一个接口的Service

在NestJS中有一种场景&#xff0c;在注入的时候需要将多个实现了同一个接口的service都注入到系统里&#xff0c;而NestJS中默认时没有这种注入&#xff0c;此时我们可以使用一个变通的provider来实现这一功能。 看下面例子&#xff0c;假定我们有一个OSService接口&#xff0…...

Qt按钮美化教程

前言 Qt按钮美化主要有三种方式&#xff1a;QSS、属性和自绘 QSS 字体大小 font-size: 18px;文字颜色 color: white;背景颜色 background-color: rgb(10,88,163); 按钮边框 border: 2px solid rgb(114,188,51);文字对齐 text-align: left;左侧内边距 padding-left: 10…...

基于单片机的多功能蓝牙语音智能台灯(论文+源码)

1总体方案设计 通过需求分析&#xff0c;本设计多功能蓝牙语音智能台灯的系统框图如图2.1所示&#xff0c;系统架构包括主控制器STM32F103单片机、HC-06蓝牙通信模块、LU-ASR01语音识别模块、OLED液晶、LED灯、按键等器件&#xff0c;在使用时用户可以通过手机APP、语音识别、…...

第15章:Python TDD应对货币类开发变化(二)

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

算法随笔_13: 有效三角形的个数

上一篇:算法随笔_12:最短无序子数组-CSDN博客 题目描述如下: 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 示例 1: 输入: nums [2,2,3,4] 输出: 3 解释:有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使用第二个 2) 2,2,3 算法…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...