The principle and source code analysis of the. NET License Compiler (Lc.exe) in depth-practical tips

Source: Internet
Author: User
Tags httpcontext

When using a Third-party class library, you will often see its own demo program that contains the demo license file

Copy Code code as follows:

Infragistics.Win.Misc.UltraButton, infragistics2.win.misc.v11.1, version=11.1.20111.2009, Culture=neutral, Publickeytoken=f8b58b62b52fdf31
Infragistics.Win.Misc.UltraLabel, infragistics2.win.misc.v11.1, version=11.1.20111.2009, Culture=neutral, Publickeytoken=f8b58b62b52fdf31
Infragistics.Win.Printing.UltraPrintPreviewDialog, infragistics2.win.ultrawinprintpreviewdialog.v11.1, version= 11.1.20111.2009, Culture=neutral, publickeytoken=f8b58b62b52fdf31
Infragistics.Win.UltraWinDataSource.UltraDataSource, infragistics2.win.ultrawindatasource.v11.1, version= 11.1.20111.2009, Culture=neutral, publickeytoken=f8b58b62b52fdf31

The format of this file is a text file, but it needs to be written according to its format:

Control name, assembly full name

First, write a list of controls that need to be authorized, as shown above. For example, a HostApp.exe application that references the authorization control MyCompany.Samples.LicControl1 in Samples.DLL can create a HostAppLic.txt that contains the following content. MyCompany.Samples.LicControl1, Samples.DLL.

Then call the following command to create a. licenses file named HostApp.exe.licenses. Lc/target:hostapp.exe/complist:hostapplic.txt/i:samples.dll/outdir:c:\bindir

The build embeds the. licenses file as a resource in the HostApp.exe resource. If you are building a C # application, you should use the following command to build the application.

Csc/res:hostapp.exe.licenses/out:hostapp.exe *.cs

The LC.EXE file in the. NET Framework SDK directory is written in the. NET language and is designed to generate resource files based on the contents of the license file. At the end of the compilation, the CSC compiler embeds the generated resource files into the execution file.

Load LC.EXE with. NET Reflector to start a trip to source code analysis.



The entrance to the program first analyzes the command-line arguments and performs the specified function according to the parameters. Let's look at a complete list of parameters. The code is three lines below
Copy Code code as follows:

if (! Processargs (args))
{
return num;
}



MSDN has a complete explanation, copied to the following for your reference, to reduce the disruption of thinking by looking for MSDN.
/COMPLIST:FILENAME Specifies the name of the file that contains the list of authorized components to include in the. licenses file. Each component is referenced with its full name, and there is only one component per line. Command line users can specify a separate file for each form in the project. Lc.exe accepts multiple input files and produces a. licenses file.
/H[ELP] Displays the command syntax and options for the tool.
/I:MODULE Specifies the modules that contain the components listed in the file/complist. To specify multiple modules, use multiple/I flags.
/nologo suppresses the Microsoft startup banner.
/OUTDIR:PATH Specifies the directory used to place the output. licenses file.
/TARGET:TARGETPE Specifies the executable file for which the. licenses file is generated.
/v Specifies verbose mode, and displays compilation progress information.
/? Displays the command syntax and options for the tool.
The key role of the Processargs method is to analyze the list of components, the list of assemblies, as shown in the following code
Copy Code code as follows:

if (!flag3 && (str2). Length > 7)) && str2. Substring (0, 7). ToUpper (CultureInfo.InvariantCulture). Equals ("TARGET:"))
{
TARGETPE = str2. Substring (7);
Flag3 = true;
}
if (!flag3 && (str2). Length > 8)) && str2. Substring (0, 9). ToUpper (CultureInfo.InvariantCulture). Equals ("complist:"))
{
String str3 = str2. Substring (9);
if (STR3!= null) && (STR3. Length > 1))
{
if (complists = null)
{
complists = new ArrayList ();
}
Complists.add (STR3);
Flag3 = true;
}
}
if (!flag3 && (str2). Length > 2)) && str2. Substring (0, 2). ToUpper (CultureInfo.InvariantCulture). Equals ("I:"))
{
String STR4 = str2. Substring (2);
if (STR4. Length > 0)
{
if (assemblies = null)
{
assemblies = new ArrayList ();
}
Assemblies. ADD (STR4);
}
Flag3 = true;
}

