C#在编译时将日期放入程序中

时间:2021-09-11 22:52:04

I was thinking about how to create a program that would only be valid for X period of time, (within a C# app).

我在考虑如何创建一个只在X时间段内有效的程序(在C#应用程序中)。

What I was thinking was that you would have the current date as a constant inside the program and it would check to see if it is X days older than that. Naturally I do not want to store the date, or the X outside of the program as it can be tampered with.

我在想的是你将当前日期作为程序中的常量,它会检查它是否比X日期早X天。当然,我不想将日期或X外部存储在程序之外,因为它可以被篡改。

What I also do not want to manually change this regularly and recompile and deploy it. So is there a way to set a variable to be the current date when it is compiled?

我也不想定期手动更改它并重新编译和部署它。那么有没有办法将变量设置为编译时的当前日期?

I could have a batch file that would compile it and deploy the new exe to the distribution server.

我可以有一个批处理文件来编译它并将新的exe部署到分发服务器。

Thanks

7 个解决方案

#1


6  

Precompilation directives are your key here. You could create a constant in your application and have it set when you compile.

预编译指令是您的关键。您可以在应用程序中创建一个常量,并在编译时设置它。

Make sure you obfuscate your code, however. Someone could disassemble it easily and tamper with the constant. Another solution is to have your software "phone home" to register itself. That way, the registration info is stored on your server and not their machine. There are also third party packages that perform the same security as you're looking for, but they are expensive!

但是,请确保对代码进行模糊处理。有人可以轻松拆卸它并篡改常数。另一个解决方案是让您的软件“手机回家”进行自我注册。这样,注册信息存储在您的服务器上,而不是他们的机器上。还有第三方软件包可以执行您所需的相同安全性,但它们很昂贵!

#2


5  

Check out AssemblyInfo.cs file in the Properties folder in your project:

查看项目的Properties文件夹中的AssemblyInfo.cs文件:

// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Change this to:

将此更改为:

[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Then, elsewhere in the assembly, use this:

然后,在程序集的其他地方,使用:

System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

// MyVersion.Build = days after 2000-01-01
// MyVersion.Revision*2 = seconds after 0-hour  (NEVER daylight saving time)
DateTime MyTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);
return string.Format("Version:{0}  Compiled:{1:s}", MyVersion, MyTime);

#3


3  

I would go with the "Phone home"-variant. And make that call important. ;) I mean, some important function in your program (some calculation maybe?) will take place on the server. So if the user decompile the program and remove that "call home" it will render the program useless.

我会选择“电话之家” - 变种。并使这个电话很重要。 ;)我的意思是,你的程序中的一些重要功能(可能会进行一些计算?)将在服务器上进行。因此,如果用户反编译程序并删除“回家”,则会使程序无效。

I know that not all programs have those specifications that makes this possible but more than you think in general.

我知道并非所有程序都有那些使这成为可能的程序,但总的来说比你想的要多。

#4


2  

From within your automated build process (you do use an automated build process, right?), had a simple app which generates a 1-line C# class

从您的自动构建过程中(您确实使用自动构建过程,对吗?),有一个简单的应用程序生成一行C#类

 public struct TimeLimit { public DateTime Date = new DateTime(2009,1,1); }

changing the date automatically, and compile.

自动更改日期,然后编译。

Then just refer to TimeLimit.Date in your app.

然后在您的应用中引用TimeLimit.Date。

#5


2  

I know this is a 3 year old question, but just to add my 2 cents. We use a "DateLimit" hard coded in a structure as suggested by James Curran.

我知道这是一个3岁的问题,但只是加上我的2美分。我们使用James Curran建议的结构中硬编码的“DateLimit”。

But we also use that same "Date" as a simple key to "crypt" and "Decrypt" (more Code and decode) all strings, labels, messages. If some people (We call them Cheaters) want to change the expiration date, They will have to go thru the whole assembly to reenter all those string correctly for the new expiration date. It's not perfect, but the cost to us is now near zero and the cost for the Cheaters is high.

但我们也使用相同的“日期”作为“crypt”和“Decrypt”(更多代码和解码)所有字符串,标签和消息的简单密钥。如果某些人(我们称之为骗子)想要更改到期日期,他们必须通过整个程序集重新输入所有这些字符串以用于新的到期日期。它并不完美,但我们的成本现在几乎为零,骗子的成本很高。

#6


1  

