Code provided free for anyone to use.. # MultiCharts.NET License Protection Instructions The Protection System Overview: Step 1: Information Gathering SystemInfoTester is the "scout" indicator Run it on any target machine you want to authorize It generates C:\post\SystemInfoTester.txt with unique machine fingerprints This code stays open - customers can run it to get their machine info Step 2: Code Protection Take the fingerprints from the text file Add them to your protected indicator's authorized list Compile and distribute the protected version Keep the source code private - only distribute compiled versions Example Workflow: https://claude.ai/public/artifacts/9c8696ed-9c2f-4c42-8500-45ec358b7554 What it will do: Creates the C:\post\ directory if it doesn't exist Writes a complete text file with all system information Shows a confirmation message in the Output Window Includes license binding examples in the file To use it: Compile and apply the indicator to any chart Check the Output Window for confirmation message Open the file: C:\post\SystemInfoTester.txt The file will contain: Complete system information (user, machine, OS, etc.) Environment variables Generated fingerprints for license binding Code examples showing how to use the fingerprints Timestamp of when it was generated File structure example: Code: using System; using System.Drawing; using System.Security.Cryptography; using System.Text; using System.IO; using PowerLanguage.Indicator; namespace PowerLanguage.Indicator { [SameAsSymbol(true)] public class SystemInfoTester : IndicatorObject { private bool infoDisplayed = false; private readonly string outputFilePath = @"C:\post\SystemInfoTester.txt"; // Constructor public SystemInfoTester(object ctx) : base(ctx) { } protected override void Create() { // No plots needed for this tester } protected override void StartCalc() { Output.Clear(); infoDisplayed = false; } protected override void CalcBar() { // Display system info only once if (!infoDisplayed && Bars.CurrentBar == 1) { WriteSystemInformationToFile(); infoDisplayed = true; } } private void WriteSystemInformationToFile() { try { // Ensure directory exists string directory = Path.GetDirectoryName(outputFilePath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } // Create StringBuilder to build the content StringBuilder content = new StringBuilder(); content.AppendLine("=== MULTICHARTS.NET SYSTEM INFORMATION ==="); content.AppendLine("Generated on: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); content.AppendLine(""); // Basic System Info content.AppendLine("--- BASIC SYSTEM INFORMATION ---"); try { content.AppendLine("User Name: " + System.Environment.UserName); content.AppendLine("Machine Name: " + System.Environment.MachineName); content.AppendLine("Domain Name: " + System.Environment.UserDomainName); content.AppendLine("OS Version: " + System.Environment.OSVersion.ToString()); content.AppendLine("64-bit OS: " + System.Environment.Is64BitOperatingSystem.ToString()); content.AppendLine("64-bit Process: " + System.Environment.Is64BitProcess.ToString()); content.AppendLine("Processor Count: " + System.Environment.ProcessorCount.ToString()); content.AppendLine("CLR Version: " + System.Environment.Version.ToString()); } catch (Exception ex) { content.AppendLine("Basic System Info Error: " + ex.Message); } content.AppendLine(""); // Windows Registry Info content.AppendLine("--- WINDOWS INFORMATION ---"); try { content.AppendLine("Current Directory: " + System.Environment.CurrentDirectory); content.AppendLine("System Directory: " + System.Environment.SystemDirectory); content.AppendLine("Windows Directory: " + System.Environment.GetEnvironmentVariable("WINDIR")); content.AppendLine("Computer Name: " + System.Environment.GetEnvironmentVariable("COMPUTERNAME")); content.AppendLine("User Profile: " + System.Environment.GetEnvironmentVariable("USERPROFILE")); content.AppendLine("Program Files: " + System.Environment.GetEnvironmentVariable("PROGRAMFILES")); content.AppendLine("Program Files (x86): " + System.Environment.GetEnvironmentVariable("PROGRAMFILES(X86)")); } catch (Exception ex) { content.AppendLine("Windows Info Error: " + ex.Message); } content.AppendLine(""); // MultiCharts Specific Information content.AppendLine("--- MULTICHARTS ENVIRONMENT ---"); try { content.AppendLine("Application Name: " + System.AppDomain.CurrentDomain.FriendlyName); content.AppendLine("Base Directory: " + System.AppDomain.CurrentDomain.BaseDirectory); content.AppendLine("Current Time: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); content.AppendLine("UTC Time: " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")); content.AppendLine("Temp Directory: " + Path.GetTempPath()); } catch (Exception ex) { content.AppendLine("MultiCharts Environment Error: " + ex.Message); } content.AppendLine(""); // Additional Environment Variables content.AppendLine("--- ENVIRONMENT VARIABLES ---"); try { string[] importantVars = { "PROCESSOR_IDENTIFIER", "PROCESSOR_REVISION", "NUMBER_OF_PROCESSORS", "PROCESSOR_ARCHITECTURE", "PROCESSOR_LEVEL", "USERDOMAIN", "USERNAME", "SESSIONNAME", "LOGONSERVER" }; foreach (string varName in importantVars) { string value = System.Environment.GetEnvironmentVariable(varName); content.AppendLine(varName + ": " + (value ?? "Not Available")); } } catch (Exception ex) { content.AppendLine("Environment Variables Error: " + ex.Message); } content.AppendLine(""); // Generate Fingerprints content.AppendLine("--- GENERATED FINGERPRINTS FOR LICENSE BINDING ---"); try { string simpleFingerprint = GenerateSimpleFingerprint(); content.AppendLine("Simple Fingerprint: " + simpleFingerprint); string userFingerprint = GenerateUserFingerprint(); content.AppendLine("User-based Fingerprint: " + userFingerprint); string timeFingerprint = GenerateTimeBasedFingerprint(); content.AppendLine("Time-based Fingerprint: " + timeFingerprint); string combinedFingerprint = GenerateCombinedFingerprint(); content.AppendLine("Combined Fingerprint: " + combinedFingerprint); string shortFingerprint = GenerateShortFingerprint(); content.AppendLine("Short Fingerprint (8 chars): " + shortFingerprint); } catch (Exception ex) { content.AppendLine("Fingerprint Generation Error: " + ex.Message); } content.AppendLine(""); // License Binding Examples content.AppendLine("--- LICENSE BINDING EXAMPLES ---"); content.AppendLine("// Example 1: Simple machine + user binding"); content.AppendLine("string licenseKey = \"" + GenerateSimpleFingerprint() + "\";"); content.AppendLine(""); content.AppendLine("// Example 2: Complex binding"); content.AppendLine("string complexKey = \"" + GenerateCombinedFingerprint() + "\";"); content.AppendLine(""); content.AppendLine("// Example 3: Short key for manual entry"); content.AppendLine("string shortKey = \"" + GenerateShortFingerprint() + "\";"); content.AppendLine(""); content.AppendLine("=== END OF SYSTEM INFORMATION ==="); // Write to file File.WriteAllText(outputFilePath, content.ToString()); // Also write to Output window to confirm Output.WriteLine("System information written to: " + outputFilePath); Output.WriteLine("File contains " + content.Length + " characters of system data"); Output.WriteLine("Check the file for complete system information and license binding keys"); } catch (Exception ex) { Output.WriteLine("Error writing system info to file: " + ex.Message); Output.WriteLine("Attempted to write to: " + outputFilePath); } } private string GenerateSimpleFingerprint() { try { string combined = System.Environment.MachineName + System.Environment.UserName; return ComputeHash(combined).Substring(0, 16); } catch { return "ERROR_SIMPLE"; } } private string GenerateUserFingerprint() { try { string combined = System.Environment.UserName + System.Environment.UserDomainName + System.Environment.MachineName; return ComputeHash(combined).Substring(0, 12); } catch { return "ERROR_USER"; } } private string GenerateTimeBasedFingerprint() { try { string combined = System.Environment.MachineName + System.Environment.OSVersion.ToString() + System.Environment.ProcessorCount.ToString(); return ComputeHash(combined).Substring(0, 10); } catch { return "ERROR_TIME"; } } private string GenerateCombinedFingerprint() { try { string combined = System.Environment.MachineName + System.Environment.UserName + System.Environment.OSVersion.ToString() + System.Environment.ProcessorCount.ToString() + (System.Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER") ?? ""); return ComputeHash(combined); } catch { return "ERROR_COMBINED"; } } private string GenerateShortFingerprint() { try { string combined = System.Environment.MachineName + System.Environment.UserName; string hash = ComputeHash(combined); return hash.Substring(0, Math.Min(8, hash.Length)).Replace("/", "").Replace("+", ""); } catch { return "ERR_SHT"; } } private string ComputeHash(string input) { if (string.IsNullOrEmpty(input)) return ""; try { using (SHA256 sha256 = SHA256.Create()) { byte[] bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(input)); return Convert.ToBase64String(bytes); } } catch { // Fallback to simpler hash if SHA256 not available return Math.Abs(input.GetHashCode()).ToString("X8"); } } } }