获取Windows计算机VB.NET的登录用户

时间:2014-05-15 08:44:40

标签: vb.net

我的程序取决于根据登录的用户而变化的信息。例如AppData的位置。我的程序还需要管理权限。如果我以管理员身份运行程序,程序会认为管理员是当前登录的用户。

我的“解决方案”:创建第二个程序作为控制台运行。它作为标准用户运行,将信息放入变量以正确识别当前用户。然后它将主程序从Resources保存到磁盘,启动它,然后通过Arguments传递这些变量。

问题:我必须先构建程序两次才能测试它。这非常烦人。

虽然我的解决方案有效,但我已经厌倦了。有没有其他方法可以让当前(活动)登录用户?我尝试过 SystemInformation.UserName.ToString My.User.Name.ToString 。两者都给错了用户。

编辑: System.Security.Principal.WindowsIdentity.GetCurrent()。名称不起作用。

建议的解决方案:我不会在我的主程序之前运行程序来收集信息,而是尝试在我的主程序运行的同时运行该程序。我的主程序将等待信息被发回,然后恢复。这样,我不必一直双重构建。

4 个答案:

答案 0 :(得分:1)

这个答案可能会引起争议,因为它并没有严格回答标题中的问题。但是问题仍然是正确的答案。明确提出的问题是所谓的XY problem。您遇到了问题,找到了可能的解决方案,然后在实施该解决方案时遇到问题,因此您已经寻求帮助。问题在于,你脑海中想出的解决方案并不正确。

  

我的程序取决于根据登录用户而变化的信息。例如AppData的位置。

这很正常。但是,您不会通过检测登录的用户来解决此问题。无论如何,这对您没有任何好处。假设您知道用户的名称:您现在如何使用它来找出AppData文件夹?我假设您将尝试根据您对Windows默认安装中文件夹位置的了解手动撰写路径:C:\Users\<the user name>\AppData\。但是你只是犯了错误。如果用户已将其配置文件目录映射到其他位置,会发生什么?如果用户名与Users目录中的目录名称不匹配(例如,如果管理员帐户已重命名),该怎么办?

这个问题的真正解决方案完全简单。您只需向Windows询问AppData文件夹的路径即可。让操作系统完成其工作,跟踪登录用户。

通常,在Windows中,您可以调用SHGetKnownFolderPath函数或其道德等效函数。在.NET Framework中,该功能由Environment.GetFolderPath method包装。简单,保证是正确的。

您需要指定SpecialFolder.CommonApplicationData(所有用户的AppData文件夹),SpecialFolder.ApplicationData(当前用户的漫游AppData文件夹)或SpecialFolder.LocalApplicationData(非漫游)当前用户的AppData文件夹。)

  

我的程序还需要管理权限。如果我以管理员身份运行程序,程序会认为管理员是当前登录的用户。

因为它是。如果您以管理员身份运行程序,则出于所有意图和目的,程序将以管理员身份运行。这意味着返回Administrator作为当前用户的名称,返回管理员的AppData文件夹,依此类推。这是非常合乎逻辑的,它使程序能够执行特定于管理员的事情。

但除此之外,拥有一个需要管理权限的整个应用程序是不好的做法(除了最不寻常的情况之外)。通常,真正需要管理权限的应用程序只执行一个或两个操作。例如,我写了一点实用工具。它的基本功能都不需要管理权限,但它具有安装自身的功能,以便在启动时为所有用户启动。显然,这需要管理权限,但这只是一次性的专业功能。您不希望整个应用仅需要针对该专用功能的管理权限。如果当前用户无法获得管理员权限,该怎么办?他们应该仍然可以使用该软件,只需禁用管理员专用功能或无法访问。

这适用于Windows的流程提升模型。暂时无法提升当前流程。您必须启动一个新的提升进程,执行需要管理权限的任何操作,然后退出该进程。我已经写了关于如何做到这一点的详细说明here。当然,它们都在C#中,但很容易翻译成VB.NET。

  

我可以通过其他方式获取当前(活动)登录用户吗?我已经尝试过SystemInformation.UserName.ToString和My.User.Name.ToString。两者都给错了用户。