I'd suggest that you have the date in a separate, strong named assembly - then at least the malevolent user will find it hard to disassemble, edit and get your program to use it. Is there a way to have two assemblies validating each other based on strong names?

我建议您将日期放在一个单独的,强大的命名程序集中 - 然后至少恶意用户会发现难以反汇编,编辑并让您的程序使用它。有没有办法让两个程序集基于强名称相互验证?

We kind of use this as a first step in our license control for one of our components. If the calling assembly has the same fingerprint as the license controlled one, we assume that it's being used within our own software and licensing is bypassed. If the calling assembly has a different fingerprint or no print at all, normal license checka are carried through. When I come to think of it, our users could probably disassemble, compile without strong naming and bypass licensing. But then again, all our assemblies are shipped as x86, not CIL - would that change anything?

我们将此作为我们其中一个组件的许可控制的第一步。如果调用程序集具有与许可证控制的指纹相同的指纹,我们假设它在我们自己的软件中使用并且许可被绕过。如果主叫程序集具有不同的指纹或根本没有打印,则执行正常的许可证检查。当我想到它时,我们的用户可能会在没有强大命名和绕过许可的情况下进行反汇编,编译。但话说再说一遍,我们所有的程序集都是以x86发布的,而不是CIL - 会改变什么吗?

Our experience is that if you're dealing with corporate customers, no-one can bear the hassle of tampering with your stuff, especially since there is a risk in getting caught. A little goes a long way, our current licensing solution is pretty outdated (the package includes examples for VC5!) but has been a high enough hurdle so far. With consumers, on the other hand, I can imagine that it's a bigger threat.

我们的经验是,如果你与企业客户打交道,没有人可以忍受篡改你的东西的麻烦,特别是因为有被抓住的风险。有点长远,我们当前的许可解决方案已经过时了(该软件包包含VC5的示例!)但到目前为止已经是一个足够高的障碍。另一方面,对于消费者,我可以想象这是一个更大的威胁。

My initial suggestion seems to spawn more questions that answers - perhaps not that helpful after all. :)

我最初的建议似乎产生了更多可以回答的问题 - 毕竟可能没那么有用。 :)

#7


0  

The problem with .Net is that it would be easy to decompile and change the date you want to use has constant. You might need to think to something else.

.Net的问题在于它很容易反编译并且改变你想要使用的日期是恒定的。您可能需要考虑其他事情。

You could write it in the registry but then the people will edit this value.

您可以在注册表中编写它,然后人们将编辑此值。

They aren't a perfect solution but to have an account that validate with an external (web) server is a good idea.

它们不是一个完美的解决方案,但拥有一个可以通过外部(Web)服务器验证的帐户是个好主意。

#1


6  

Precompilation directives are your key here. You could create a constant in your application and have it set when you compile.

预编译指令是您的关键。您可以在应用程序中创建一个常量,并在编译时设置它。

Make sure you obfuscate your code, however. Someone could disassemble it easily and tamper with the constant. Another solution is to have your software "phone home" to register itself. That way, the registration info is stored on your server and not their machine. There are also third party packages that perform the same security as you're looking for, but they are expensive!

但是,请确保对代码进行模糊处理。有人可以轻松拆卸它并篡改常数。另一个解决方案是让您的软件“手机回家”进行自我注册。这样,注册信息存储在您的服务器上,而不是他们的机器上。还有第三方软件包可以执行您所需的相同安全性,但它们很昂贵!

#2


5  

Check out AssemblyInfo.cs file in the Properties folder in your project:

查看项目的Properties文件夹中的AssemblyInfo.cs文件:

// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Change this to:

将此更改为:

[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Then, elsewhere in the assembly, use this:

然后,在程序集的其他地方,使用:

System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

// MyVersion.Build = days after 2000-01-01
// MyVersion.Revision*2 = seconds after 0-hour  (NEVER daylight saving time)
DateTime MyTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);
return string.Format("Version:{0}  Compiled:{1:s}", MyVersion, MyTime);

#3


3  

I would go with the "Phone home"-variant. And make that call important. ;) I mean, some important function in your program (some calculation maybe?) will take place on the server. So if the user decompile the program and remove that "call home" it will render the program useless.

我会选择“电话之家” - 变种。并使这个电话很重要。 ;)我的意思是,你的程序中的一些重要功能(可能会进行一些计算?)将在服务器上进行。因此,如果用户反编译程序并删除“回家”,则会使程序无效。

