diff --git a/cpp/SampleWithLicensing/SampleWithLicensingValidator.cpp b/cpp/SampleWithLicensing/SampleWithLicensingValidator.cpp index a8546331..acc88255 100644 --- a/cpp/SampleWithLicensing/SampleWithLicensingValidator.cpp +++ b/cpp/SampleWithLicensing/SampleWithLicensingValidator.cpp @@ -92,7 +92,7 @@ CRhinoLicenseValidator::result CSampleWithLicensingValidator::VerifyLicenseKey( license_key = L"SAMPLE-EVALUATION"; bEvaluation = true; } - else if (license_key.Left(8).CompareNoCase(L"EVALUATION") == 0) + else if (license_key.Right(10).CompareNoCase(L"EVALUATION") == 0) { bEvaluation = true; } diff --git a/rhinocommon/cs/SampleCsWithLicense/Properties/AssemblyInfo.cs b/rhinocommon/cs/SampleCsWithLicense/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..348a2d1e --- /dev/null +++ b/rhinocommon/cs/SampleCsWithLicense/Properties/AssemblyInfo.cs @@ -0,0 +1,52 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using Rhino.PlugIns; + +// Plug-in Description Attributes - all of these are optional. +// These will show in Rhino's option dialog, in the tab Plug-ins. +[assembly: PlugInDescription(DescriptionType.Address, "3670 Woodland Park Avenue North\r\nSeattle, WA 98103")] +[assembly: PlugInDescription(DescriptionType.Country, "United States")] +[assembly: PlugInDescription(DescriptionType.Email, "devsupport@mcneel.com")] +[assembly: PlugInDescription(DescriptionType.Phone, "206-545-6877")] +[assembly: PlugInDescription(DescriptionType.Fax, "206-545-7321")] +[assembly: PlugInDescription(DescriptionType.Organization, "Robert McNeel & Associates")] +[assembly: PlugInDescription(DescriptionType.UpdateUrl, "https://github.com/mcneel/rhino-developer-samples")] +[assembly: PlugInDescription(DescriptionType.WebSite, "http://www.rhino3d.com/")] +[assembly: PlugInDescription(DescriptionType.Icon, "SampleCsWithLicense.Resources.SampleCs.ico")] + + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SampleCsWithLicense")] +[assembly: AssemblyDescription("RhinoCommon Sample - SampleCsWithLicense")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Robert McNeel & Associates")] +[assembly: AssemblyProduct("SampleCsCommands")] +[assembly: AssemblyCopyright("Copyright © 2018, Robert McNeel & Associates")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5deff610-a9c2-4922-92bc-ff6d3deb8d5e")] // This will also be the Guid of the Rhino plug-in + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// 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("6.0.0.0")] +[assembly: AssemblyFileVersion("6.0.0.0")] + +// Make compatible with Rhino Installer Engine +[assembly: AssemblyInformationalVersion("2")] diff --git a/rhinocommon/cs/SampleCsWithLicense/Resources/SampleCs.ico b/rhinocommon/cs/SampleCsWithLicense/Resources/SampleCs.ico new file mode 100644 index 00000000..3652186f Binary files /dev/null and b/rhinocommon/cs/SampleCsWithLicense/Resources/SampleCs.ico differ diff --git a/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicense.csproj b/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicense.csproj new file mode 100644 index 00000000..436b174f --- /dev/null +++ b/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicense.csproj @@ -0,0 +1,88 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {5DEFF610-A9C2-4922-92BC-FF6D3DEB8D5E} + Library + Properties + SampleCsWithLicense + SampleCsWithLicense + v4.5 + 512 + false + + + true + full + false + ..\bin\ + DEBUG;TRACE + prompt + false + + + pdbonly + true + ..\bin\ + TRACE + prompt + 4 + + + + C:\Program Files\Rhino 6\System\RhinoWindows.dll + False + + + + + + + False + C:\Program Files\Rhino 6\System\rhinocommon.dll + False + + + False + C:\Program Files\Rhino 6\System\Eto.dll + False + + + False + C:\Program Files\Rhino 6\System\Rhino.UI.dll + False + + + + + + + + + + + + + + Copy "$(TargetPath)" "$(TargetDir)$(ProjectName).rhp" +Erase "$(TargetPath)" + + + en-US + + + C:\Program Files\Rhino 6\System\Rhino.exe + + + Program + + \ No newline at end of file diff --git a/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicenseCommand.cs b/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicenseCommand.cs new file mode 100644 index 00000000..bb726c1f --- /dev/null +++ b/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicenseCommand.cs @@ -0,0 +1,16 @@ +using Rhino; +using Rhino.Commands; + +namespace SampleCsWithLicense +{ + public class SampleCsWithLicenseCommand : Command + { + public override string EnglishName => "SampleCsWithLicense"; + + protected override Result RunCommand(RhinoDoc doc, RunMode mode) + { + RhinoApp.WriteLine($"{0} plug-in loaded.", SampleCsWithLicensePlugIn.Instance.Name); + return Result.Success; + } + } +} diff --git a/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicensePlugIn.cs b/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicensePlugIn.cs new file mode 100644 index 00000000..fdffac6f --- /dev/null +++ b/rhinocommon/cs/SampleCsWithLicense/SampleCsWithLicensePlugIn.cs @@ -0,0 +1,187 @@ +using System; +using Rhino.PlugIns; +using Rhino.UI; + +namespace SampleCsWithLicense +{ + /// + /// Every RhinoCommon .rhp assembly must have one and only one PlugIn-derived + /// class. DO NOT create instances of this class yourself. It is the + /// responsibility of Rhino to create an instance of this class. + /// To complete plug-in information, please also see all PlugInDescription + /// attributes in AssemblyInfo.cs (you might need to click "Project" -> + /// "Show All Files" to see it in the "Solution Explorer" window). + /// + public class SampleCsWithLicensePlugIn : PlugIn + { + /// + /// Public constructor + /// + public SampleCsWithLicensePlugIn() + { + Instance = this; + } + + /// + /// Gets the only instance of the SampleCsWithLicensePlugIn plug-in. + /// + public static SampleCsWithLicensePlugIn Instance + { + get; private set; + } + + // You can override methods here to change the plug-in behavior on + // loading and shut down, add options pages to the Rhino _Option command + // and maintain plug-in wide options in a document. + + /// + /// OnLoad override + /// + protected override LoadReturnCode OnLoad(ref string errorMessage) + { + var rc = GetLicense(Capabilities, TextMask, OnValidateProductKey, OnLeaseChanged); + if (!rc) + return LoadReturnCode.ErrorNoDialog; + + return LoadReturnCode.Success; + } + + #region Licensing Info + + /// + /// Returns an icon to show in the License page in Options. + /// + private static System.Drawing.Icon ProductIcon + { + get + { + var size = RhinoWindows.Forms.Dpi.ScaleInt(32); + return DrawingUtilities.LoadIconWithScaleDown("SampleCsWithLicense.Resources.SampleCs.ico", size); + } + } + + /// + /// In the event that the user needs to be asked for a license, then you can + /// provide a text mask, which helps the user to distinguish between proper + /// and improper user input of your license code. Note, if you do not want + /// to use a text mask, then pass in a null value for this parameter. + /// + private static string TextMask => ">S\\AMP\\LE-AAAAAAAAAA"; + + /// + /// Our hard-code evaluation license key. + /// + private static string EvalLicenseKey => "SAMPLE-EVALUATION"; + + /// + /// Controls the buttons that will appear on the license notification window that + // is displayed if a license for the requesting product is not found. Note, the + // "Close" button will always be displayed. + /// + private static LicenseCapabilities Capabilities => LicenseCapabilities.CanBeEvaluated | + LicenseCapabilities.CanBePurchased | + LicenseCapabilities.CanBeSpecified; + + #endregion + + #region Licensing delegates + + /// + /// Validates a product key or license. + /// + /// The license key as input by the user. + /// The license data extracted by validating the license key. + /// The results of the license validation. + private static ValidateResult OnValidateProductKey(string licenseKey, out LicenseData licenseData) + { + // Initialize output data + licenseData = new LicenseData + { + BuildType = LicenseBuildType.Release, + LicenseCount = 1, + ProductIcon = ProductIcon, + IsUpgradeFromPreviousVersion = false, + RequiresOnlineValidation = false // This sample current does not support Rhino accounts. + }; + + var evaluation = false; + if (string.IsNullOrEmpty(licenseKey)) + { + licenseKey = EvalLicenseKey; + evaluation = true; + } + else if (licenseKey.IndexOf("EVALUATION", StringComparison.OrdinalIgnoreCase) > 0) + { + evaluation = true; + } + + // Fill in the class members based on the license key and validation code. + // This value will never be display in any user interface. + // When your plugin's VerifyLicenseKey function is called, it is + // passed a a product, or CD, key that was entered into the Zoo + // administrator console. Your VerifyLicenseKey function will validate + // the product key and decode it into a product license. This is + // where you can store this license. This value will be passed + // to your application at runtime when it requests a license. + licenseData.ProductLicense = licenseKey; + + // This value will display in user interface items, such as in + // the Zoo console and in About dialog boxes. Also, this value + // is used to uniquely identify this license. Thus, it is + // critical that this value be unique per product key, entered + // by the administrator. No other license of this product, as + // validated by this plugin, should return this value. + // TODO: provide an obfuscated license string here. + licenseData.SerialNumber = licenseKey; + + // This value will display in user interface items, such as in + // the Zoo console and in About dialog boxes. + // (e.g. "Rhinoceros 6", "Rhinoceros 6 Commercial", etc.) + // TODO: provide a license title string here. + licenseData.LicenseTitle = Instance.Name; + + // The Zoo supports licenses that expire. If your licensing scheme + // is sophisticated enough to support this, then specify the + // expiration date here. Note, this value must be specified in + // Coordinated Universal Time (UTC). If your license does not expire, + // then just this value to null. + if (evaluation) + { + var today = DateTime.UtcNow; + var expire = today.AddDays(90); + licenseData.DateToExpire = expire; + } + + return ValidateResult.Success; + } + + /// + /// Called by Rhino to signal that a lease from Rhino Accounts has changed. + /// If LicenseLeaseChangedEventArgs.Lease is null, then the server has signaled + /// that this product is no longer licensed. Your plug-in must change behavior + /// to behave appropriately. + /// + /// Data passed by Rhino when the lease changes + /// Icon to be displayed in Tools > Options > Licenses for this lease. + private static void OnLeaseChanged(LicenseLeaseChangedEventArgs args, out System.Drawing.Icon icon) + { + icon = ProductIcon; + + // This sample does not support Rhino accounts. + + if (null == args.Lease) + { + // Lease has been voided; this product should behave as if it has no + // license. It is up to the plug-in to determine what that looks like. + } + + // Verify that args.Lease.ProductId is correct + // Verify that args.Lease.ProductEdition is correct + // Verify that args.Lease.ProductVersion is correct + // Verify thatargs.Lease.IsExpired() is false + } + + #endregion + + } +} \ No newline at end of file diff --git a/rhinocommon/cs/SamplesCs.sln b/rhinocommon/cs/SamplesCs.sln index 97b013b5..02cade24 100644 --- a/rhinocommon/cs/SamplesCs.sln +++ b/rhinocommon/cs/SamplesCs.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27004.2008 +VisualStudioVersion = 15.0.27130.2020 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleCsCommands", "SampleCsCommands\SampleCsCommands.csproj", "{C1498326-89AB-48B0-A148-290C169CAA68}" EndProject @@ -63,6 +63,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleCsWizardPanel", "Samp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleCsDockBar", "SampleCsDockBar\SampleCsDockBar.csproj", "{9C84103D-7C1B-4685-8763-129503FEE6B6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleCsWithLicense", "SampleCsWithLicense\SampleCsWithLicense.csproj", "{5DEFF610-A9C2-4922-92BC-FF6D3DEB8D5E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -177,6 +179,10 @@ Global {9C84103D-7C1B-4685-8763-129503FEE6B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C84103D-7C1B-4685-8763-129503FEE6B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C84103D-7C1B-4685-8763-129503FEE6B6}.Release|Any CPU.Build.0 = Release|Any CPU + {5DEFF610-A9C2-4922-92BC-FF6D3DEB8D5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DEFF610-A9C2-4922-92BC-FF6D3DEB8D5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DEFF610-A9C2-4922-92BC-FF6D3DEB8D5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DEFF610-A9C2-4922-92BC-FF6D3DEB8D5E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE