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

Prevent the program from being cloned by Windows at startup

我在原程序的基础上设计了一个小程序,大家可以看下面

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'?

我怎样才能防止这种情况发生并解决问题?

我敢打赌,当它工作时,您是第一次从 Memory.txt 所在的文件夹中 运行 安装程序。这样,当您执行 GetCurrentDirectory 时,它会找到文件。

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

异常没有帮助,但我猜你没有权限在这种情况下从那里读取。

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

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