I know that not all programs have those specifications that makes this possible but more than you think in general.

我知道并非所有程序都有那些使这成为可能的程序,但总的来说比你想的要多。

#4


2  

From within your automated build process (you do use an automated build process, right?), had a simple app which generates a 1-line C# class

从您的自动构建过程中(您确实使用自动构建过程,对吗?),有一个简单的应用程序生成一行C#类

 public struct TimeLimit { public DateTime Date = new DateTime(2009,1,1); }

changing the date automatically, and compile.

自动更改日期,然后编译。

Then just refer to TimeLimit.Date in your app.

然后在您的应用中引用TimeLimit.Date。

#5


2  

I know this is a 3 year old question, but just to add my 2 cents. We use a "DateLimit" hard coded in a structure as suggested by James Curran.

我知道这是一个3岁的问题,但只是加上我的2美分。我们使用James Curran建议的结构中硬编码的“DateLimit”。

But we also use that same "Date" as a simple key to "crypt" and "Decrypt" (more Code and decode) all strings, labels, messages. If some people (We call them Cheaters) want to change the expiration date, They will have to go thru the whole assembly to reenter all those string correctly for the new expiration date. It's not perfect, but the cost to us is now near zero and the cost for the Cheaters is high.

但我们也使用相同的“日期”作为“crypt”和“Decrypt”(更多代码和解码)所有字符串,标签和消息的简单密钥。如果某些人(我们称之为骗子)想要更改到期日期,他们必须通过整个程序集重新输入所有这些字符串以用于新的到期日期。它并不完美,但我们的成本现在几乎为零,骗子的成本很高。

#6


1  

I'd suggest that you have the date in a separate, strong named assembly - then at least the malevolent user will find it hard to disassemble, edit and get your program to use it. Is there a way to have two assemblies validating each other based on strong names?

我建议您将日期放在一个单独的,强大的命名程序集中 - 然后至少恶意用户会发现难以反汇编,编辑并让您的程序使用它。有没有办法让两个程序集基于强名称相互验证?

We kind of use this as a first step in our license control for one of our components. If the calling assembly has the same fingerprint as the license controlled one, we assume that it's being used within our own software and licensing is bypassed. If the calling assembly has a different fingerprint or no print at all, normal license checka are carried through. When I come to think of it, our users could probably disassemble, compile without strong naming and bypass licensing. But then again, all our assemblies are shipped as x86, not CIL - would that change anything?

我们将此作为我们其中一个组件的许可控制的第一步。如果调用程序集具有与许可证控制的指纹相同的指纹,我们假设它在我们自己的软件中使用并且许可被绕过。如果主叫程序集具有不同的指纹或根本没有打印,则执行正常的许可证检查。当我想到它时,我们的用户可能会在没有强大命名和绕过许可的情况下进行反汇编,编译。但话说再说一遍,我们所有的程序集都是以x86发布的,而不是CIL - 会改变什么吗?

Our experience is that if you're dealing with corporate customers, no-one can bear the hassle of tampering with your stuff, especially since there is a risk in getting caught. A little goes a long way, our current licensing solution is pretty outdated (the package includes examples for VC5!) but has been a high enough hurdle so far. With consumers, on the other hand, I can imagine that it's a bigger threat.

我们的经验是,如果你与企业客户打交道,没有人可以忍受篡改你的东西的麻烦,特别是因为有被抓住的风险。有点长远,我们当前的许可解决方案已经过时了(该软件包包含VC5的示例!)但到目前为止已经是一个足够高的障碍。另一方面,对于消费者,我可以想象这是一个更大的威胁。

My initial suggestion seems to spawn more questions that answers - perhaps not that helpful after all. :)

我最初的建议似乎产生了更多可以回答的问题 - 毕竟可能没那么有用。 :)

#7


0  

The problem with .Net is that it would be easy to decompile and change the date you want to use has constant. You might need to think to something else.

.Net的问题在于它很容易反编译并且改变你想要使用的日期是恒定的。您可能需要考虑其他事情。

You could write it in the registry but then the people will edit this value.

您可以在注册表中编写它,然后人们将编辑此值。

They aren't a perfect solution but to have an account that validate with an external (web) server is a good idea.

它们不是一个完美的解决方案,但拥有一个可以通过外部(Web)服务器验证的帐户是个好主意。