diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb97be1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# Click-Once directory +publish/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Microsoft Fakes +FakesAssemblies/ \ No newline at end of file diff --git a/FontManager.sln b/FontManager.sln new file mode 100644 index 0000000..ad12928 --- /dev/null +++ b/FontManager.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontMgr", "FontManager\FontMgr.csproj", "{B6CA95F5-306C-4860-B2B3-22511B0604B8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B6CA95F5-306C-4860-B2B3-22511B0604B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6CA95F5-306C-4860-B2B3-22511B0604B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6CA95F5-306C-4860-B2B3-22511B0604B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6CA95F5-306C-4860-B2B3-22511B0604B8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/FontManager/App.config b/FontManager/App.config new file mode 100644 index 0000000..8227adb --- /dev/null +++ b/FontManager/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/FontManager/CmdOptions.cs b/FontManager/CmdOptions.cs new file mode 100644 index 0000000..cdea86e --- /dev/null +++ b/FontManager/CmdOptions.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CommandLine; +using CommandLine.Text; +using System.Reflection; + +namespace TheWilds +{ + class CmdOptions + { + [OptionArray('i', "install", Required = false, HelpText = "Install the given fonts.", DefaultValue = new string[] { })] + public string[] InstallFiles { get; set; } + + + [ValueList(typeof(List))] + public IList ImplicitInstallFiles { get; set; } + + [OptionArray('u', "uninstall", Required = false, HelpText = "Uninstall the given fonts.", DefaultValue = new string[] { })] + public string[] UninstallFiles { get; set; } + + [Option('q', DefaultValue = false, HelpText = "Suppress all output.")] + public bool Quiet { get; set; } + + [HelpOption('?', "help", MutuallyExclusiveSet = "help")] + public string GetUsage() + { + var help = new HelpText + { + Heading = new HeadingInfo("Font Manager", Assembly.GetEntryAssembly().GetName().Version.ToSt‌​ring()), + AdditionalNewLineAfterOption = true, + AddDashesToOption = true + }; + help.AddPreOptionsLine(String.Format("{0}A simple utility for adding and removing system fonts in Windows.", Environment.NewLine)); + help.AddPreOptionsLine(String.Format("{0}Usage: {1} [* [-i *] [-u *]] [-q]", Environment.NewLine, Assembly.GetEntryAssembly().GetName().Name)); + help.AddOptions(this); + return help; + } + } +} diff --git a/FontManager/FodyWeavers.xml b/FontManager/FodyWeavers.xml new file mode 100644 index 0000000..2e6d4a7 --- /dev/null +++ b/FontManager/FodyWeavers.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FontManager/FontMgr.csproj b/FontManager/FontMgr.csproj new file mode 100644 index 0000000..66efb72 --- /dev/null +++ b/FontManager/FontMgr.csproj @@ -0,0 +1,103 @@ + + + + + Debug + AnyCPU + {B6CA95F5-306C-4860-B2B3-22511B0604B8} + Exe + Properties + TheWilds + FontMgr + v4.5.2 + 512 + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + app.manifest + + + + ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll + True + False + + + ..\packages\NLog.4.4.1\lib\net45\NLog.dll + True + False + + + + + + + + + + + + + + + + + + + + + + + Always + + + Designer + + + Designer + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/FontManager/NLog.config b/FontManager/NLog.config new file mode 100644 index 0000000..bcdaa13 --- /dev/null +++ b/FontManager/NLog.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/FontManager/NLog.xsd b/FontManager/NLog.xsd new file mode 100644 index 0000000..bbbacc4 --- /dev/null +++ b/FontManager/NLog.xsd @@ -0,0 +1,2723 @@ + + + + + + + + + + + + + + + Watch config file for changes and reload automatically. + + + + + Print internal NLog messages to the console. Default value is: false + + + + + Print internal NLog messages to the console error output. Default value is: false + + + + + Write internal NLog messages to the specified file. + + + + + Log level threshold for internal log messages. Default value is: Info. + + + + + Global log level threshold for application log messages. Messages below this level won't be logged.. + + + + + Pass NLog internal exceptions to the application. Default value is: false. + + + + + Write internal NLog messages to the the System.Diagnostics.Trace. Default value is: false + + + + + + + + + + + + + + Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). + + + + + + + + + + + + + + + + + Prefix for targets/layout renderers/filters/conditions loaded from this assembly. + + + + + Load NLog extensions from the specified file (*.dll) + + + + + Load NLog extensions from the specified assembly. Assembly name should be fully qualified. + + + + + + + + + + Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name* + + + + + Comma separated list of levels that this rule matches. + + + + + Minimum level that this rule matches. + + + + + Maximum level that this rule matches. + + + + + Level that this rule matches. + + + + + Comma separated list of target names. + + + + + Ignore further rules if this one matches. + + + + + Enable or disable logging rule. Disabled rules are ignored. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the file to be included. The name is relative to the name of the current config file. + + + + + Ignore any errors in the include file. + + + + + + + Variable name. + + + + + Variable value. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Number of log events that should be processed in a batch by the lazy writer thread. + + + + + Action to be taken when the lazy writer thread request queue count exceeds the set limit. + + + + + Limit on the number of requests in the lazy writer thread request queue. + + + + + Time in milliseconds to sleep between batches. + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Condition expression. Log events who meet this condition will cause a flush on the wrapped target. + + + + + + + + + + + + + + + + + Name of the target. + + + + + Number of log events to be buffered. + + + + + Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. + + + + + Indicates whether to use sliding timeout. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Encoding to be used. + + + + + Instance of that is used to format log messages. + + + + + End of line value if a newline is appended at the end of log message . + + + + + Maximum message size in bytes. + + + + + Indicates whether to append newline at the end of log message. + + + + + Action that should be taken if the will be more connections than . + + + + + Action that should be taken if the message is larger than maxMessageSize. + + + + + Indicates whether to keep connection open whenever possible. + + + + + Size of the connection cache (number of connections which are kept alive). + + + + + Maximum current connections. 0 = no maximum. + + + + + Network address. + + + + + Maximum queue size. + + + + + Indicates whether to include source info (file name and line number) in the information sent over the network. + + + + + NDC item separator. + + + + + Indicates whether to include stack contents. + + + + + Indicates whether to include call site (class and method name) in the information sent over the network. + + + + + AppInfo field. By default it's the friendly name of the current AppDomain. + + + + + Indicates whether to include NLog-specific extensions to log4j schema. + + + + + Indicates whether to include dictionary contents. + + + + + + + + + + + + + + + + + + + + + + + + + + + Layout that should be use to calcuate the value for the parameter. + + + + + Viewer parameter name. + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Indicates whether to use default row highlighting rules. + + + + + Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) + + + + + The encoding for writing messages to the . + + + + + Indicates whether the error stream (stderr) should be used instead of the output stream (stdout). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Condition that must be met in order to set the specified foreground and background color. + + + + + Background color. + + + + + Foreground color. + + + + + + + + + + + + + + + + Indicates whether to ignore case when comparing texts. + + + + + Regular expression to be matched. You must specify either text or regex. + + + + + Text to be matched. You must specify either text or regex. + + + + + Indicates whether to match whole words only. + + + + + Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. + + + + + Background color. + + + + + Foreground color. + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Indicates whether to send the log messages to the standard error instead of the standard output. + + + + + Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) + + + + + The encoding for writing messages to the . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. + + + + + Name of the connection string (as specified in <connectionStrings> configuration section. + + + + + Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. + + + + + Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. + + + + + Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. + + + + + Name of the database provider. + + + + + Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. + + + + + Indicates whether to keep the database connection open between the log events. + + + + + Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this. + + + + + Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. + + + + + Text of the SQL command to be run on each log level. + + + + + Type of the SQL command to be run on each log level. + + + + + + + + + + + + + + + + + + + + + + + Type of the command. + + + + + Connection string to run the command against. If not provided, connection string from the target is used. + + + + + Indicates whether to ignore failures. + + + + + Command text. + + + + + + + + + + + + + + Layout that should be use to calcuate the value for the parameter. + + + + + Database parameter name. + + + + + Database parameter precision. + + + + + Database parameter scale. + + + + + Database parameter size. + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Layout that renders event Category. + + + + + Layout that renders event ID. + + + + + Name of the Event Log to write to. This can be System, Application or any user-defined name. + + + + + Name of the machine on which Event Log service is running. + + + + + Value to be used as the event Source. + + + + + Action to take if the message is larger than the option. + + + + + Optional entrytype. When not set, or when not convertable to then determined by + + + + + Message length limit to write to the Event Log. + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Indicates whether to return to the first target after any successful write. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + File encoding. + + + + + Line ending mode. + + + + + Way file archives are numbered. + + + + + Name of the file to be used for an archive. + + + + + Indicates whether to automatically archive log files every time the specified time passes. + + + + + Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: + + + + + Indicates whether to compress archive files into the zip archive format. + + + + + Maximum number of archive files that should be kept. + + + + + Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. + + + + + Is the an absolute or relative path? + + + + + Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. + + + + + Is the an absolute or relative path? + + + + + Value indicationg whether file creation calls should be synchronized by a system global mutex. + + + + + Indicates whether the footer should be written only when the file is archived. + + + + + Name of the file to write to. + + + + + Value specifying the date format to use when archiving files. + + + + + Indicates whether to archive old log file on startup. + + + + + Indicates whether to create directories if they do not exist. + + + + + Indicates whether to enable log file(s) to be deleted. + + + + + File attributes (Windows only). + + + + + Indicates whether to delete old log file on startup. + + + + + Indicates whether to replace file contents on each write instead of appending log message at the end. + + + + + Indicates whether concurrent writes to the log file by multiple processes on the same host. + + + + + Indicates whether to keep log file open instead of opening and closing it on each logging event. + + + + + Maximum number of log filenames that should be stored as existing. + + + + + Indicates whether concurrent writes to the log file by multiple processes on different network hosts. + + + + + Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). + + + + + Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity. + + + + + Log file buffer size in bytes. + + + + + Indicates whether to automatically flush the file buffers after each log message. + + + + + Delay in milliseconds to wait before attempting to write to the file again. + + + + + Number of times the write is appended on the file before NLog discards the log message. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Condition expression. Log events who meet this condition will be forwarded to the wrapped target. + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Windows domain name to change context to. + + + + + Required impersonation level. + + + + + Type of the logon provider. + + + + + Logon Type. + + + + + User account password. + + + + + Indicates whether to revert to the credentials of the process instead of impersonating another user. + + + + + Username to change context to. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Interval in which messages will be written up to the number of messages. + + + + + Maximum allowed number of messages written per . + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Endpoint address. + + + + + Name of the endpoint configuration in WCF configuration file. + + + + + Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply) + + + + + Client ID. + + + + + Indicates whether to include per-event properties in the payload sent to the server. + + + + + Indicates whether to use binary message encoding. + + + + + + + + + + + + + + Layout that should be use to calculate the value for the parameter. + + + + + Name of the parameter. + + + + + Type of the parameter. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Text to be rendered. + + + + + Header. + + + + + Footer. + + + + + Indicates whether to send message as HTML instead of plain text. + + + + + Encoding to be used for sending e-mail. + + + + + Indicates whether to add new lines between log entries. + + + + + CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). + + + + + Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). + + + + + BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). + + + + + Mail message body (repeated for each log message send in one mail). + + + + + Mail subject. + + + + + Sender's email address (e.g. joe@domain.com). + + + + + Indicates whether NewLine characters in the body should be replaced with tags. + + + + + Priority used for sending mails. + + + + + Indicates the SMTP client timeout. + + + + + SMTP Server to be used for sending. + + + + + SMTP Authentication mode. + + + + + Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). + + + + + Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). + + + + + Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. + + + + + Port number that SMTP Server is listening on. + + + + + Indicates whether the default Settings from System.Net.MailSettings should be used. + + + + + Folder where applications save mail messages to be processed by the local SMTP server. + + + + + Specifies how outgoing email messages will be handled. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Encoding to be used when writing text to the queue. + + + + + Indicates whether to use the XML format when serializing message. This will also disable creating queues. + + + + + Indicates whether to check if a queue exists before writing to it. + + + + + Indicates whether to create the queue if it doesn't exists. + + + + + Label to associate with each message. + + + + + Name of the queue to write to. + + + + + Indicates whether to use recoverable messages (with guaranteed delivery). + + + + + + + + + + + + + + + + + Name of the target. + + + + + Class name. + + + + + Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Encoding to be used. + + + + + End of line value if a newline is appended at the end of log message . + + + + + Maximum message size in bytes. + + + + + Indicates whether to append newline at the end of log message. + + + + + Action that should be taken if the will be more connections than . + + + + + Action that should be taken if the message is larger than maxMessageSize. + + + + + Network address. + + + + + Size of the connection cache (number of connections which are kept alive). + + + + + Indicates whether to keep connection open whenever possible. + + + + + Maximum current connections. 0 = no maximum. + + + + + Maximum queue size. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Encoding to be used. + + + + + Instance of that is used to format log messages. + + + + + End of line value if a newline is appended at the end of log message . + + + + + Maximum message size in bytes. + + + + + Indicates whether to append newline at the end of log message. + + + + + Action that should be taken if the will be more connections than . + + + + + Action that should be taken if the message is larger than maxMessageSize. + + + + + Indicates whether to keep connection open whenever possible. + + + + + Size of the connection cache (number of connections which are kept alive). + + + + + Maximum current connections. 0 = no maximum. + + + + + Network address. + + + + + Maximum queue size. + + + + + Indicates whether to include source info (file name and line number) in the information sent over the network. + + + + + NDC item separator. + + + + + Indicates whether to include stack contents. + + + + + Indicates whether to include call site (class and method name) in the information sent over the network. + + + + + AppInfo field. By default it's the friendly name of the current AppDomain. + + + + + Indicates whether to include NLog-specific extensions to log4j schema. + + + + + Indicates whether to include dictionary contents. + + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + Indicates whether to perform layout calculation. + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Indicates whether performance counter should be automatically created. + + + + + Name of the performance counter category. + + + + + Counter help text. + + + + + Name of the performance counter. + + + + + Performance counter type. + + + + + The value by which to increment the counter. + + + + + Performance counter instance name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Default filter to be applied when no specific rule matches. + + + + + + + + + + + + + Condition to be tested. + + + + + Resulting filter to be applied when the condition matches. + + + + + + + + + + + + Name of the target. + + + + + + + + + + + + + + + Name of the target. + + + + + Number of times to repeat each log message. + + + + + + + + + + + + + + + + Name of the target. + + + + + Number of retries that should be attempted on the wrapped target in case of a failure. + + + + + Time to wait between retries in milliseconds. + + + + + + + + + + + + + + Name of the target. + + + + + + + + + + + + + + Name of the target. + + + + + + + + + + + + + + + Name of the target. + + + + + Layout used to format log messages. + + + + + + + + + + + + + + + + + + + + + + + + + Name of the target. + + + + + Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8. + + + + + Encoding. + + + + + Value whether escaping be done according to the old NLog style (Very non-standard) + + + + + Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) + + + + + Web service method name. Only used with Soap. + + + + + Web service namespace. Only used with Soap. + + + + + Protocol to be used when calling web service. + + + + + Web service URL. + + + + + Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ). + + + + + (optional) root namespace of the XML document, if POST of XML document chosen. (see and ). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Footer layout. + + + + + Header layout. + + + + + Body layout (can be repeated multiple times). + + + + + Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). + + + + + Column delimiter. + + + + + Quote Character. + + + + + Quoting mode. + + + + + Indicates whether CVS should include header. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layout of the column. + + + + + Name of the column. + + + + + + + + + + + + + + + + List of property names to exclude when is true + + + + + Option to include all properties from the log events + + + + + Option to render the empty object value {} + + + + + Option to suppress the extra spaces in the output json + + + + + + + + + + + + + + Determines wether or not this attribute will be Json encoded. + + + + + Layout that will be rendered as the attribute's value. + + + + + Name of the attribute. + + + + + + + + + + + + + + Footer layout. + + + + + Header layout. + + + + + Body layout (can be repeated multiple times). + + + + + + + + + + + + + + + + + + + + + Layout text. + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Condition expression. + + + + + + + + + + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + Substring to be matched. + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + String to compare the layout to. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + Substring to be matched. + + + + + + + + + + + + + + + + + Action to be taken when filter matches. + + + + + String to compare the layout to. + + + + + Indicates whether to ignore case when comparing strings. + + + + + Layout to be used to filter log messages. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FontManager/Program.cs b/FontManager/Program.cs new file mode 100644 index 0000000..5ad83e5 --- /dev/null +++ b/FontManager/Program.cs @@ -0,0 +1,284 @@ +using Microsoft.Win32; +using NLog; +using System; +using System.Collections.Generic; +using System.Drawing.Text; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; + +namespace TheWilds +{ + + /// + /// Font Manager is a simple program that simplifies the ability to add and remove + /// fonts for a Windows system from a command line. It has the benefit of being very + /// fast in comparison to using the Windows Shell COM object. + /// + /// The main ideas from this code were borrowed from KYRIACOSS at http://pastebin.com/C99TmXBn. + /// This code pasting was referenced on StackOverflow at http://stackoverflow.com/a/29334492/277798. + /// + class FontManager + { + /// + /// The path in HKLM where the fonts are registered. + /// + private const string FONT_REG_PATH = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"; + + /// + /// Used to tell SendMessage() to broadcast that a font change has occurred. + /// + private const int WM_FONTCHANGE = 0x1D; + + /// + /// Used to tell SendMessage() to broadcast to all top-level applications that a change has occurred. + /// + private const int HWND_BROADCAST = 0xffff; + + /// + /// Notifies the the Windows graphics system that a font has been added. + /// + /// A string that names a font resource file. Use full path name. To add a font whose information comes from several resource files, have lpszFileName point to a string with the file names separated by a "|" --for example, abcxxxxx.pfm | abcxxxxx.pfb. + /// If the function succeeds, the return value specifies the number of fonts added. If the function fails, the return value is zero. No extended error information is available. + [DllImport("gdi32.dll")] + private static extern int AddFontResource(string lpszFilename); + + /// + /// Notifies the the Windows graphics system that a font has been removed. + /// + /// A string that names a font resource file. Use full path name. + /// + [DllImport("gdi32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool RemoveFontResource(string lpszFilename); + + /// + /// Notify other applications on the system when a change has happened. In the case + /// of this program it notifies them when a font has been added or removed. + /// + /// A handle to the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST ((HWND)0xffff), the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows. + /// The message to be sent. For lists of the system-provided messages, see ( System-Defined Messages | https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx#system_defined ) . + /// Additional message-specific information. + /// Additional message-specific information. + /// The return value specifies the result of the message processing; it depends on the message sent. + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); + + /// + /// The logger is used for handling Console output as well as debug information. + /// + private static Logger logger = LogManager.GetCurrentClassLogger(); + + /// + /// The main entrypoint for the application. + /// + /// All command-line arguments. + static void Main(string[] args) + { + ConfigureLogger(); + var options = new CmdOptions(); + + if (CommandLine.Parser.Default.ParseArgumentsStrict(args, options)) + { + if (options.Quiet) + { + // Remove all Console logging targets. + NLog.Config.LoggingRule[] rules = LogManager.Configuration.LoggingRules.Where(r => r.Targets.Where(t => t is NLog.Targets.ConsoleTarget).Count() > 0).ToArray(); + foreach (var rule in rules) + { + LogManager.Configuration.LoggingRules.Remove(rule); + } + + LogManager.ReconfigExistingLoggers(); + } + + IEnumerable installFiles = options.InstallFiles.Concat(options.ImplicitInstallFiles); + foreach (string file in installFiles) + { + string FullPath = Path.GetFullPath(file); + + if (!File.Exists(FullPath)) + { + logger.Warn("'{0}' does not exist. Unable to install.", FullPath); + } else + { + if (InstallFont(FullPath)) + { + logger.Info("Installed '{0}'", Path.GetFileName(FullPath)); + } + } + } + + foreach (string file in options.UninstallFiles) + { + if (UninstallFont(file)) + { + logger.Info("Uninstalled '{0}'", file); + } + } + } + } + + /// + /// Define defaults for logger if there is no config file present. + /// + private static void ConfigureLogger() + { + if (!File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "NLog.config"))) + { + NLog.Targets.ConsoleTarget console = new NLog.Targets.ConsoleTarget("WriteLine"); + console.Layout = new NLog.Layouts.SimpleLayout("${message}"); + LogManager.Configuration = new NLog.Config.LoggingConfiguration(); + LogManager.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, console); + LogManager.ReconfigExistingLoggers(); + } + } + + + /// + /// Installs the specified font on the system. + /// + /// The path to the font file to install. This could be an absolute + /// path or a relative path from the application. + /// True if the font was installed. False if it was not installed. + private static bool InstallFont(string FontPath) + { + bool installed = false; + + string FontName = Path.GetFileName(FontPath); + + // Creates the full path where your font will be installed + var fontDestination = Path.Combine(System.Environment.GetFolderPath + (System.Environment.SpecialFolder.Fonts), FontName); + + logger.Debug("Attempting to install '{0}' into '{1}'", FontName, fontDestination); + + if (!File.Exists(fontDestination)) + { + logger.Debug("Copying '{0}' to '{1}'", FontPath, fontDestination); + + // Copies font to destination + try + { + System.IO.File.Copy(FontPath, fontDestination); + } + catch (Exception ex) + { + logger.Error(ex.Message); + + return false; + } + + logger.Debug("Retrieving font name from '{0}'", fontDestination); + + // Retrieves font name + // Makes sure you reference System.Drawing.Text + PrivateFontCollection fontCol = new PrivateFontCollection(); + fontCol.AddFontFile(fontDestination); + var actualFontName = fontCol.Families[0].Name; + + logger.Debug("Retrieved font name is '{0}'", actualFontName); + + logger.Debug(@"Setting 'HKLM\{0} [{1}]' = '{2}'.", FONT_REG_PATH, actualFontName, FontName); + + //Add registry entry + Registry.SetValue(String.Format(@"HKEY_LOCAL_MACHINE\{0}", FONT_REG_PATH), actualFontName, FontName, RegistryValueKind.String); + + logger.Debug("Calling gdi32.dll::AddFontResource('{0}')", fontDestination); + + //Add font + AddFontResource(fontDestination); + + logger.Debug("Using user32.dll::SendMessage() to notify other apps that a font change has happend."); + + SendMessage(new IntPtr(HWND_BROADCAST), WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero); + + installed = true; + } else + { + logger.Debug("Did not install the font because it already exists in '{0}'", fontDestination); + } + + return installed; + } + + /// + /// Uninstall a font with the given file name. + /// + /// The name of the font file to uninstall. This could be just a file name + /// or a full path to a font file. If it is a full path, it will extract the filename from the + /// path and attempt to uninstall a font with that file name from the system's font folder. + /// True if the font was uninstalled. False if it was not. + private static bool UninstallFont(string FileName) + { + bool uninstalled = false; + + string FontFileName = Path.GetFileName(FileName); + + // Creates the full path where your font will be uninstalled + var systemFontPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), FontFileName); + + logger.Debug("Attempting to uninstall '{0}'", systemFontPath); + + if (File.Exists(systemFontPath)) + { + + logger.Debug("Calling gdi32.dll::RemoveFontResource('{0}')", systemFontPath); + + bool result = RemoveFontResource(systemFontPath); + + + logger.Debug("'{0}' does exist. Attempting to delete."); + + try + { + System.IO.File.Delete(systemFontPath); + } + catch (UnauthorizedAccessException ex) + { + logger.Error(ex.Message); + + return false; + } + + logger.Debug(@"Searching for any keys in 'HKLM\{0}' that reference '{1}' so they can be deleted.", FONT_REG_PATH, FontFileName); + + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(FONT_REG_PATH, true)) + { + if (key != null) + { + string[] names = key.GetValueNames(); + + // Delete all registry keys that point to the font file. + foreach (string name in names) + { + if (key.GetValueKind(name) == RegistryValueKind.String) + { + string namevalue = (string)key.GetValue(name); + + if (namevalue.ToLower().Trim() == FontFileName.ToLower().Trim()) + { + logger.Debug(@"Deleting 'HKLM\{0} [{1}]' because it was referencing '{2}'", FONT_REG_PATH, name, FontFileName); + + key.DeleteValue(name); + } + } + + } + } + } + + logger.Debug("Using user32.dll::SendMessage() to notify other apps that a font change has happend."); + + SendMessage(new IntPtr(HWND_BROADCAST), WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero); + + uninstalled = true; + } else + { + logger.Debug("Did not uninstall '{0}' because it did not exist on the system.", systemFontPath); + } + + return uninstalled; + } + } +} diff --git a/FontManager/Properties/AssemblyInfo.cs b/FontManager/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ae19573 --- /dev/null +++ b/FontManager/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("Font Manager")] +[assembly: AssemblyDescription("Adds and removes fonts from the system.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("The Wilds")] +[assembly: AssemblyProduct("Font Manager")] +[assembly: AssemblyCopyright("Copyright © The Wilds 2017")] +[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("b6ca95f5-306c-4860-b2b3-22511b0604b8")] + +// 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("0.5.*")] diff --git a/FontManager/app.manifest b/FontManager/app.manifest new file mode 100644 index 0000000..4670159 --- /dev/null +++ b/FontManager/app.manifest @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FontManager/packages.config b/FontManager/packages.config new file mode 100644 index 0000000..767f083 --- /dev/null +++ b/FontManager/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9ff157 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Commmand-line Font Manager for Windows + +This utility makes it very easy and fast to add and remove fonts from Windows from the +command line. Traditionally this has been cumbersome and at times required user interaction +for it to work. + +At this point, this utility is very basic and still considered beta as it has not been +battle tested. However, for the normal use case it works very well. + +Usage +---- + +`FontMtr.exe [* [-i|-install ] [-u|-uninstall ]]` + +_Examples_ + +* `FontMgr.exe -i fontfile.ttf` +* `FontMgr.exe -u fontb.ttf` +* `FontMgr.exe fontfile.ttf fontb.ttf hello.ttf -q` - Installs all three fonts + and supresses the output. +* `FontMgr.exe -?` - Prints help +* `FontMgr.exe -i C:\Users\user\Desktop\fontname.ttf otherfont.ttf` - Installs + both fonts onto the system. + +Additional Notes +---- + +* If a font file of the same name already exists, FontMgr.exe will just skip it. At present + There is no functionality to force it to overwrite or install. \ No newline at end of file