防止程序在启动时被 Windows 克隆

Posted

技术标签:

【中文标题】防止程序在启动时被 Windows 克隆【英文标题】:Prevent the program from being cloned by Windows at startup 【发布时间】:2021-07-08 11:42:47 【问题描述】:

我在原程序的基础上设计了一个小程序,如下图所示

private void RegisterAtStartupButton_Click(object sender, EventArgs e)

    var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
    var value = key.GetValue(Application.ProductName, false)?.ToString();

    if (value == null)
    
        key.SetValue(Application.ProductName, Application.ExecutablePath);
    

    var path = Path.Combine(Directory.GetCurrentDirectory(), "Memory.txt");

    var text = File.Exists(path)
        ? File.ReadAllText(path)
        : "1";

    MessageBox.Show(text);

    File.WriteAllText(path, (Convert.ToInt32(text) + 1).ToString());

这个程序统计这个方法的执行次数,并保存在一个文本文件中 此外,在 Windows 启动中注册该程序,以便在重新启动 Windows 并登录到相同的用户帐户后运行它。 重启Windows并登录同一个账户,程序会自动运行,现在如果我们点击调用该函数的按钮,会显示如下错误

System.UnauthorizedAccessException: Access to the path 'C:\WINDOWS\system32\Memory.txt' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
   at System.IO.File.WriteAllText(String path, String contents)
   at StartupCounter.MainForm.MainForm_Load(Object sender, EventArgs e) in C:\Users\User\Source\Repos\StartupCounter\StartupCounter\MainForm.cs:line 23
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form.OnCreateControl()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
当程序位于另一个驱动器上时,Windows 是否将程序克隆到“C:\WINDOWS\system32\Memory.txt”? 如何防止这种情况发生并解决问题?

【问题讨论】:

您在启动时对当前目录所做的任何假设几乎肯定会出错。避免使用当前目录,除非您的程序已将其设置为它知道的内容。 我认为您将当前目录与程序集目录混淆了。 【参考方案1】:

我敢打赌,当它运行时,您第一次运行该程序时,它来自 Memory.txt 所在的文件夹。这样,当您执行 GetCurrentDirectory 时,它会找到该文件。

但是在启动情况下重启运行时,当前目录是系统目录。

这个例外没有帮助,但我猜你在这种情况下没有从那里读取的权限。

因此,要解决此问题,您无需使用 GetCurrentDirectory,而是使用完整路径。

或者更好的是,将 Memory.txt 存储在应用数据特定位置,见Where is the correct place to store my application specific data?

【讨论】:

以上是关于防止程序在启动时被 Windows 克隆的主要内容,如果未能解决你的问题,请参考以下文章

系统优化Wise Care 365 绿色便携版及系统清理CCleaner工具软件分享

当线程在保存时被杀死时,如何防止 NSManagedObjectContext 损坏数据库?

防止 Django SQLite db 在推送到 Heroku 时被覆盖

onLocationChanged 在应用程序启动时被多次调用

C# 程序(Winform 和 WPF)在启动文件夹中创建快捷方式时被视为病毒?

windoes任务管理器中的“句柄数”是啥意思!