如何从非提升的 c# 程序更改系统时间
Posted
技术标签:
【中文标题】如何从非提升的 c# 程序更改系统时间【英文标题】:How do I change system time from a non elevated c# program 【发布时间】:2021-01-18 16:21:36 【问题描述】:我再次需要你的帮助:)
我想做的事: 我有一个 c# 程序,它以普通用户权限运行 - 无法提高 - 我想从该程序更改系统日期(而不是时间)。
[编辑] 更具体一点:我确实有可以嵌入到程序中的管理员凭据(哎呀,我知道),但我想避免 UAC 提示.
当我从 Visual Studio 外部启动 cmd
并尝试更改日期时,它会因“缺少客户端权限”而失败(大致翻译自德语)。当我以管理员身份启动 cmd
时,确认 UAC 提示相同的命令成功。
我是在家写作,所以目前无法提供运行代码。但是我所有的尝试都编译并运行没有错误,但日期没有改变。
我尝试过的:
创建了一个Process
实例,将管理员凭据应用到ProcessStartInfo
,将FileName
设置为c:\windows\system32\cmd.exe
,并将参数设置为/C date thedate
。我重定向了StandardOutput
和StandardError
,执行后StandardError
包含与上述相同的消息:“缺少客户端权限”
我已经修改了这个示例MSDN: WindowsIdentity.Impersonate,使用带有AdvAPI32.LogonUser
的PInvoke 来提高权限,并使用Kernel32.SetSystemTime
来更改系统时间。 AdvAPI32.LogonUser
成功,WindowsIdentity.GetCurrent().Name
返回管理员名称,但调用 Kernel32.SetSystemTime
失败并显示“缺少客户端权限”。
我已经尝试打开当前进程AdvApi32.OpenCurrentProcess
并使用AdvApi32.AdjustTokenPrivileges
按照此示例***: Change system time programmaticaly using datetimepeaker 调整权限,代码运行完全正常,但Kernel32.SetSystemTime
失败...
[编辑] 解决方案: 我最终编写了一个带有嵌入式 app.manifest 的小程序,请求管理员权限。这个应用程序是从主程序调用的,所以它仍然可以由普通用户运行。
【问题讨论】:
我不明白你的问题。当您需要某些任务的权限时,您肯定必须提供一些权限。或者换句话说:您需要管理员权限来更改系统日期。 这能回答你的问题吗? How do you do Impersonation in .NET? 您需要特权。在 Windows 中关闭 UAC 以删除弹出窗口并创建一个快捷方式以始终以管理员身份运行。 @HimBromBeere 我确实有管理员凭据,我用它们来创建进程/模拟但似乎没有 app.manifest/UAC 提示程序,将使用一个不允许的受限令牌我来更改日期。 @Charlieface 感谢您的链接。代码更容易阅读,但来自 MSDN 的代码确实有效。WindowsIdentity.GetCurrent().Name
确实确认我是管理员,但即使这样也不允许我更改日期。
【参考方案1】:
一旦启动,就无法更改进程的权限。原始进程必须以提升的权限启动另一个进程。第二个进程实际上可以是同一个 .exe 文件,但带有一个命令参数,告诉进程执行一些小操作并立即退出。
如another question 中所述,要以提升的权限启动进程,请使用 Process.Start,但使用 .Verb = "runas"。这当然会导致 UAC 提示弹出,如果它在机器上启用。必须至少显示一个 UAC 提示,因为如果有这种防御机制,UAC 提示就是重点。
如果您想将许多 UAC 提示减少到只有一个,那么您可以将原始应用设置为以管理员身份启动(原始进程启动时显示 UAC 提示)并且只有一个进程。或者在原始进程和提升的进程之间进行一些进程间通信,使提升的进程只启动一次,并在原始进程结束时完成。在第二种情况下,UAC 提示显示第一次需要它。
【讨论】:
我已经投了赞成票,因为它是我最终得到的解决方案,但它不是我正在寻找的解决方案(在没有 UAC 提示的情况下以管理员身份进行身份验证) - 但它似乎是唯一的出路。 【参考方案2】:请问您为什么需要从非特权应用程序更改系统时间?
如果要影响其他应用程序,那么您将需要管理员权限,因为日期时间对于许多其他应用程序来说是如此重要的系统功能。但是,如果您只需要调整应用程序中的日期,那么我建议您创建自己的日期/时间提供程序,该提供程序可以将日期偏移量返回到您在应用程序中所需的日期。
例如。
public DateTime GetDateWithOffset(int daysToOffset)
return DateTime.UtcNow.AddDays(daysToOffset);
【讨论】:
以上是关于如何从非提升的 c# 程序更改系统时间的主要内容,如果未能解决你的问题,请参考以下文章