After analyzing the components and assemblies, then resolveeventhandler the meaning of the delegate. If the runtime class loader cannot resolve a reference to an assembly, type, or resource, the corresponding event is raised so that the callback has an opportunity to notify the runtime which assembly the referenced assemblies, type, or resource are in. Resolveeventhandler is responsible for returning the assembly that resolves the type, assembly, or resource.
Copy Code code as follows:

Resolveeventhandler handler = new Resolveeventhandler (licensecompiler.onassemblyresolve);
AppDomain.CurrentDomain.AssemblyResolve + = handler;

A list of components that are parsed by the first parameter, followed by a loop, which gives them a license
Copy Code code as follows:

Designtimelicensecontext creationcontext = new Designtimelicensecontext ();
foreach (String str in complists)
{
Key = Reader.    ReadLine ();        Hashtable[key] = Type.GetType (key); Licensemanager.createwithcontext ((Type) Hashtable[key], creationcontext);
}

Finally, the license file is generated and saved to disk, waiting for the CSC compiler to compile it into a resource file and embed it in the assembly.
Copy Code code as follows:

string path = null;
if (OutputDir!= null)
{
Path = OutputDir + @ "\" + targetpe.tolower (cultureinfo.invariantculture) + ". Licenses";
}
Else
{
Path = Targetpe.tolower (CultureInfo.InvariantCulture) + ". Licenses";
}
Stream o = null;
Try
{
o = file.create (path);
Designtimelicensecontextserializer.serialize (O, Targetpe.toupper (cultureinfo.invariantculture), CreationContext) ;
}
Finally
{
if (o!= null)
{
O.flush ();
O.close ();
}
}

This approach is a way of protecting components recommended by the. NET framework, which is different from the input serial number we are talking about, the RSA signature.
Take a look at how the business component applies this technical protection component.
Copy Code code as follows:

Using System;
Using System.Web;
Using System.Web.UI;
Using System.Web.UI.WebControls;
Using System.ComponentModel;
Namespace ComponentArt.Licensing.Providers
{
#region Redistributablelicenseprovider
public class RedistributableLicenseProvider:System.ComponentModel.LicenseProvider
{
Const string Strappkey = "This edition of the Componentart Web.ui is licensed to."

public override System.ComponentModel.License Getlicense (licensecontext context, type type, object instance, bool Allowexceptions)
{
if (context. Usagemode = = licenseusagemode.designtime)
{
We are not going to worry about design time Issue a license
Return to New ComponentArt.Licensing.Providers.RedistributableLicense (this, "the App");
}
Else
{
String Strfoundappkey;
During runtime, we only want this control to run in the application
That it is packaged with.
HttpContext ctx = HttpContext.Current;
Strfoundappkey = (string) ctx. application["Componentartwebui_appkey"];
if (Strappkey = = Strfoundappkey)
Return to New ComponentArt.Licensing.Providers.RedistributableLicense (this, "the App");
Else
return null;
}
}
}
#endregion
#region Redistributablelicense Class
public class RedistributableLicense:System.ComponentModel.License
{
Private ComponentArt.Licensing.Providers.RedistributableLicenseProvider owner;
private string key;
Public Redistributablelicense (ComponentArt.Licensing.Providers.RedistributableLicenseProvider owner, string key)
{
This.owner = owner;
This.key = key;
}
public override string LicenseKey
{
Get
{
Return key;
}
}
public override void Dispose ()
{
}
}
#endregion
}

First you create a type, inherit from the license type, and then create a type that inherits from LicenseProvider, which is used to issue licenses, including design-time licensing and runtime licensing, as you can see from the example above that there is no restriction at design time to run, but at run time, You must have a serial number to generate the license object instead of returning null to the. NET Framework type. The entire validation process consists of the. NET complete.
You just need to apply this license protection mechanism as follows:
Copy Code code as follows:

[LicenseProvider (typeof (Redistributablelicenseprovider))]
public class Mycontrol:control {
Insert code here.
protected override void Dispose (bool disposing) {
/* All components must dispose of the licenses they grant.
* Insert code here to dispose of the license. */
}
}

The validation code (redistributablelicenseprovider) of the control license is completely separated from the logic of the control itself, and the Division of cooperation protects the intellectual property of the component.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.