就像我上面所说的那样,信息不是&#34;错误&#34;。你自己说过:他们正在回归现在的(活跃的)&#34;用户:管理员。您请求将应用程序运行的那个。

根据我上面提出的解决方案,您的应用程序正常运行,不会以管理员身份运行。这样可以提高安全性,并确保您获得适用于当前登录用户的信息。当您需要执行需要管理员权限的操作时,您将关闭第二个提升的进程,执行工作,然后退出该进程。升级过程将作为管理员,用于所有意图和目的,这几乎总是你想要的。

对于它的价值,我经常会看到像你这样的人尝试编写安装程序的问题(不要这样做,只需使用已有的许多优秀安装程序之一)。显然,他们的安装程序需要管理员权限,因此他们将其设置为在启动时请求提升。到现在为止还挺好。除了他们想要在安装期间将数据写入特定用户的AppData文件夹。现在他们遇到了问题,因为(1)他们无法获得该路径,并且(2)甚至可能 其他已登录用户。该解决方案以及Windows徽标指南正式推荐的解决方案是在首次运行时执行此类初始化。换句话说,第一次安装的应用程序由普通用户运行。然后你得到你期望的AppData文件夹。

答案 1 :(得分:0)

我相信Environment.UserName会获取当前登录的用户(而不是&#39;运行为&#39;用户)。也可以按如下方式查询WMI:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];

这来自this SO question

答案 2 :(得分:0)

此处找到的解决方案Detect Current Logged on User with VB.Netgetting username in vb.net

我还需要编写应用程序直接转到我已经拥有url的本地路径。 c:\ users \ username \ appdata \ packages和&#34; environment.username&#34;适合我。我刚刚声明了一个变量来保存它

答案 3 :(得分:0)

我的供稿中弹出了一个经常被问到的问题,我想尝试一下“回答”自己的问题。

背景故事是我试图创建一个注册表调整实用程序(部分作为自学VB的一种方式)。当时我对编程非常陌生。我会选中一个框并立即将其应用。其中一些调整是HKEY_CURRENT_USER。至少对于Windows 10,如果您在本地Administrators组中并且进行了提升,则它仍具有运行用户身份。也许UAC在Windows 7上的表现有所不同,也许我在运行两个帐户(用户和管理员)。我相信我正在尝试解决一个边缘案件。

无论哪种方式,如果用户将其他用户提升(或运行),显然它将以该用户身份列出进程。您可以通过以下几种方式来检测交互式用户:

  • 事件日志:事件ID 4624(Logon_Type 2)和4648都将列出试图提升的用户。它不会列出实际程序,可能是svchost.exe。如果启用了进程创建(GPO),则可以将事件ID 4688与产生的新进程相关联。
  • 执行路径:如果位于用户的文件夹中(也称为C:\ Users \ myuser),则它可能是用户尝试提升的一个很好的指示(特别是如果您枚举本地Administrators并且发现该用户是常规用户) 。
  • 最小特权:我相信我最终建议这样做。以交互用户身份运行程序。仅在必要时提升。如果您可以控制重定向,则可以传递用户名。
  • 注册表:如果是特定于用户的,则点击HKEY_USER可能适用(以避免重定向)。
  • 检查资源管理器/登录进程:如果用户以交互方式登录,则资源管理器进程应正在运行。如果它们被锁定,则还应该有一个登录过程。
  • query /user:此命令不容易解析。但是,它不受海拔高度的影响(它始终了解交互式用户)。
  • interactive user:基于https://serverfault.com/questions/188115/what-is-windows-interactive-user,系统会自动为用户分配特殊身份。我还没有弄清楚,但是也许有一种方法可以枚举它们以确定用户是否是交互式的。

以上所有内容不一定都可以防弹,也不一定适合所有人。您可能需要一起使用多个以确保正确使用,尤其是在您的需求至关重要的情况下。上面的内容还假设您具有实施每个单独的知识。 (例如,我如何使用C#从“事件日志”中读取信息。)有足够的指南和线程,尤其是关于SO的指南和线程将对此进行解释。我认为没有必要对此进行重新讨论,尤其是考虑到我的问题与系统管理员的关系比什么都重要。