【问题标题】:Set a permanent value of a variable without using a database在不使用数据库的情况下设置变量的永久值
【发布时间】:2018-03-15 10:25:04
【问题描述】:

我不知道如何在标题中彻底描述它,但是一旦进程返回 true,我需要设置变量/标志的永久值,并且可能在程序本身中设置一些标志值而不是保存它到数据库。并且一旦该变量/标志已经具有该值,那么程序将不会再次运行该过程而只是使用该值。可能吗?我正在使用 VB.Net。我不能使用数据库,因为可以使用查询覆盖数据库并更改值。提前致谢!

【问题讨论】:

  • 了解更多关于为什么值需要在每次执行中保持不变的背景知识可能有助于了解最合适的解决方案。 TLDR;你想完成什么?
  • @ChristopherHarris 我正试图在到期日期到来时禁用我的系统,由于我没有托管我系统的数据库,我不能只在数据库中创建另一个字段并存储那里的值,因为它可以通过执行查询手动覆盖。
  • 因为您担心值会被更新,所以您应该将其保存在除您之外没有其他人可以访问的地方。最好的方法是运行每次都产生价值的过程,但如果你这样做是非常“昂贵”的。您可以创建 Web API 来存储您的价值。
  • 如果您的代码在“攻击者”的机器上运行,那么您所能做的就是放置路障。 IE。熟练的用户可以反编译您的代码并删除变量检查。唯一 100% 的方法是将要保护的代码保留在 您控制的机器 上。除此之外,您最好购买一个许可组件,而不是尝试自己重新实现一个。

标签: c# .net vb.net


【解决方案1】:

您可以简单地在文件中使用二进制/XML 序列化来通过您的程序保存该变量的状态。每次重新启动应用程序时,您都可以访问该文件中的值以获取其当前状态。

你可以看看这个例子——http://www.centerspace.net/examples/nmath/csharp/core/binary-serialization-example.php

基本上,您不会将值保存在数据库中,而是保存在文件中。无论如何,您需要将值保留在某个地方。

【讨论】:

  • 值可以在文件中更新,其方式与在数据库中更新的方式相同,这是 OP 关心的。
  • 您提供的链接正在加载中。
【解决方案2】:

下面的一些方法

您没有说明是否担心您的应用程序或其他应用程序会更改该值

我会怎么做

下面是我的想法

1) 例如,您可以使用 xml 文件并使用强密码压缩该文件的副本。每次更新第一个 xml 时,您还将更新加密的压缩 xml。您可以使用 FileSystemWatcher 并捕获任何文件更改,因此如果某些/某人更改了文件,您只需从 zip 中获取一个新副本

2)您可以将值存储在数据库中并添加触发器以防止删除/更新

例如

    -- delete trigger
CREATE TRIGGER Function_Value_Deleted
ON [dbo].[FunctionsValueTb]
AFTER DELETE 
AS
BEGIN
SET NOCOUNT ON;



 IF EXISTS (
        SELECT [Flag] FROM deleted
    )
    BEGIN
        ROLLBACK;

RAISERROR ('Record deletion  is not allowed...', 16, 1);
END
END

*你也可以使用 THROW 而不是 RAISERROR

**对插入和更新操作执行相同操作

***您还可以将值存储到日志表中或发送电子邮件

【讨论】:

    【解决方案3】:

    几天前我发现自己的情况和你很相似。

    最后,我决定使用.NET 提供的settings functionaly:它易于使用和维护,到目前为止它给了我很好的效果。

    你可以在这里看到我在说什么: Best practice to save application settings in a Windows Forms Application

    该线程指的是 C#,但很容易适用于 VB.NET:我只需按照相同的步骤添加设置文件:

    在解决方案资源管理器中右键单击项目,选择属性。 选择设置选项卡,如果设置没有,请单击超链接 存在。使用设置选项卡创建应用程序设置。视觉的 Studio 创建文件 Settings.settings 和 Settings.Designer.settings 包含单例类 Settings 继承自 ApplicationSettingsBase

    然后,从我的代码中,我使用如下设置:

    Dim lastExecDate As Date = My.Settings.LastSuccessfulExecution
    lastExecDate = lastExecDate.AddDays(1)
    // Perform my next execution and do other stuff
    My.Settings.LastSuccessfulExecution = lastExecDate
    My.Settings.Save()
    

    下次您检索参数 LastSuccessfulExecution 时,它将具有更新后的值。

    还有一点,正如我在上面链接的帖子中所述:

    请注意,您需要设置设置的范围属性。如果你 选择 Application scope 然后 Settings.Default. 将 只读

    最后,我看到您正在使用它来存储产品的到期日期,因此您不希望用户弄乱它。根据this 帖子,参数的实际值存储在应用程序数据用户文件夹中。它以某种方式被混淆了,因为它不是那么容易找到,而且它的名字还包含一个哈希......我不知道这对你来说是否隐藏得足够好。

    【讨论】:

      【解决方案4】:

      如果您希望该值仅在应用程序运行时存在于内存中,那么您可以使用应用程序的主线程并使用:

      int slotData = randomGenerator.Next(1, 200);
      //to set the data
      Thread.SetData(Thread.GetNamedDataSlot("SomeDataKey"), slotData);
      //to get the data
      int newSlotData = (int)Thread.GetData(Thread.GetNamedDataSlot("SomeDataKey"));
      

      如果您的应用仅在 Windows 上运行,您也可以使用 Windows 注册表,否则您必须将值/对象写入文件并从那里读取。

      【讨论】:

      • 我不希望该值仅存在于内存中,我想在我的应用程序中设置一些标志,如果到期日期到来,它将无法使用,我希望这不是任何用户都可以编辑。这就是为什么我不希望用户编辑它。
      猜你喜欢
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 2016-01-08
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多