/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options, string[] args) { // show usage Logger.Information(""); string commandLine = string.Empty; foreach (var arg in args) { commandLine = commandLine + " " + arg; } Logger.Information($"Command line: {commandLine}"); Logger.Information(""); Logger.Information(""); Logger.Information("Usage: {0}.exe [<options>]", Assembly.GetEntryAssembly().GetName().Name); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\r\n"); foreach (var line in helpLines) { Logger.Information(line); } }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options, string[] args) { // show usage Logger.Information(""); string commandLine = string.Empty; foreach (var arg in args) { commandLine = commandLine + " " + arg; } Logger.Information($"Command line: {commandLine}"); Logger.Information(""); Logger.Information(""); Logger.Information("Usage: dotnet NetCoreConsoleClient.dll [OPTIONS]"); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\r\n"); foreach (var line in helpLines) { Logger.Information(line); } }
/// <summary> /// Process a command line of the console sample application. /// </summary> public static string ProcessCommandLine( TextWriter output, string[] args, Mono.Options.OptionSet options, ref bool showHelp, bool noExtraArgs = true) { IList <string> extraArgs = null; try { extraArgs = options.Parse(args); if (noExtraArgs) { foreach (string extraArg in extraArgs) { output.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } } catch (OptionException e) { output.WriteLine(e.Message); showHelp = true; } if (showHelp) { options.WriteOptionDescriptions(output); throw new ErrorExitException("Invalid Commandline or help requested.", ExitCode.ErrorInvalidCommandLine); } return(extraArgs.FirstOrDefault()); }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options, string[] args = null) { Logger.Information(""); // show the args if (args != null) { string commandLine = string.Empty; foreach (var arg in args) { commandLine = commandLine + " " + arg; } Logger.Information($"Command line: {commandLine}"); } Logger.Information(""); Logger.Information($"{ProgramName} V{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}"); Logger.Information($"Informational version: V{(Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute).InformationalVersion}"); Logger.Information(""); Logger.Information("Usage: {0} [<options>]", Assembly.GetEntryAssembly().GetName().Name); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\n"); foreach (var line in helpLines) { Logger.Information(line); } }
private static void ShowHelp(Mono.Options.OptionSet p) { Console.WriteLine("Usage: UaTypeGenerator.exe [OPTIONS]+"); Console.WriteLine(); Console.WriteLine("Options:"); p.WriteOptionDescriptions(Console.Out); }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options) { // show usage WriteLine(); WriteLine("Usage: {0}.exe <applicationname> [<iothubconnectionstring>] [<options>]", Assembly.GetEntryAssembly().GetName().Name); WriteLine(); WriteLine("OPC Edge Publisher to subscribe to configured OPC UA servers and send telemetry to Azure IoTHub."); WriteLine("To exit the application, just press ENTER while it is running."); WriteLine(); WriteLine("applicationname: the OPC UA application name to use, required"); WriteLine(" The application name is also used to register the publisher under this name in the"); WriteLine(" IoTHub device registry."); WriteLine(); WriteLine("iothubconnectionstring: the IoTHub owner connectionstring, optional"); WriteLine(); WriteLine("There are a couple of environment variables which can be used to control the application:"); WriteLine("_HUB_CS: sets the IoTHub owner connectionstring"); WriteLine("_GW_LOGP: sets the filename of the log file to use"); WriteLine("_TPC_SP: sets the path to store certificates of trusted stations"); WriteLine("_GW_PNFP: sets the filename of the publishing configuration file"); WriteLine(); WriteLine("Command line arguments overrule environment variable settings."); WriteLine(); // output the options WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options) { // show usage Logger.Information(""); Logger.Information("Usage: {0}.exe [<options>]", Assembly.GetEntryAssembly().GetName().Name); Logger.Information(""); Logger.Information($"{ProgramName} to run test operations against OPC UA servers."); Logger.Information("To exit the application, just press CTRL-C while it is running."); Logger.Information(""); Logger.Information("There are a couple of environment variables which can be used to control the application:"); Logger.Information("_GW_LOGP: sets the filename of the log file to use"); Logger.Information("_TPC_SP: sets the path to store certificates of trusted stations"); Logger.Information(""); Logger.Information("Command line arguments overrule environment variable settings."); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\n"); foreach (var line in helpLines) { Logger.Information(line); } }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options) { // show usage Logger.Information(""); Logger.Information($"{ProgramName} V{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}"); Logger.Information($"Informational version: V{(Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute).InformationalVersion}"); Logger.Information(""); Logger.Information("Usage: {0}.exe [<options>]", Assembly.GetEntryAssembly().GetName().Name); Logger.Information(""); Logger.Information("OPC UA PLC for different data simulation scenarios"); Logger.Information("To exit the application, just press CTRL-C while it is running."); Logger.Information(""); Logger.Information("To specify a list of strings, please use the following format:"); Logger.Information("\"<string 1>,<string 2>,...,<string n>\""); Logger.Information("or if one string contains commas:"); Logger.Information("\"\"<string 1>\",\"<string 2>\",...,\"<string n>\"\""); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); System.IO.StringWriter stringWriter = new System.IO.StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\r\n"); foreach (var line in helpLines) { Logger.Information(line); } return; }
static void Main(string[] args) { var options = new Options(4); string file = "bingo.txt"; string dir = "."; uint count = 30; bool rtl = false; var opts = new Mono.Options.OptionSet { { "title=", "title of the bingo cards", t => options.title = t }, { "file=", "text file containing the values to put in the bingo cells (an answer to a line)", f => file = f }, { "center=", "value to be entered in center tile of all cards", c => options.center = c }, { "size=", "dimensions of the bingo cards", s => options.size = UInt32.Parse(s) }, { "count=", "number of bingo cards to create", c => count = UInt32.Parse(c) }, { "rtl", "create Right To Left cards", x => rtl = true }, }; try { opts.Parse(args); } catch (OptionException e) { Console.WriteLine(e.Message); return; } if (options.center != null) { if ((options.size & 1) != 1) { Console.WriteLine("Center should only be specified with odd sized cards"); return; } } var words = new List <string>(); using (var r = new System.IO.StreamReader(Path.Combine(dir, file))) { while (!r.EndOfStream) { string line = r.ReadLine(); if (!String.IsNullOrWhiteSpace(line)) { words.Add(line); } } } Console.WriteLine("Read {0} lines from {1}", words.Count, file); using (var w = new System.IO.StreamWriter(Path.Combine(dir, "output.html"), false, Encoding.UTF8)) { writeCards(w, options, words, dir, count, rtl); } Console.WriteLine("done"); }
public static int Main(string[] args) { Console.WriteLine( (Utils.IsRunningOnMono() ? "Mono" : ".Net Core") + " OPC UA Console Server sample"); // command line options bool showHelp = false; int stopTimeout = 0; bool autoAccept = false; string reverseConnectUrlString = null; Uri reverseConnectUrl = null; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "t|timeout=", "the number of seconds until the server stops.", (int t) => stopTimeout = t }, { "r|reverse=", "a url for a reverse connection", (string r) => reverseConnectUrlString = r } }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } if (reverseConnectUrlString != null) { reverseConnectUrl = new Uri(reverseConnectUrlString); } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine(Utils.IsRunningOnMono() ? "Usage: mono NetCoreConsoleServer.exe [OPTIONS]" : "Usage: dotnet NetCoreConsoleServer.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } MySampleServer server = new MySampleServer(autoAccept, stopTimeout, reverseConnectUrl); server.Run(); return((int)MySampleServer.ExitCode); }
public static int Main(string[] args) { #region Open a thread for pipeServer int i; Thread[] servers = new Thread[Globals.numberThreads]; Console.WriteLine("Waiting for client connect...\n"); for (i = 0; i < Globals.numberThreads; i++) { servers[i] = new Thread(PipeServerThread); servers[i].Start(); } #endregion Console.WriteLine("{0} OPC UA Reference Server", Utils.IsRunningOnMono() ? "Mono" : ".Net Core"); // command line options bool showHelp = false; bool autoAccept = false; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null } }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine(Utils.IsRunningOnMono() ? "Usage: mono MonoReferenceServer.exe [OPTIONS]" : "Usage: dotnet ConsoleReferenceServer.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } MyRefServer server = new MyRefServer(autoAccept); server.Run(); return((int)MyRefServer.ExitCode); }
public static async Task <int> MainAsync(string[] args) { string tests = ""; string correlationId = ""; string correlationIdFile = ""; bool waitForJobCompletion = false; var options = new Mono.Options.OptionSet { { "tests=", "Tests to run", param => { if (param != null) { tests = param; } } }, { "correlationIdFile=", "File to write correlation ID to", param => { if (param != null) { correlationIdFile = param; } } }, { "wait=", "Wait for job to complete", param => { if(param != null) { correlationId = param; waitForJobCompletion = true; } } }, }; try { options.Parse(args); } catch (Mono.Options.OptionException e) { Console.WriteLine("Option error: {0}", e.Message); return(1); } if (tests == "mainline" || tests == "mainline-cxx") { var t = new MainlineTests(tests); correlationId = await t.CreateJob().SendJob(); if (!String.IsNullOrEmpty(correlationIdFile)) { File.WriteAllText(correlationIdFile, correlationId); } return(0); } if (waitForJobCompletion) { var success = await new HelixBase().WaitForJobCompletion(correlationId); return(success ? 0 : 1); } Console.Error.WriteLine("Error: Invalid arguments."); return(1); }
public static async Task <int> Main(string[] args) { Console.WriteLine("{0} OPC UA Reference Server", Utils.IsRunningOnMono() ? "Mono" : ".Net Core"); // command line options bool showHelp = false; bool autoAccept = false; bool console = false; string password = null; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "c|console", "log trace to console", c => console = c != null }, { "p|password="******"optional password for private key", (string p) => password = p } }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine(Utils.IsRunningOnMono() ? "Usage: mono MonoReferenceServer.exe [OPTIONS]" : "Usage: dotnet ConsoleReferenceServer.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } var server = new MyRefServer() { AutoAccept = autoAccept, LogConsole = console, Password = password }; await server.Run().ConfigureAwait(false); return((int)server.ExitCode); }
static void Main(string[] args) { var shouldShowHelp = false; var nodesetFile = default(string); var ns = default(string); var assembliesNames = new List <string>(); var p = new Mono.Options.OptionSet { { "f|nodeset=", "the nodeset file", f => nodesetFile = f }, { "n|namespace=", "the .NET namespace.", n => ns = n }, { "a|additional-assemblies=", "the .NET namespace.", a => assembliesNames.Add(a) }, { "h|help", "show this message and exit", h => shouldShowHelp = h != null }, }; try { p.Parse(args); } catch (OptionException e) { Console.Write("UaTypeGenerator.exe: "); Console.WriteLine(e.Message); Console.WriteLine("Try `UaTypeGenerator.exe --help' for more information."); return; } if (shouldShowHelp) { ShowHelp(p); return; } var assemblies = assembliesNames .Select(n => Assembly.LoadFrom(n)) .Prepend(typeof(OpenSecureChannelRequest).Assembly) .ToArray(); var nodeset = ReadNodeSet(nodesetFile); var typeset = new TypeSet(nodeset, assemblies); var typewriter = new TypeSetWriter(typeset, ns); var outputFile = Path.ChangeExtension(nodesetFile, ".cs"); using (var writer = File.CreateText(outputFile)) { var intendedWriter = new IndentedTextWriter(writer); typewriter.Write(intendedWriter); } }
public static int Main(string[] args) { Console.WriteLine(Name); // command line options bool showHelp = false; var opcVaultOptions = new OpcVaultApiOptions(); var azureADOptions = new OpcVaultAzureADOptions(); Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "v|vault=", "OpcVault Url", g => opcVaultOptions.BaseAddress = g }, { "r|resource=", "OpcVault Resource Id", r => opcVaultOptions.ResourceId = r }, { "c|clientid=", "AD Client Id", c => azureADOptions.ClientId = c }, { "s|secret=", "AD Client Secret", s => azureADOptions.ClientSecret = s }, { "a|authority=", "Authority", a => azureADOptions.Authority = a }, { "t|tenantid=", "Tenant Id", t => azureADOptions.TenantId = t }, { "h|help", "show this message and exit", h => showHelp = h != null }, }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine("Usage: dotnet Microsoft.Azure.IIoT.OpcUa.Modules.Vault.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } var server = new VaultGlobalDiscoveryServer(); server.Run(opcVaultOptions, azureADOptions); return((int)VaultGlobalDiscoveryServer.ExitCode); }
/// <summary> /// The main entry point for the application. /// </summary> public static int Main(string[] args) { Console.WriteLine("SampleCompany {0} OPC UA Sample Server", Utils.IsRunningOnMono() ? "Mono" : ".NET Core"); // command line options var showHelp = false; var stopTimeout = 0; var autoAccept = false; var options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "t|timeout=", "the number of seconds until the server stops.", (int t) => stopTimeout = t }, }; try { IList <string> extraArgs = options.Parse(args); foreach (var extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine(Utils.IsRunningOnMono() ? "Usage: mono SampleCompany.SampleServer.exe [OPTIONS]" : "Usage: dotnet SampleCompany.SampleServer.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } var server = new MySampleServer(autoAccept, stopTimeout); server.Run(); return((int)MySampleServer.ExitCode); }
public static int Main(string[] args) { Console.WriteLine("OPC UA Reference Server.Net Core"); // command line options bool showHelp = false; bool autoAccept = false; bool console = false; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "c|console", "log trace to console", c => console = c != null } }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine("Usage: dotnet ConsoleReferenceServer.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } MyRefServer server = new MyRefServer(autoAccept, console); server.Run(); return((int)MyRefServer.ExitCode); }
public static int Main(string[] args) { Console.WriteLine(".Net Core OPC UA Global Discovery Server"); // command line options bool showHelp = false; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { Console.WriteLine("Usage: dotnet NetCoreGlobalDiscoveryServer.dll [OPTIONS]"); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } NetCoreGlobalDiscoveryServer server = new NetCoreGlobalDiscoveryServer(); server.Run(); return((int)NetCoreGlobalDiscoveryServer.ExitCode); }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options) { // show usage Logger.Information(""); Logger.Information("Usage: {0}.exe [<options>]", Assembly.GetEntryAssembly().GetName().Name); Logger.Information(""); Logger.Information("OPC Publisher node configuration tool."); Logger.Information("To exit the application, just press CTRL-C while it is running."); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\n"); foreach (var line in helpLines) { Logger.Information(line); } }
/// <summary> /// Usage message. /// </summary> private static void Usage(Mono.Options.OptionSet options) { // show usage Logger.Information(""); Logger.Information("Usage: {0}.exe [<options>]", Assembly.GetEntryAssembly().GetName().Name); Logger.Information(""); Logger.Information("OPC UA Connectedfactory station for the factory simulation"); Logger.Information("To exit the application, just press ENTER while it is running."); Logger.Information(""); // output the options Logger.Information("Options:"); StringBuilder stringBuilder = new StringBuilder(); System.IO.StringWriter stringWriter = new System.IO.StringWriter(stringBuilder); options.WriteOptionDescriptions(stringWriter); string[] helpLines = stringBuilder.ToString().Split("\r\n"); foreach (var line in helpLines) { Logger.Information(line); } return; }
public Collage(string [] args) { bool showHelp = false; var options = new Mono.Options.OptionSet() { { "cols=", (int cols) => columns = cols }, { "cellsize=", (int cell) => cellsize = cell }, { "output=", (string file) => output = file }, { "h|?|help", v => showHelp = true }, }; void Help() { Console.WriteLine("collage [options] DIRECTORY\n" + $"Default output is {output}, columns {columns}, cell size {cellsize}"); options.WriteOptionDescriptions(Console.Error); Environment.Exit(0); } if (showHelp) { Help(); } var dir = options.Parse(args).FirstOrDefault(); if (dir == null) { Help(); } if (dir != null) { directory = dir; } }
/// <summary> /// Asynchronous part of the main method of the app. /// </summary> public async static Task MainAsync(string[] args) { var shouldShowHelp = false; // command line options Mono.Options.OptionSet options = new Mono.Options.OptionSet { // log configuration { "lf|logfile=", $"the filename of the logfile to use.\nDefault: './{_logFileName}'", (string l) => _logFileName = l }, { "lt|logflushtimespan=", $"the timespan in seconds when the logfile should be flushed.\nDefault: {_logFileFlushTimeSpanSec} sec", (int s) => { if (s > 0) { _logFileFlushTimeSpanSec = TimeSpan.FromSeconds(s); } else { throw new Mono.Options.OptionException("The logflushtimespan must be a positive number.", "logflushtimespan"); } } }, { "ll|loglevel=", $"the loglevel to use (allowed: fatal, error, warn, info, debug, verbose).\nDefault: info", (string l) => { List <string> logLevels = new List <string> { "fatal", "error", "warn", "info", "debug", "verbose" }; if (logLevels.Contains(l.ToLowerInvariant())) { _logLevel = l.ToLowerInvariant(); } else { throw new OptionException("The loglevel must be one of: fatal, error, warn, info, debug, verbose", "loglevel"); } } }, // simulation configuration { "sc|simulationcyclecount=", $"count of cycles in one simulation phase\nDefault: {SimulationCycleCount} cycles", (int i) => SimulationCycleCount = i }, { "ct|cycletime=", $"length of one cycle time in milliseconds\nDefault: {SimulationCycleLength} msec", (int i) => SimulationCycleLength = i }, { "ns|nospikes", $"do not generate spike data\nDefault: {!GenerateSpikes}", a => GenerateSpikes = a == null }, { "nd|nodips", $"do not generate dip data\nDefault: {!GenerateDips}", a => GenerateDips = a == null }, { "np|nopostrend", $"do not generate positive trend data\nDefault: {!GeneratePosTrend}", a => GeneratePosTrend = a == null }, { "nn|nonegtrend", $"do not generate negative trend data\nDefault: {!GenerateNegTrend}", a => GenerateNegTrend = a == null }, { "nv|nodatavalues", $"do not generate data values\nDefault: {!GenerateData}", a => GenerateData = a == null }, // opc configuration { "pn|portnum=", $"the server port of the OPC server endpoint.\nDefault: {ServerPort}", (ushort p) => ServerPort = p }, { "op|path=", $"the enpoint URL path part of the OPC server endpoint.\nDefault: '{ServerPath}'", (string a) => ServerPath = a }, { "ph|plchostname=", $"the fullqualified hostname of the plc.\nDefault: {Hostname}", (string a) => Hostname = a }, { "ol|opcmaxstringlen=", $"the max length of a string opc can transmit/receive.\nDefault: {OpcMaxStringLength}", (int i) => { if (i > 0) { OpcMaxStringLength = i; } else { throw new OptionException("The max opc string length must be larger than 0.", "opcmaxstringlen"); } } }, { "lr|ldsreginterval=", $"the LDS(-ME) registration interval in ms. If 0, then the registration is disabled.\nDefault: {LdsRegistrationInterval}", (int i) => { if (i >= 0) { LdsRegistrationInterval = i; } else { throw new OptionException("The ldsreginterval must be larger or equal 0.", "ldsreginterval"); } } }, { "aa|autoaccept", $"all certs are trusted when a connection is established.\nDefault: {AutoAcceptCerts}", a => AutoAcceptCerts = a != null }, { "ut|unsecuretransport", $"enables the unsecured transport.\nDefault: {EnableUnsecureTransport}", u => EnableUnsecureTransport = u != null }, { "to|trustowncert", $"the own certificate is put into the trusted certificate store automatically.\nDefault: {TrustMyself}", t => TrustMyself = t != null }, // cert store options { "at|appcertstoretype=", $"the own application cert store type. \n(allowed values: Directory, X509Store)\nDefault: '{OpcOwnCertStoreType}'", (string s) => { if (s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(CertificateStoreType.Directory, StringComparison.OrdinalIgnoreCase)) { OpcOwnCertStoreType = s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) ? CertificateStoreType.X509Store : CertificateStoreType.Directory; OpcOwnCertStorePath = s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) ? OpcOwnCertX509StorePathDefault : OpcOwnCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "ap|appcertstorepath=", $"the path where the own application cert should be stored\nDefault (depends on store type):\n" + $"X509Store: '{OpcOwnCertX509StorePathDefault}'\n" + $"Directory: '{OpcOwnCertDirectoryStorePathDefault}'", (string s) => OpcOwnCertStorePath = s }, { "tp|trustedcertstorepath=", $"the path of the trusted cert store\nDefault '{OpcTrustedCertDirectoryStorePathDefault}'", (string s) => OpcTrustedCertStorePath = s }, { "rp|rejectedcertstorepath=", $"the path of the rejected cert store\nDefault '{OpcRejectedCertDirectoryStorePathDefault}'", (string s) => OpcRejectedCertStorePath = s }, { "ip|issuercertstorepath=", $"the path of the trusted issuer cert store\nDefault '{OpcIssuerCertDirectoryStorePathDefault}'", (string s) => OpcIssuerCertStorePath = s }, { "csr", $"show data to create a certificate signing request\nDefault '{ShowCreateSigningRequestInfo}'", c => ShowCreateSigningRequestInfo = c != null }, { "ab|applicationcertbase64=", $"update/set this applications certificate with the certificate passed in as bas64 string", (string s) => { NewCertificateBase64String = s; } }, { "af|applicationcertfile=", $"update/set this applications certificate with the certificate file specified", (string s) => { if (File.Exists(s)) { NewCertificateFileName = s; } else { throw new OptionException("The file '{s}' does not exist.", "applicationcertfile"); } } }, { "pb|privatekeybase64=", $"initial provisioning of the application certificate (with a PEM or PFX fomat) requires a private key passed in as base64 string", (string s) => { PrivateKeyBase64String = s; } }, { "pk|privatekeyfile=", $"initial provisioning of the application certificate (with a PEM or PFX fomat) requires a private key passed in as file", (string s) => { if (File.Exists(s)) { PrivateKeyFileName = s; } else { throw new OptionException("The file '{s}' does not exist.", "privatekeyfile"); } } }, { "cp|certpassword="******"the optional password for the PEM or PFX or the installed application certificate", (string s) => { CertificatePassword = s; } }, { "tb|addtrustedcertbase64=", $"adds the certificate to the applications trusted cert store passed in as base64 string (multiple strings supported)", (string s) => { TrustedCertificateBase64Strings = ParseListOfStrings(s); } }, { "tf|addtrustedcertfile=", $"adds the certificate file(s) to the applications trusted cert store passed in as base64 string (multiple filenames supported)", (string s) => { TrustedCertificateFileNames = ParseListOfFileNames(s, "addtrustedcertfile"); } }, { "ib|addissuercertbase64=", $"adds the specified issuer certificate to the applications trusted issuer cert store passed in as base64 string (multiple strings supported)", (string s) => { IssuerCertificateBase64Strings = ParseListOfStrings(s); } }, { "if|addissuercertfile=", $"adds the specified issuer certificate file(s) to the applications trusted issuer cert store (multiple filenames supported)", (string s) => { IssuerCertificateFileNames = ParseListOfFileNames(s, "addissuercertfile"); } }, { "rb|updatecrlbase64=", $"update the CRL passed in as base64 string to the corresponding cert store (trusted or trusted issuer)", (string s) => { CrlBase64String = s; } }, { "uc|updatecrlfile=", $"update the CRL passed in as file to the corresponding cert store (trusted or trusted issuer)", (string s) => { if (File.Exists(s)) { CrlFileName = s; } else { throw new OptionException("The file '{s}' does not exist.", "updatecrlfile"); } } }, { "rc|removecert=", $"remove cert(s) with the given thumbprint(s) (multiple thumbprints supported)", (string s) => { ThumbprintsToRemove = ParseListOfStrings(s); } }, // misc { "h|help", "show this message and exit", h => shouldShowHelp = h != null }, }; List <string> extraArgs = new List <string>(); try { // parse the command line extraArgs = options.Parse(args); } catch (OptionException e) { // initialize logging InitLogging(); // show message Logger.Fatal(e, "Error in command line options"); Logger.Error($"Command line arguments: {String.Join(" ", args)}"); // show usage Usage(options); return; } // initialize logging InitLogging(); // show usage if requested if (shouldShowHelp) { Usage(options); return; } // validate and parse extra arguments if (extraArgs.Count > 0) { Logger.Error("Error in command line options"); Logger.Error($"Command line arguments: {String.Join(" ", args)}"); Usage(options); return; } //show version Logger.Information($"{ProgramName} V{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion} starting up..."); Logger.Debug($"Informational version: V{(Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute).InformationalVersion}"); try { await ConsoleServerAsync(args); } catch (Exception ex) { Logger.Fatal(ex, "OPC UA server failed unexpectedly."); } Logger.Information("OPC UA server exiting..."); }
private OptionSet ParseArguments(string[] args, Settings settings) { var optionSet = new Mono.Options.OptionSet() { { "h|help", "shows this help", s => settings.Action = AppAction.ShowHelp }, { "p|port=", "sets the name of the serialport (COM1, COM2, etc)", s => settings.PortName = s }, { "l|listports", "lists the name of all available COM ports", s => settings.Action = AppAction.ListPorts }, { "e|echo", "echoes the received byte back", s => settings.Echo = true }, { "b|baudrate=", "sets the baudrate of the serialport", s => settings.BaudRate = TryParseBaudRate(s) }, { "parity=", "sets the parity bit configuration of the serialport", s => settings.Parity = TryParseParity(s) }, { "db|databits=", "sets the databits configuration of the serialport", s => settings.DataBits = TryParseDataBits(s) }, { "sb|stopbits=", "sets the stopbits configuration of the serialport", s => settings.StopBits = TryParseStopBits(s) }, { "f|send-file=", "sends the specified file over the serialport", s => { settings.FilePath = s; settings.Action = AppAction.SendFile; } }, { "a|send-ascii=", "sends the specified ascii value over the serialport", s => { settings.Ascii = TryParseAscii(s); settings.Action = AppAction.SendAscii; } }, { "c|count=", "specifies the number of files or ascii characters that are sent over the serialport", s => settings.Count = TryParseCount(s) }, { "t|text=", "specifies the text that is to be sent over the serialport", s => { settings.Text = s; settings.Action = AppAction.SendText; } }, { "r|receive", "listens on the serialport and writes received data to a file", s => { settings.Action = AppAction.Receive; settings.FilePath = s; } }, { "d|dump-to-file=", "optional file to dump the received data to", s => settings.FilePath = s } }; optionSet.Parse(args); return optionSet; }
/// <summary> /// Asynchronous part of the main method of the app. /// </summary> public async static Task MainAsync(string[] args) { try { var shouldShowHelp = false; // command line options configuration Mono.Options.OptionSet options = new Mono.Options.OptionSet { // Publishing configuration options { "pf|publishfile=", $"the filename to configure the nodes to publish (fallback procedure).\nDefault: '{PublisherNodeConfigurationFilename}'", (string p) => PublisherNodeConfigurationFilename = p }, { "tc|telemetryconfigfile=", $"the filename to configure the ingested telemetry\nDefault: '{PublisherTelemetryConfigurationFilename}'", (string p) => PublisherTelemetryConfigurationFilename = p }, { "sd|shopfloordomain=", $"the domain of the shopfloor. if specified this domain is appended (delimited by a ':' to the 'ApplicationURI' property when telemetry is sent to IoTHub.\n" + "The value must follow the syntactical rules of a DNS hostname.\nDefault: not set", (string s) => { Regex domainNameRegex = new Regex("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"); if (domainNameRegex.IsMatch(s)) { ShopfloorDomain = s; } else { throw new OptionException("The shopfloor domain is not a valid DNS hostname.", "shopfloordomain"); } } }, { "sw|sessionconnectwait=", $"specify the wait time in seconds publisher is trying to connect to disconnected endpoints and starts monitoring unmonitored items\nMin: 10\nDefault: {_publisherSessionConnectWaitSec}", (int i) => { if (i > 10) { _publisherSessionConnectWaitSec = i; } else { throw new OptionException("The sessionconnectwait must be greater than 10 sec", "sessionconnectwait"); } } }, { "mq|monitoreditemqueuecapacity=", $"specify how many notifications of monitored items can be stored in the internal queue, if the data can not be sent quick enough to IoTHub\nMin: 1024\nDefault: {MonitoredItemsQueueCapacity}", (int i) => { if (i >= 1024) { MonitoredItemsQueueCapacity = i; } else { throw new OptionException("The monitoreditemqueueitems must be greater than 1024", "monitoreditemqueueitems"); } } }, { "di|diagnosticsinterval=", $"shows publisher diagnostic info at the specified interval in seconds. 0 disables diagnostic output.\nDefault: {DiagnosticsInterval}", (uint u) => DiagnosticsInterval = u }, { "vc|verboseconsole=", $"the output of publisher is shown on the console.\nDefault: {VerboseConsole}", (bool b) => VerboseConsole = b }, { "ns|noshutdown=", $"publisher can not be stopped by pressing a key on the console, but will run forever.\nDefault: {_noShutdown}", (bool b) => _noShutdown = b }, // IoTHub specific options { "ih|iothubprotocol=", $"the protocol to use for communication with Azure IoTHub (allowed values: {string.Join(", ", Enum.GetNames(IotHubProtocol.GetType()))}).\nDefault: {Enum.GetName(IotHubProtocol.GetType(), IotHubProtocol)}", (Microsoft.Azure.Devices.Client.TransportType p) => IotHubProtocol = p }, { "ms|iothubmessagesize=", $"the max size of a message which can be send to IoTHub. when telemetry of this size is available it will be sent.\n0 will enforce immediate send when telemetry is available\nMin: 0\nMax: {IotHubMessageSizeMax}\nDefault: {IotHubMessageSize}", (uint u) => { if (u >= 0 && u <= IotHubMessageSizeMax) { IotHubMessageSize = u; } else { throw new OptionException("The iothubmessagesize must be in the range between 1 and 256*1024.", "iothubmessagesize"); } } }, { "si|iothubsendinterval=", $"the interval in seconds when telemetry should be send to IoTHub. If 0, then only the iothubmessagesize parameter controls when telemetry is sent.\nDefault: '{DefaultSendIntervalSeconds}'", (int i) => { if (i >= 0) { DefaultSendIntervalSeconds = i; } else { throw new OptionException("The iothubsendinterval must be larger or equal 0.", "iothubsendinterval"); } } }, { "dc|deviceconnectionstring=", $"if publisher is not able to register itself with IoTHub, you can create a device with name <applicationname> manually and pass in the connectionstring of this device.\nDefault: none", (string dc) => DeviceConnectionString = dc }, { "lf|logfile=", $"the filename of the logfile to use.\nDefault: './Logs/<applicationname>.log.txt'", (string l) => LogFileName = l }, { "ot|operationtimeout=", $"the operation timeout of the publisher OPC UA client in ms.\nDefault: {OpcOperationTimeout}", (int i) => { if (i >= 0) { OpcOperationTimeout = i; } else { throw new OptionException("The operation timeout must be larger or equal 0.", "operationtimeout"); } } }, { "oi|opcsamplinginterval=", "the publisher is using this as default value in milliseconds to request the servers to sample the nodes with this interval\n" + "this value might be revised by the OPC UA servers to a supported sampling interval.\n" + "please check the OPC UA specification for details how this is handled by the OPC UA stack.\n" + "a negative value will set the sampling interval to the publishing interval of the subscription this node is on.\n" + $"0 will configure the OPC UA server to sample in the highest possible resolution and should be taken with care.\nDefault: {OpcSamplingInterval}", (int i) => OpcSamplingInterval = i }, { "op|opcpublishinginterval=", "the publisher is using this as default value in milliseconds for the publishing interval setting of the subscriptions established to the OPC UA servers.\n" + "please check the OPC UA specification for details how this is handled by the OPC UA stack.\n" + $"a value less than or equal zero will let the server revise the publishing interval.\nDefault: {OpcPublishingInterval}", (int i) => { if (i > 0 && i >= OpcSamplingInterval) { OpcPublishingInterval = i; } else { if (i <= 0) { OpcPublishingInterval = 0; } else { throw new OptionException($"The opcpublishinterval ({i}) must be larger than the opcsamplinginterval ({OpcSamplingInterval}).", "opcpublishinterval"); } } } }, { "ct|createsessiontimeout=", $"specify the timeout in seconds used when creating a session to an endpoint. On unsuccessful connection attemps a backoff up to {OpcSessionCreationBackoffMax} times the specified timeout value is used.\nMin: 1\nDefault: {OpcSessionCreationTimeout}", (uint u) => { if (u > 1) { OpcSessionCreationTimeout = u; } else { throw new OptionException("The createsessiontimeout must be greater than 1 sec", "createsessiontimeout"); } } }, { "ki|keepaliveinterval=", $"specify the interval in seconds the publisher is sending keep alive messages to the OPC servers on the endpoints it is connected to.\nMin: 2\nDefault: {OpcKeepAliveIntervalInSec}", (int i) => { if (i >= 2) { OpcKeepAliveIntervalInSec = i; } else { throw new OptionException("The keepaliveinterval must be greater or equal 2", "keepalivethreshold"); } } }, { "kt|keepalivethreshold=", $"specify the number of keep alive packets a server can miss, before the session is disconneced\nMin: 1\nDefault: {OpcKeepAliveDisconnectThreshold}", (uint u) => { if (u > 1) { OpcKeepAliveDisconnectThreshold = u; } else { throw new OptionException("The keepalivethreshold must be greater than 1", "keepalivethreshold"); } } }, { "st|opcstacktracemask=", $"the trace mask for the OPC stack. See github OPC .NET stack for definitions.\nTo enable IoTHub telemetry tracing set it to 711.\nDefault: {OpcStackTraceMask:X} ({OpcStackTraceMask})", (int i) => { if (i >= 0) { OpcStackTraceMask = i; } else { throw new OptionException("The OPC stack trace mask must be larger or equal 0.", "opcstacktracemask"); } } }, { "as|autotrustservercerts=", $"the publisher trusts all servers it is establishing a connection to.\nDefault: {OpcPublisherAutoTrustServerCerts}", (bool b) => OpcPublisherAutoTrustServerCerts = b }, // trust own public cert option { "tm|trustmyself=", $"the publisher certificate is put into the trusted certificate store automatically.\nDefault: {TrustMyself}", (bool b) => TrustMyself = b }, // read the display name of the nodes to publish from the server and publish them instead of the node id { "fd|fetchdisplayname=", $"enable to read the display name of a published node from the server. this will increase the runtime.\nDefault: {FetchOpcNodeDisplayName}", (bool b) => FetchOpcNodeDisplayName = b }, // own cert store options { "at|appcertstoretype=", $"the own application cert store type. \n(allowed values: Directory, X509Store)\nDefault: '{OpcOwnCertStoreType}'", (string s) => { if (s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(Directory, StringComparison.OrdinalIgnoreCase)) { OpcOwnCertStoreType = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? X509Store : Directory; OpcOwnCertStorePath = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? OpcOwnCertX509StorePathDefault : OpcOwnCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "ap|appcertstorepath=", $"the path where the own application cert should be stored\nDefault (depends on store type):\n" + $"X509Store: '{OpcOwnCertX509StorePathDefault}'\n" + $"Directory: '{OpcOwnCertDirectoryStorePathDefault}'", (string s) => OpcOwnCertStorePath = s }, // trusted cert store options { "tt|trustedcertstoretype=", $"the trusted cert store type. \n(allowed values: Directory, X509Store)\nDefault: {OpcTrustedCertStoreType}", (string s) => { if (s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(Directory, StringComparison.OrdinalIgnoreCase)) { OpcTrustedCertStoreType = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? X509Store : Directory; OpcTrustedCertStorePath = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? OpcTrustedCertX509StorePathDefault : OpcTrustedCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "tp|trustedcertstorepath=", $"the path of the trusted cert store\nDefault (depends on store type):\n" + $"X509Store: '{OpcTrustedCertX509StorePathDefault}'\n" + $"Directory: '{OpcTrustedCertDirectoryStorePathDefault}'", (string s) => OpcTrustedCertStorePath = s }, // rejected cert store options { "rt|rejectedcertstoretype=", $"the rejected cert store type. \n(allowed values: Directory, X509Store)\nDefault: {OpcRejectedCertStoreType}", (string s) => { if (s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(Directory, StringComparison.OrdinalIgnoreCase)) { OpcRejectedCertStoreType = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? X509Store : Directory; OpcRejectedCertStorePath = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? OpcRejectedCertX509StorePathDefault : OpcRejectedCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "rp|rejectedcertstorepath=", $"the path of the rejected cert store\nDefault (depends on store type):\n" + $"X509Store: '{OpcRejectedCertX509StorePathDefault}'\n" + $"Directory: '{OpcRejectedCertDirectoryStorePathDefault}'", (string s) => OpcRejectedCertStorePath = s }, // issuer cert store options { "it|issuercertstoretype=", $"the trusted issuer cert store type. \n(allowed values: Directory, X509Store)\nDefault: {OpcIssuerCertStoreType}", (string s) => { if (s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(Directory, StringComparison.OrdinalIgnoreCase)) { OpcIssuerCertStoreType = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? X509Store : Directory; OpcIssuerCertStorePath = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? OpcIssuerCertX509StorePathDefault : OpcIssuerCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "ip|issuercertstorepath=", $"the path of the trusted issuer cert store\nDefault (depends on store type):\n" + $"X509Store: '{OpcIssuerCertX509StorePathDefault}'\n" + $"Directory: '{OpcIssuerCertDirectoryStorePathDefault}'", (string s) => OpcIssuerCertStorePath = s }, // device connection string cert store options { "dt|devicecertstoretype=", $"the iothub device cert store type. \n(allowed values: Directory, X509Store)\nDefault: {IotDeviceCertStoreType}", (string s) => { if (s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(Directory, StringComparison.OrdinalIgnoreCase)) { IotDeviceCertStoreType = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? X509Store : Directory; IotDeviceCertStorePath = s.Equals(X509Store, StringComparison.OrdinalIgnoreCase) ? IotDeviceCertX509StorePathDefault : IotDeviceCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "dp|devicecertstorepath=", $"the path of the iot device cert store\nDefault Default (depends on store type):\n" + $"X509Store: '{IotDeviceCertX509StorePathDefault}'\n" + $"Directory: '{IotDeviceCertDirectoryStorePathDefault}'", (string s) => IotDeviceCertStorePath = s }, // misc { "h|help", "show this message and exit", h => shouldShowHelp = h != null }, }; List <string> arguments = new List <string>(); int maxAllowedArguments = 2; int applicationNameIndex = 0; int connectionStringIndex = 1; if (IsIotEdgeModule) { maxAllowedArguments = 3; applicationNameIndex = 1; connectionStringIndex = 2; } try { // parse the command line arguments = options.Parse(args); } catch (OptionException e) { // show message WriteLine($"Error: {e.Message}"); // show usage Usage(options); return; } // Validate and parse arguments. if (arguments.Count > maxAllowedArguments || shouldShowHelp) { Usage(options); return; } else if (arguments.Count == maxAllowedArguments) { ApplicationName = arguments[applicationNameIndex]; IotHubOwnerConnectionString = arguments[connectionStringIndex]; } else if (arguments.Count == maxAllowedArguments - 1) { ApplicationName = arguments[applicationNameIndex]; } else { ApplicationName = Utils.GetHostName(); } WriteLine("Publisher is starting up..."); // Shutdown token sources. ShutdownTokenSource = new CancellationTokenSource(); // init OPC configuration and tracing OpcStackConfiguration opcStackConfiguration = new OpcStackConfiguration(); await opcStackConfiguration.ConfigureAsync(); _opcTraceInitialized = true; // log shopfloor domain setting if (string.IsNullOrEmpty(ShopfloorDomain)) { Trace("There is no shopfloor domain configured."); } else { Trace($"Publisher is in shopfloor domain '{ShopfloorDomain}'."); } // Set certificate validator. if (OpcPublisherAutoTrustServerCerts) { Trace("Publisher configured to auto trust server certificates of the servers it is connecting to."); PublisherOpcApplicationConfiguration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_AutoTrustServerCerts); } else { Trace("Publisher configured to not auto trust server certificates. When connecting to servers, you need to manually copy the rejected server certs to the trusted store to trust them."); PublisherOpcApplicationConfiguration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_Default); } // read telemetry configuration file PublisherTelemetryConfiguration.Init(); if (!await PublisherTelemetryConfiguration.ReadConfigAsync()) { return; } // read node configuration file // read it before loading desired properties in case of misconfigurations PublisherNodeConfiguration.Init(); if (!await PublisherNodeConfiguration.ReadConfigAsync()) { return; } // initialize and start IoTHub messaging IotHubCommunication = new IotHubMessaging(); if (!await IotHubCommunication.InitAsync()) { return; } if (!await PublisherNodeConfiguration.CreateOpcPublishingDataAsync()) { return; } // kick off the task to maintain all sessions Task sessionConnectorAsync = Task.Run(async() => await SessionConnectorAsync(ShutdownTokenSource.Token)); // initialize publisher diagnostics Diagnostics.Init(); // stop on user request WriteLine(""); WriteLine(""); if (_noShutdown) { // wait forever if asked to do so WriteLine("Publisher is running infinite..."); await Task.Delay(Timeout.Infinite); } else { WriteLine("Publisher is running. Press any key to quit."); try { ReadKey(true); } catch { // wait forever if there is no console WriteLine("There is no console. Publisher is running infinite..."); await Task.Delay(Timeout.Infinite); } } WriteLine(""); WriteLine(""); ShutdownTokenSource.Cancel(); WriteLine("Publisher is shutting down..."); // Wait for session connector completion await sessionConnectorAsync; // Clean up Publisher sessions await SessionShutdownAsync(); // shutdown the IoTHub messaging await IotHubCommunication.ShutdownAsync(); IotHubCommunication = null; // shutdown diagnostics await ShutdownAsync(); // free resources PublisherTelemetryConfiguration.Deinit(); PublisherNodeConfiguration.Deinit(); ShutdownTokenSource = null; } catch (Exception e) { if (_opcTraceInitialized) { Trace(e, e.StackTrace); e = e.InnerException ?? null; while (e != null) { Trace(e, e.StackTrace); e = e.InnerException ?? null; } Trace("Publisher exiting... "); } else { WriteLine($"{DateTime.Now.ToString()}: {e.Message.ToString()}"); WriteLine($"{DateTime.Now.ToString()}: {e.StackTrace}"); e = e.InnerException ?? null; while (e != null) { WriteLine($"{DateTime.Now.ToString()}: {e.Message.ToString()}"); WriteLine($"{DateTime.Now.ToString()}: {e.StackTrace}"); e = e.InnerException ?? null; } WriteLine($"{DateTime.Now.ToString()}: Publisher exiting..."); } } }
public static int Main(string[] args) { Console.WriteLine(".Net Core OPC UA Complex Types Client sample"); // command line options bool showHelp = false; int stopTimeout = Timeout.Infinite; bool autoAccept = false; bool writeComplexInt = false; bool noloadTypes = false; bool verbose = false; bool json = false; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "t|timeout=", "the number of seconds until the client stops.", (int t) => stopTimeout = t }, { "w|writeint", "Read and increment all complex types with an Int32.", w => writeComplexInt = w != null }, { "n|noloadtypes", "Load the type system dictionary from the server.", n => noloadTypes = n != null }, { "v|verbose", "Verbose output.", v => verbose = v != null }, { "j|json", "Print custom nodes as Json.", j => json = j != null }, }; IList <string> extraArgs = null; try { extraArgs = options.Parse(args); if (extraArgs.Count > 1) { foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { // show some app description message Console.WriteLine("Usage: dotnet NetCoreConsoleClient.dll [OPTIONS] [ENDPOINTURL]"); Console.WriteLine(); // output the options Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } string endpointURL; if (extraArgs.Count == 0) { // use OPC UA .Net Sample server endpointURL = "opc.tcp://localhost:51210/UA/SampleServer"; } else { endpointURL = extraArgs[0]; } MySampleClient client = new MySampleClient(endpointURL, autoAccept, stopTimeout) { Verbose = verbose, LoadTypeSystem = !noloadTypes, WriteComplexInt = writeComplexInt, PrintAsJson = json }; return((int)client.Run()); }
// TODO: Figure out which are actually supported in the new publisher implementation /// <summary> /// Parse arguments and set values in the environment the way the new configuration expects it. /// </summary> /// <param name="args">The specified command line arguments.</param> public LegacyCliOptions(string[] args) { // command line options var options = new Mono.Options.OptionSet { // Publisher configuration options { "pf|publishfile=", "the filename to configure the nodes to publish.", s => this[LegacyCliConfigKeys.PublisherNodeConfigurationFilename] = s }, { "s|site=", "the site OPC Publisher is working in.", s => this[LegacyCliConfigKeys.PublisherSite] = s }, { "di|diagnosticsinterval=", "Shows publisher diagnostic info at the specified interval " + "in seconds (need log level info).\n-1 disables remote diagnostic log and diagnostic output", (int i) => this[LegacyCliConfigKeys.DiagnosticsInterval] = TimeSpan.FromSeconds(i).ToString() }, { "lf|logfile=", "the filename of the logfile to use.", s => this[LegacyCliConfigKeys.LogFileName] = s }, { "lt|logflushtimespan=", "the timespan in seconds when the logfile should be flushed.", (int i) => this[LegacyCliConfigKeys.LogFileFlushTimeSpanSec] = TimeSpan.FromSeconds(i).ToString() }, { "ll|loglevel=", "the loglevel to use (allowed: fatal, error, warn, info, debug, verbose).", (LogEventLevel l) => LogControl.Level.MinimumLevel = l }, { "ih|iothubprotocol=", "Protocol to use for communication with the hub. " + $"(allowed values: {string.Join(", ", Enum.GetNames(typeof(TransportOption)))}).", (TransportOption p) => this[LegacyCliConfigKeys.HubTransport] = p.ToString() }, { "dc|deviceconnectionstring=", "A device or edge module connection string to use.", dc => this[LegacyCliConfigKeys.EdgeHubConnectionString] = dc }, { "ec|edgehubconnectionstring=", "An edge module connection string to use", dc => this[LegacyCliConfigKeys.EdgeHubConnectionString] = dc }, { "hb|heartbeatinterval=", "the publisher is using this as default value in seconds " + "for the heartbeat interval setting of nodes without a heartbeat interval setting.", (int i) => this[LegacyCliConfigKeys.HeartbeatIntervalDefault] = TimeSpan.FromSeconds(i).ToString() }, { "sf|skipfirstevent=", "the publisher is using this as default value for the skip first " + "event setting of nodes without a skip first event setting.", (bool b) => this[LegacyCliConfigKeys.SkipFirstDefault] = b.ToString() }, { "mm|messagingmode=", "The messaging mode for messages " + $"(allowed values: {string.Join(", ", Enum.GetNames(typeof(MessagingMode)))}).", (MessagingMode m) => this[LegacyCliConfigKeys.MessagingMode] = m.ToString() }, // Client settings { "ot|operationtimeout=", "the operation timeout of the publisher OPC UA client in ms.", (uint i) => this[LegacyCliConfigKeys.OpcOperationTimeout] = TimeSpan.FromMilliseconds(i).ToString() }, { "ol|opcmaxstringlen=", "the max length of a string opc can transmit/receive.", (uint i) => this[LegacyCliConfigKeys.OpcMaxStringLength] = i.ToString() }, { "oi|opcsamplinginterval=", "Default value in milliseconds to request the servers to " + "sample values.", (int i) => this[LegacyCliConfigKeys.OpcSamplingInterval] = TimeSpan.FromMilliseconds(i).ToString() }, { "op|opcpublishinginterval=", "Default value in milliseconds for the publishing interval " + "setting of the subscriptions against the OPC UA server.", (int i) => this[LegacyCliConfigKeys.OpcPublishingInterval] = TimeSpan.FromMilliseconds(i).ToString() }, { "ct|createsessiontimeout=", "The timeout in seconds used when creating a session to an endpoint.", (uint u) => this[LegacyCliConfigKeys.OpcSessionCreationTimeout] = TimeSpan.FromSeconds(u).ToString() }, { "ki|keepaliveinterval=", "The interval in seconds the publisher is sending keep alive messages " + "to the OPC servers on the endpoints it is connected to.", (int i) => this[LegacyCliConfigKeys.OpcKeepAliveIntervalInSec] = TimeSpan.FromSeconds(i).ToString() }, { "kt|keepalivethreshold=", "specify the number of keep alive packets a server can miss, " + "before the session is disconneced.", (uint u) => this[LegacyCliConfigKeys.OpcKeepAliveDisconnectThreshold] = u.ToString() }, { "fd|fetchdisplayname=", "same as fetchname.", (bool b) => this[LegacyCliConfigKeys.FetchOpcNodeDisplayName] = b.ToString() }, { "sw|sessionconnectwait=", "Wait time in seconds publisher is trying to connect " + "to disconnected endpoints and starts monitoring unmonitored items.", (int s) => this[LegacyCliConfigKeys.SessionConnectWaitSec] = TimeSpan.FromSeconds(s).ToString() }, // cert store options { "aa|autoaccept", "the publisher trusts all servers it is establishing a connection to.", b => this[LegacyCliConfigKeys.AutoAcceptCerts] = (b != null).ToString() }, { "to|trustowncert", "the publisher certificate is put into the trusted store automatically.", t => this[LegacyCliConfigKeys.TrustMyself] = (t != null).ToString() }, { "at|appcertstoretype=", "the own application cert store type (allowed: Directory, X509Store).", s => { if (s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(CertificateStoreType.Directory, StringComparison.OrdinalIgnoreCase)) { this[LegacyCliConfigKeys.OpcOwnCertStoreType] = s; return; } throw new OptionException("Bad store type", "at"); } }, { "ap|appcertstorepath=", "the path where the own application cert should be stored.", s => this[LegacyCliConfigKeys.OpcOwnCertStorePath] = s }, { "tp|trustedcertstorepath=", "the path of the trusted cert store.", s => this[LegacyCliConfigKeys.OpcTrustedCertStorePath] = s }, { "tt|trustedcertstoretype=", "Legacy - do not use.", _ => {} }, { "rp|rejectedcertstorepath=", "the path of the rejected cert store.", s => this[LegacyCliConfigKeys.OpcRejectedCertStorePath] = s }, { "rt|rejectedcertstoretype=", "Legacy - do not use.", _ => {} }, { "ip|issuercertstorepath=", "the path of the trusted issuer cert store.", s => this[LegacyCliConfigKeys.OpcIssuerCertStorePath] = s }, { "it|issuercertstoretype=", "Legacy - do not use.", _ => {} }, // Legacy unsupported { "si|iothubsendinterval=", "Legacy - do not use.", _ => {} }, { "tc|telemetryconfigfile=", "Legacy - do not use.", _ => {} }, { "ic|iotcentral=", "Legacy - do not use.", _ => {} }, { "mq|monitoreditemqueuecapacity=", "Legacy - do not use.", _ => {} }, { "ns|noshutdown=", "Legacy - do not use.", _ => {} }, { "rf|runforever", "Legacy - do not use.", _ => {} }, { "ms|iothubmessagesize=", "Legacy - do not use.", _ => {} }, { "pn|portnum=", "Legacy - do not use.", _ => {} }, { "pa|path=", "Legacy - do not use.", _ => {} }, { "lr|ldsreginterval=", "Legacy - do not use.", _ => {} }, { "ss|suppressedopcstatuscodes=", "Legacy - do not use.", _ => {} }, { "csr", "Legacy - do not use.", _ => {} }, { "ab|applicationcertbase64=", "Legacy - do not use.", _ => {} }, { "af|applicationcertfile=", "Legacy - do not use.", _ => {} }, { "pk|privatekeyfile=", "Legacy - do not use.", _ => {} }, { "pb|privatekeybase64=", "Legacy - do not use.", _ => {} }, { "cp|certpassword="******"Legacy - do not use.", _ => {} }, { "tb|addtrustedcertbase64=", "Legacy - do not use.", _ => {} }, { "tf|addtrustedcertfile=", "Legacy - do not use.", _ => {} }, { "ib|addissuercertbase64=", "Legacy - do not use.", _ => {} }, { "if|addissuercertfile=", "Legacy - do not use.", _ => {} }, { "rb|updatecrlbase64=", "Legacy - do not use.", _ => {} }, { "uc|updatecrlfile=", "Legacy - do not use.", _ => {} }, { "rc|removecert=", "Legacy - do not use.", _ => {} }, { "dt|devicecertstoretype=", "Legacy - do not use.", _ => {} }, { "dp|devicecertstorepath=", "Legacy - do not use.", _ => {} }, { "i|install", "Legacy - do not use.", _ => {} }, { "st|opcstacktracemask=", "Legacy - do not use.", _ => {} }, { "sd|shopfloordomain=", "Legacy - do not use.", _ => {} }, { "vc|verboseconsole=", "Legacy - do not use.", _ => {} }, { "as|autotrustservercerts=", "Legacy - do not use.", _ => {} } }; options.Parse(args); Config = ToAgentConfigModel(); LegacyCliModel = ToLegacyCliModel(); }
/// <summary> /// Asynchronous part of the main method of the app. /// </summary> public async static Task MainAsync(string[] args) { Logger = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Logger.Information($"OPC Publisher node configuration tool"); // command line options bool showHelp = false; string iotHubConnectionString = string.Empty; string iotHubPublisherDeviceName = string.Empty; string iotHubPublisherModuleName = string.Empty; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "ic|iotHubConnectionString=", "IoTHub owner or service connectionstring", (string s) => iotHubConnectionString = s }, { "id|iothubdevicename=", "IoTHub device name of the OPC Publisher", (string s) => iotHubPublisherDeviceName = s }, { "im|iothubmodulename=", "IoT Edge module name of the OPC Publisher which runs in the IoT Edge device specified by id/iothubdevicename", (string s) => iotHubPublisherModuleName = s }, { "pc|purgeconfig", "remove all configured nodes before pushing new ones", b => _purgeConfig = b != null }, { "bf|backupfile=", $"the filename to store the existing node configuration of OPC Publisher\nDefault: './{_backupFileName}'", (string l) => _backupFileName = l }, { "nc|nodeconfigfile=", $"the filename of the new node configuration to be set", (string l) => _nodeConfigFileName = l }, { "lf|logfile=", $"the filename of the logfile to use\nDefault: './{_logFileName}'", (string l) => _logFileName = l }, { "ll|loglevel=", $"the loglevel to use (allowed: fatal, error, warn, info, debug, verbose).\nDefault: info", (string l) => { List <string> logLevels = new List <string> { "fatal", "error", "warn", "info", "debug", "verbose" }; if (logLevels.Contains(l.ToLowerInvariant())) { _logLevel = l.ToLowerInvariant(); } else { throw new OptionException("The loglevel must be one of: fatal, error, warn, info, debug, verbose", "loglevel"); } } } }; IList <string> extraArgs = null; try { extraArgs = options.Parse(args); } catch (OptionException e) { // initialize logging InitLogging(); // show message Logger.Fatal(e, "Error in command line options"); // show usage Usage(options, args); return; } // initialize logging InitLogging(); // show usage if requested if (showHelp) { Usage(options); return; } // no extra options if (extraArgs.Count > 0) { for (int i = 1; i < extraArgs.Count; i++) { Logger.Error("Error: Unknown option: {0}", extraArgs[i]); } Usage(options, args); return; } // sanity check parameters if (string.IsNullOrEmpty(iotHubConnectionString) || string.IsNullOrEmpty(iotHubPublisherDeviceName)) { Logger.Fatal("For IoTHub communication an IoTHub connection string and the publisher devicename (and modulename) must be specified."); return; } Logger.Information($"IoTHub connectionstring: {iotHubConnectionString}"); if (string.IsNullOrEmpty(iotHubPublisherModuleName)) { Logger.Information($"OPC Publisher not running in IoT Edge."); Logger.Information($"IoTHub OPC Publisher device name: {iotHubPublisherDeviceName}"); } else { Logger.Information($"OPC Publisher running as IoT Edge module."); Logger.Information($"IoT Edge device name: {iotHubPublisherDeviceName}"); Logger.Information($"OPC Publisher module name: {iotHubPublisherModuleName}"); } CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken ct = cts.Token; // read new configuration if (!string.IsNullOrEmpty(_nodeConfigFileName)) { try { _configurationFileEntries = JsonConvert.DeserializeObject <List <PublisherConfigurationFileEntryLegacyModel> >(File.ReadAllText(_nodeConfigFileName)); } catch (Exception e) { Logger.Fatal(e, $"Error reading configuration file. Exiting..."); return; } Logger.Information($"The configuration file '{_nodeConfigFileName}' to be applied contains {_configurationFileEntries.Count} entries."); } // instantiate OPC Publisher interface Publisher publisher = new Publisher(iotHubConnectionString, iotHubPublisherDeviceName, iotHubPublisherModuleName, MAX_SHORT_WAIT_SEC, MAX_LONG_WAIT_SEC, ct); // read existing configuration List <PublisherConfigurationFileEntryModel> currentConfiguration = new List <PublisherConfigurationFileEntryModel>(); List <string> configuredEndpoints = publisher.GetConfiguredEndpoints(ct); if (configuredEndpoints.Count > 0) { Logger.Information($"OPC Publisher has the following node configuration:"); } else { Logger.Information($"OPC Publisher is not publishing any data."); } foreach (var configuredEndpoint in configuredEndpoints) { List <NodeModel> configuredNodesOnEndpoint = publisher.GetConfiguredNodesOnEndpoint(configuredEndpoint, ct); PublisherConfigurationFileEntryModel configEntry = new PublisherConfigurationFileEntryModel(); configEntry.EndpointUrl = new Uri(configuredEndpoint); List <OpcNodeOnEndpointModel> nodesOnEndpoint = new List <OpcNodeOnEndpointModel>(); Logger.Information($"For endpoint '{configuredEndpoint}' there are {configuredNodesOnEndpoint.Count} nodes configured."); foreach (var configuredNode in configuredNodesOnEndpoint) { Logger.Debug($"Id '{configuredNode.Id}', " + $"OpcPublishingInterval: {(configuredNode.OpcPublishingInterval == null ? "default" : configuredNode.OpcPublishingInterval.ToString())}, " + $"OpcSamplingInterval: {(configuredNode.OpcSamplingInterval == null ? "default" : configuredNode.OpcSamplingInterval.ToString())}"); OpcNodeOnEndpointModel opcNodeOnEndpoint = new OpcNodeOnEndpointModel(); opcNodeOnEndpoint.Id = configuredNode.Id; opcNodeOnEndpoint.OpcSamplingInterval = configuredNode.OpcSamplingInterval; opcNodeOnEndpoint.OpcPublishingInterval = configuredNode.OpcPublishingInterval; nodesOnEndpoint.Add(opcNodeOnEndpoint); } configEntry.OpcNodes = nodesOnEndpoint; currentConfiguration.Add(configEntry); } // save it on request if (!string.IsNullOrEmpty(_backupFileName) && currentConfiguration.Count > 0) { await File.WriteAllTextAsync(_backupFileName, JsonConvert.SerializeObject(currentConfiguration, Formatting.Indented)); Logger.Information($"The existing OPC Publisher node configuration was saved in '{_backupFileName}'"); } // remove existing configuration on request if (_purgeConfig) { publisher.UnpublishAllConfiguredNodes(ct); Logger.Information($"The existing node configuration was purged. OPC Publisher should no longer publish any data."); } // push new configuration, if required if (_configurationFileEntries != null) { var uniqueEndpoints = _configurationFileEntries.Select(e => e.EndpointUrl).Distinct(); Logger.Information($"The new node configuration will now be set in OPC Publisher."); foreach (var uniqueEndpoint in uniqueEndpoints) { var endpointConfigurationfileEntries = _configurationFileEntries.Where(e => e.EndpointUrl == uniqueEndpoint); List <NodeIdInfo> configurationNodeIdInfos = new List <NodeIdInfo>(); foreach (var endpointConfigurationFileEntry in endpointConfigurationfileEntries) { foreach (var opcNode in endpointConfigurationFileEntry.OpcNodes) { Logger.Debug($"Id '{opcNode.Id}', " + $"OpcPublishingInterval: {(opcNode.OpcPublishingInterval == null ? "default" : opcNode.OpcPublishingInterval.ToString())}, " + $"OpcSamplingInterval: {(opcNode.OpcSamplingInterval == null ? "default" : opcNode.OpcSamplingInterval.ToString())}"); NodeIdInfo nodeIdInfo = new NodeIdInfo(opcNode.Id); configurationNodeIdInfos.Add(nodeIdInfo); } } if (!publisher.PublishNodes(configurationNodeIdInfos, ct, uniqueEndpoint.AbsoluteUri)) { Logger.Error($"Not able to send the new node configuration to OPC Publisher."); } } } // done Logger.Information($"Done. Exiting...."); return; }
/// <summary> /// Asynchronous part of the main method of the app. /// </summary> public async static Task MainAsync(string[] args) { try { var shouldShowHelp = false; // shutdown token sources ShutdownTokenSource = new CancellationTokenSource(); // command line options Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "cf|configfile=", $"the filename containing action configuration.\nDefault: '{OpcActionConfigurationFilename}'", (string p) => OpcActionConfigurationFilename = p }, { "tc|testconnectivity", $"tests connectivity with the server.\nDefault: {TestConnectivity}", b => TestConnectivity = b != null }, { "tu|testunsecureconnectivity", $"tests connectivity with the server using an unsecured endpoint.\nDefault: {TestUnsecureConnectivity}", b => TestUnsecureConnectivity = b != null }, { "de|defaultendpointurl=", $"endpoint OPC UA server used as default.\nDefault: {DefaultEndpointUrl}", (string s) => DefaultEndpointUrl = s }, { "sw|sessionconnectwait=", $"specify the wait time in seconds we try to connect to disconnected endpoints and starts monitoring unmonitored items\nMin: 10\nDefault: {SessionConnectWait}", (int i) => { if (i > 10) { SessionConnectWait = i; } else { throw new OptionException("The sessionconnectwait must be greater than 10 sec", "sessionconnectwait"); } } }, { "di|diagnosticsinterval=", $"shows diagnostic info at the specified interval in seconds (need log level info). 0 disables diagnostic output.\nDefault: {DiagnosticsInterval}", (uint u) => DiagnosticsInterval = u }, { "lf|logfile=", $"the filename of the logfile to use.\nDefault: don't write logfile.", (string l) => _logFileName = l }, { "lt|logflushtimespan=", $"the timespan in seconds when the logfile should be flushed.\nDefault: {_logFileFlushTimeSpanSec} sec", (int s) => { if (s > 0) { _logFileFlushTimeSpanSec = TimeSpan.FromSeconds(s); } else { throw new Mono.Options.OptionException("The logflushtimespan must be a positive number.", "logflushtimespan"); } } }, { "ll|loglevel=", $"the loglevel to use (allowed: fatal, error, warn, info, debug, verbose).\nDefault: info", (string l) => { List <string> logLevels = new List <string> { "fatal", "error", "warn", "info", "debug", "verbose" }; if (logLevels.Contains(l.ToLowerInvariant())) { _logLevel = l.ToLowerInvariant(); } else { throw new Mono.Options.OptionException("The loglevel must be one of: fatal, error, warn, info, debug, verbose", "loglevel"); } } }, // opc configuration options { "ol|opcmaxstringlen=", $"the max length of a string opc can transmit/receive.\nDefault: {OpcMaxStringLength}", (int i) => { if (i > 0) { OpcMaxStringLength = i; } else { throw new OptionException("The max opc string length must be larger than 0.", "opcmaxstringlen"); } } }, { "ot|operationtimeout=", $"the operation timeout of the OPC UA client in ms.\nDefault: {OpcOperationTimeout}", (int i) => { if (i >= 0) { OpcOperationTimeout = i; } else { throw new OptionException("The operation timeout must be larger or equal 0.", "operationtimeout"); } } }, { "ct|createsessiontimeout=", $"specify the timeout in seconds used when creating a session to an endpoint. On unsuccessful connection attemps a backoff up to {OpcSessionCreationBackoffMax} times the specified timeout value is used.\nMin: 1\nDefault: {OpcSessionCreationTimeout}", (uint u) => { if (u > 1) { OpcSessionCreationTimeout = u; } else { throw new OptionException("The createsessiontimeout must be greater than 1 sec", "createsessiontimeout"); } } }, { "ki|keepaliveinterval=", $"specify the interval in seconds se send keep alive messages to the OPC servers on the endpoints it is connected to.\nMin: 2\nDefault: {OpcKeepAliveInterval}", (int i) => { if (i >= 2) { OpcKeepAliveInterval = i; } else { throw new OptionException("The keepaliveinterval must be greater or equal 2", "keepalivethreshold"); } } }, { "kt|keepalivethreshold=", $"specify the number of keep alive packets a server can miss, before the session is disconneced\nMin: 1\nDefault: {OpcKeepAliveDisconnectThreshold}", (uint u) => { if (u > 1) { OpcKeepAliveDisconnectThreshold = u; } else { throw new OptionException("The keepalivethreshold must be greater than 1", "keepalivethreshold"); } } }, { "csvOutput=|csvoutput=", $"filename to store readed values in CSV format.\nDefault: './{_csvFileName}'", (string path) => _csvFileName = path }, { "aa|autoaccept", $"trusts all servers we establish a connection to.\nDefault: {AutoAcceptCerts}", b => AutoAcceptCerts = b != null }, { "to|trustowncert", $"our own certificate is put into the trusted certificate store automatically.\nDefault: {TrustMyself}", t => TrustMyself = t != null }, // cert store options { "at|appcertstoretype=", $"the own application cert store type. \n(allowed values: Directory, X509Store)\nDefault: '{OpcOwnCertStoreType}'", (string s) => { if (s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) || s.Equals(CertificateStoreType.Directory, StringComparison.OrdinalIgnoreCase)) { OpcOwnCertStoreType = s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) ? CertificateStoreType.X509Store : CertificateStoreType.Directory; OpcOwnCertStorePath = s.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase) ? OpcOwnCertX509StorePathDefault : OpcOwnCertDirectoryStorePathDefault; } else { throw new OptionException(); } } }, { "ap|appcertstorepath=", $"the path where the own application cert should be stored\nDefault (depends on store type):\n" + $"X509Store: '{OpcOwnCertX509StorePathDefault}'\n" + $"Directory: '{OpcOwnCertDirectoryStorePathDefault}'", (string s) => OpcOwnCertStorePath = s }, { "tp|trustedcertstorepath=", $"the path of the trusted cert store\nDefault '{OpcTrustedCertDirectoryStorePathDefault}'", (string s) => OpcTrustedCertStorePath = s }, { "rp|rejectedcertstorepath=", $"the path of the rejected cert store\nDefault '{OpcRejectedCertDirectoryStorePathDefault}'", (string s) => OpcRejectedCertStorePath = s }, { "ip|issuercertstorepath=", $"the path of the trusted issuer cert store\nDefault '{OpcIssuerCertDirectoryStorePathDefault}'", (string s) => OpcIssuerCertStorePath = s }, { "csr", $"show data to create a certificate signing request\nDefault '{ShowCreateSigningRequestInfo}'", c => ShowCreateSigningRequestInfo = c != null }, { "ab|applicationcertbase64=", $"update/set this applications certificate with the certificate passed in as bas64 string", (string s) => { NewCertificateBase64String = s; } }, { "af|applicationcertfile=", $"update/set this applications certificate with the certificate file specified", (string s) => { if (File.Exists(s)) { NewCertificateFileName = s; } else { throw new OptionException($"The file '{s}' does not exist.", "applicationcertfile"); } } }, { "pb|privatekeybase64=", $"initial provisioning of the application certificate (with a PEM or PFX fomat) requires a private key passed in as base64 string", (string s) => { PrivateKeyBase64String = s; } }, { "pk|privatekeyfile=", $"initial provisioning of the application certificate (with a PEM or PFX fomat) requires a private key passed in as file", (string s) => { if (File.Exists(s)) { PrivateKeyFileName = s; } else { throw new OptionException($"The file '{s}' does not exist.", "privatekeyfile"); } } }, { "cp|certpassword="******"the optional password for the PEM or PFX or the installed application certificate", (string s) => { CertificatePassword = s; } }, { "tb|addtrustedcertbase64=", $"adds the certificate to the applications trusted cert store passed in as base64 string (multiple strings supported)", (string s) => { TrustedCertificateBase64Strings = ParseListOfStrings(s); } }, { "tf|addtrustedcertfile=", $"adds the certificate file(s) to the applications trusted cert store passed in as base64 string (multiple filenames supported)", (string s) => { TrustedCertificateFileNames = ParseListOfFileNames(s, "addtrustedcertfile"); } }, { "ib|addissuercertbase64=", $"adds the specified issuer certificate to the applications trusted issuer cert store passed in as base64 string (multiple strings supported)", (string s) => { IssuerCertificateBase64Strings = ParseListOfStrings(s); } }, { "if|addissuercertfile=", $"adds the specified issuer certificate file(s) to the applications trusted issuer cert store (multiple filenames supported)", (string s) => { IssuerCertificateFileNames = ParseListOfFileNames(s, "addissuercertfile"); } }, { "rb|updatecrlbase64=", $"update the CRL passed in as base64 string to the corresponding cert store (trusted or trusted issuer)", (string s) => { CrlBase64String = s; } }, { "uc|updatecrlfile=", $"update the CRL passed in as file to the corresponding cert store (trusted or trusted issuer)", (string s) => { if (File.Exists(s)) { CrlFileName = s; } else { throw new OptionException($"The file '{s}' does not exist.", "updatecrlfile"); } } }, { "rc|removecert=", $"remove cert(s) with the given thumbprint(s) (multiple thumbprints supported)", (string s) => { ThumbprintsToRemove = ParseListOfStrings(s); } }, // misc { "h|help", "show this message and exit", h => shouldShowHelp = h != null }, }; List <string> extraArgs = new List <string>(); try { // parse the command line extraArgs = options.Parse(args); } catch (OptionException e) { // initialize logging InitLogging(); // show message Logger.Fatal(e, "Error in command line options"); Environment.ExitCode = 1; Logger.Error($"Command line arguments: {String.Join(" ", args)}"); // show usage Usage(options); return; } // initialize logging InitLogging(); // show usage if requested if (shouldShowHelp) { Usage(options); return; } // validate and parse extra arguments if (extraArgs.Count > 0) { Logger.Error("Error in command line options"); Environment.ExitCode = 1; Logger.Error($"Command line arguments: {String.Join(" ", args)}"); Usage(options); return; } //show version Logger.Information($"{ProgramName} V{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion} starting up..."); Logger.Debug($"Informational version: V{(Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute).InformationalVersion}"); // allow canceling the application var quitEvent = new ManualResetEvent(false); try { Console.CancelKeyPress += (sender, eArgs) => { quitEvent.Set(); eArgs.Cancel = true; ShutdownTokenSource.Cancel(); }; } catch { } // init OPC configuration and tracing OpcApplicationConfiguration applicationStackConfiguration = new OpcApplicationConfiguration(); await applicationStackConfiguration.ConfigureAsync(); // read OPC action configuration OpcConfiguration.Init(); if (!await ReadOpcConfigurationAsync()) { return; } // add well known actions if (!await CreateOpcActionDataAsync()) { return; } // kick off OPC client activities await SessionStartAsync(); // initialize diagnostics Diagnostics.Init(); await OpcSessionsListSemaphore.WaitAsync(); var pendingOperations = OpcSessions.Sum(s => s.OpcActions.Count); OpcSessionsListSemaphore.Release(); while (pendingOperations > 0 && ShutdownTokenSource.IsCancellationRequested != true) { Logger.Information($"{pendingOperations} pending operation(s)."); Logger.Information(""); Logger.Information($"{ProgramName} is running. Press CTRL-C to quit."); Thread.Sleep(1000); await OpcSessionsListSemaphore.WaitAsync(); pendingOperations = OpcSessions.Sum(s => s.OpcActions.Count); OpcSessionsListSemaphore.Release(); } Logger.Information("No pending operations."); Logger.Information(""); ShutdownTokenSource.Cancel(); Logger.Information($"{ProgramName} is shutting down..."); // shutdown all OPC sessions await SessionShutdownAsync(); // shutdown diagnostics await ShutdownAsync(); ShutdownTokenSource = null; } catch (Exception e) { Logger.Fatal(e, e.StackTrace); Environment.ExitCode = 1; e = e.InnerException ?? null; while (e != null) { Logger.Fatal(e, e.StackTrace); e = e.InnerException ?? null; } Logger.Fatal($"{ProgramName} exiting... "); } }
public static int Main(string[] args) { Console.WriteLine(".Net Core OPC UA Complex Types Client sample"); // command line options bool showHelp = false; int stopTimeout = Timeout.Infinite; bool autoAccept = false; bool writeComplexInt = false; bool noTypes = false; bool noBrowse = false; bool verbose = false; bool json = false; bool jsonReversible = false; string username = null; string pw = null; string reverseConnectUrlString = null; Uri reverseConnectUrl = null; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "t|timeout=", "the number of seconds until the client stops.", (int t) => stopTimeout = t }, { "w|writeint", "Read and increment all complex types with an Int32.", w => writeComplexInt = w != null }, { "n|notypes", "Do not load the type system dictionary from the server.", n => noTypes = n != null }, { "b|nobrowse", "Do not browse the address space of the server.", n => noBrowse = n != null }, { "u|username="******"Username to access server.", (string n) => username = n }, { "p|password="******"Password to access server.", (string n) => pw = n }, { "v|verbose", "Verbose output.", v => verbose = v != null }, { "j|json", "Print custom nodes as Json.", j => json = j != null }, { "r|jsonreversible", "Use Json reversible encoding.", r => jsonReversible = r != null }, { "rc|reverseconnect=", "Connect using the reverse connection.", (string url) => reverseConnectUrlString = url }, }; IList <string> extraArgs = null; try { extraArgs = options.Parse(args); if (extraArgs.Count > 1) { foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } if (reverseConnectUrlString != null) { reverseConnectUrl = new Uri(reverseConnectUrlString); } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { // show some app description message Console.WriteLine("Usage: dotnet NetCoreConsoleClient.dll [OPTIONS] [ENDPOINTURL]"); Console.WriteLine(); // output the options Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } string endpointURL; if (extraArgs.Count == 0) { // use OPC UA .Net Sample server endpointURL = "opc.tcp://localhost:51210/UA/SampleServer"; } else { endpointURL = extraArgs[0]; } MySampleClient client = new MySampleClient(endpointURL, autoAccept, stopTimeout) { Verbose = verbose, LoadTypeSystem = !noTypes, BrowseAdddressSpace = !noBrowse, WriteComplexInt = writeComplexInt, PrintAsJson = json, JsonReversible = jsonReversible, Username = username, Password = pw, ReverseConnectUri = reverseConnectUrl }; return((int)client.Run()); }
/// <summary> /// Asynchronous part of the main method of the app. /// </summary> public static async Task MainAsync(string[] args) { Mono.Options.OptionSet options = InitCommandLineOptions(); InitAppLocation(); InitLogging(); List <string> extraArgs; try { // parse the command line extraArgs = options.Parse(args); } catch (OptionException e) { // show message Logger.Fatal(e, "Error in command line options"); Logger.Error($"Command line arguments: {string.Join(" ", args)}"); // show usage Usage(options); return; } // show usage if requested if (ShowHelp) { Usage(options); return; } // validate and parse extra arguments if (extraArgs.Count > 0) { Logger.Error("Error in command line options"); Logger.Error($"Command line arguments: {string.Join(" ", args)}"); Usage(options); return; } //show version var fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); Logger.Information($"{ProgramName} V{fileVersion.ProductMajorPart}.{fileVersion.ProductMinorPart}.{fileVersion.ProductBuildPart} starting up..."); Logger.Debug($"Informational version: V{(Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute)?.InformationalVersion}"); using var host = CreateHostBuilder(args); if (ShowPublisherConfigJsonIp || ShowPublisherConfigJsonPh) { StartWebServer(host); } try { await ConsoleServerAsync(args).ConfigureAwait(false); } catch (Exception ex) { Logger.Fatal(ex, "OPC UA server failed unexpectedly."); } Logger.Information("OPC UA server exiting..."); }
public static int Main(string[] args) { Console.WriteLine( (Utils.IsRunningOnMono() ? "Mono" : ".Net Core") + " OPC UA Console Client sample"); // command line options bool showHelp = false; int stopTimeout = Timeout.Infinite; bool autoAccept = false; Mono.Options.OptionSet options = new Mono.Options.OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "t|timeout=", "the number of seconds until the client stops.", (int t) => stopTimeout = t } }; IList <string> extraArgs = null; try { extraArgs = options.Parse(args); if (extraArgs.Count > 1) { foreach (string extraArg in extraArgs) { Console.WriteLine("Error: Unknown option: {0}", extraArg); showHelp = true; } } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } if (showHelp) { // show some app description message Console.WriteLine(Utils.IsRunningOnMono() ? "Usage: mono MonoConsoleClient.exe [OPTIONS] [ENDPOINTURL]" : "Usage: dotnet NetCoreConsoleClient.dll [OPTIONS] [ENDPOINTURL]"); Console.WriteLine(); // output the options Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return((int)ExitCode.ErrorInvalidCommandLine); } string endpointURL; if (extraArgs.Count == 0) { // use OPC UA .Net Sample server endpointURL = "opc.tcp://localhost:51210/UA/SampleServer"; } else { endpointURL = extraArgs[0]; } MySampleClient client = new MySampleClient(endpointURL, autoAccept, stopTimeout); client.Run(); return((int)MySampleClient.ExitCode); }