├── .dependabot └── config.yml ├── .gitignore ├── LICENSE ├── README.md ├── appwithalc ├── appwithalc │ ├── AssemblyExtensions.cs │ ├── Program.cs │ └── appwithalc.csproj ├── interfaces │ ├── IFoo.cs │ └── interfaces.csproj └── library │ ├── Foo.cs │ └── library.csproj ├── badsize ├── Program.cs ├── README.md ├── badsize.csproj └── badsize.sln ├── index-and-range ├── Program.cs └── index-and-range.csproj ├── readstdin ├── Program.cs └── readstdin.csproj ├── refstructforeach ├── Bar.cs ├── Foo.cs ├── FooHolder.cs ├── Program.cs └── refstructforeach.csproj ├── trace-assembly-loading ├── README.md ├── library │ ├── Class1.cs │ └── library.csproj ├── trace-assemblies-loading-time.png ├── trace-assemblies-loads.png └── trace-assembly-loading │ ├── Program.cs │ └── trace-assembly-loading.csproj ├── versioninfo-windowsforms ├── versioninfo.sln └── versioninfo │ ├── Form1.Designer.cs │ ├── Form1.cs │ ├── Form1.resx │ ├── Program.cs │ └── versioninfo.csproj └── versioninfo ├── Program.cs ├── README.md └── versioninfo.csproj /.dependabot/config.yml: -------------------------------------------------------------------------------- 1 | # Generated by https://github.com/richlander/dependadotnet 2 | version: 1 3 | 4 | update_configs: 5 | - package_manager: "dotnet:nuget" 6 | directory: "/readstdin" # readstdin.csproj 7 | update_schedule: "live" 8 | - package_manager: "dotnet:nuget" 9 | directory: "/refstructforeach" # refstructforeach.csproj 10 | update_schedule: "live" 11 | - package_manager: "dotnet:nuget" 12 | directory: "/versioninfo" # versioninfo.csproj 13 | update_schedule: "live" 14 | - package_manager: "dotnet:nuget" 15 | directory: "/appwithalc/appwithalc" # appwithalc.csproj 16 | update_schedule: "live" 17 | - package_manager: "dotnet:nuget" 18 | directory: "/appwithalc/interfaces" # interfaces.csproj 19 | update_schedule: "live" 20 | - package_manager: "dotnet:nuget" 21 | directory: "/appwithalc/library" # library.csproj 22 | update_schedule: "live" 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | 33 | # Visual Studio 2015/2017 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | 38 | # Visual Studio 2017 auto generated files 39 | Generated\ Files/ 40 | 41 | # MSTest test Results 42 | [Tt]est[Rr]esult*/ 43 | [Bb]uild[Ll]og.* 44 | 45 | # NUNIT 46 | *.VisualState.xml 47 | TestResult.xml 48 | 49 | # Build Results of an ATL Project 50 | [Dd]ebugPS/ 51 | [Rr]eleasePS/ 52 | dlldata.c 53 | 54 | # Benchmark Results 55 | BenchmarkDotNet.Artifacts/ 56 | 57 | # .NET Core 58 | project.lock.json 59 | project.fragment.lock.json 60 | artifacts/ 61 | 62 | # StyleCop 63 | StyleCopReport.xml 64 | 65 | # Files built by Visual Studio 66 | *_i.c 67 | *_p.c 68 | *_h.h 69 | *.ilk 70 | *.meta 71 | *.obj 72 | *.iobj 73 | *.pch 74 | *.pdb 75 | *.ipdb 76 | *.pgc 77 | *.pgd 78 | *.rsp 79 | *.sbr 80 | *.tlb 81 | *.tli 82 | *.tlh 83 | *.tmp 84 | *.tmp_proj 85 | *_wpftmp.csproj 86 | *.log 87 | *.vspscc 88 | *.vssscc 89 | .builds 90 | *.pidb 91 | *.svclog 92 | *.scc 93 | 94 | # Chutzpah Test files 95 | _Chutzpah* 96 | 97 | # Visual C++ cache files 98 | ipch/ 99 | *.aps 100 | *.ncb 101 | *.opendb 102 | *.opensdf 103 | *.sdf 104 | *.cachefile 105 | *.VC.db 106 | *.VC.VC.opendb 107 | 108 | # Visual Studio profiler 109 | *.psess 110 | *.vsp 111 | *.vspx 112 | *.sap 113 | 114 | # Visual Studio Trace Files 115 | *.e2e 116 | 117 | # TFS 2012 Local Workspace 118 | $tf/ 119 | 120 | # Guidance Automation Toolkit 121 | *.gpState 122 | 123 | # ReSharper is a .NET coding add-in 124 | _ReSharper*/ 125 | *.[Rr]e[Ss]harper 126 | *.DotSettings.user 127 | 128 | # JustCode is a .NET coding add-in 129 | .JustCode 130 | 131 | # TeamCity is a build add-in 132 | _TeamCity* 133 | 134 | # DotCover is a Code Coverage Tool 135 | *.dotCover 136 | 137 | # AxoCover is a Code Coverage Tool 138 | .axoCover/* 139 | !.axoCover/settings.json 140 | 141 | # Visual Studio code coverage results 142 | *.coverage 143 | *.coveragexml 144 | 145 | # NCrunch 146 | _NCrunch_* 147 | .*crunch*.local.xml 148 | nCrunchTemp_* 149 | 150 | # MightyMoose 151 | *.mm.* 152 | AutoTest.Net/ 153 | 154 | # Web workbench (sass) 155 | .sass-cache/ 156 | 157 | # Installshield output folder 158 | [Ee]xpress/ 159 | 160 | # DocProject is a documentation generator add-in 161 | DocProject/buildhelp/ 162 | DocProject/Help/*.HxT 163 | DocProject/Help/*.HxC 164 | DocProject/Help/*.hhc 165 | DocProject/Help/*.hhk 166 | DocProject/Help/*.hhp 167 | DocProject/Help/Html2 168 | DocProject/Help/html 169 | 170 | # Click-Once directory 171 | publish/ 172 | 173 | # Publish Web Output 174 | *.[Pp]ublish.xml 175 | *.azurePubxml 176 | # Note: Comment the next line if you want to checkin your web deploy settings, 177 | # but database connection strings (with potential passwords) will be unencrypted 178 | *.pubxml 179 | *.publishproj 180 | 181 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 182 | # checkin your Azure Web App publish settings, but sensitive information contained 183 | # in these scripts will be unencrypted 184 | PublishScripts/ 185 | 186 | # NuGet Packages 187 | *.nupkg 188 | # The packages folder can be ignored because of Package Restore 189 | **/[Pp]ackages/* 190 | # except build/, which is used as an MSBuild target. 191 | !**/[Pp]ackages/build/ 192 | # Uncomment if necessary however generally it will be regenerated when needed 193 | #!**/[Pp]ackages/repositories.config 194 | # NuGet v3's project.json files produces more ignorable files 195 | *.nuget.props 196 | *.nuget.targets 197 | 198 | # Microsoft Azure Build Output 199 | csx/ 200 | *.build.csdef 201 | 202 | # Microsoft Azure Emulator 203 | ecf/ 204 | rcf/ 205 | 206 | # Windows Store app package directories and files 207 | AppPackages/ 208 | BundleArtifacts/ 209 | Package.StoreAssociation.xml 210 | _pkginfo.txt 211 | *.appx 212 | *.appxbundle 213 | *.appxupload 214 | 215 | # Visual Studio cache files 216 | # files ending in .cache can be ignored 217 | *.[Cc]ache 218 | # but keep track of directories ending in .cache 219 | !?*.[Cc]ache/ 220 | 221 | # Others 222 | ClientBin/ 223 | ~$* 224 | *~ 225 | *.dbmdl 226 | *.dbproj.schemaview 227 | *.jfm 228 | *.pfx 229 | *.publishsettings 230 | orleans.codegen.cs 231 | 232 | # Including strong name files can present a security risk 233 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 234 | #*.snk 235 | 236 | # Since there are multiple workflows, uncomment next line to ignore bower_components 237 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 238 | #bower_components/ 239 | # ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true 240 | **/wwwroot/lib/ 241 | 242 | # RIA/Silverlight projects 243 | Generated_Code/ 244 | 245 | # Backup & report files from converting an old project file 246 | # to a newer Visual Studio version. Backup files are not needed, 247 | # because we have git ;-) 248 | _UpgradeReport_Files/ 249 | Backup*/ 250 | UpgradeLog*.XML 251 | UpgradeLog*.htm 252 | ServiceFabricBackup/ 253 | *.rptproj.bak 254 | 255 | # SQL Server files 256 | *.mdf 257 | *.ldf 258 | *.ndf 259 | 260 | # Business Intelligence projects 261 | *.rdl.data 262 | *.bim.layout 263 | *.bim_*.settings 264 | *.rptproj.rsuser 265 | *- Backup*.rdl 266 | 267 | # Microsoft Fakes 268 | FakesAssemblies/ 269 | 270 | # GhostDoc plugin setting file 271 | *.GhostDoc.xml 272 | 273 | # Node.js Tools for Visual Studio 274 | .ntvs_analysis.dat 275 | node_modules/ 276 | 277 | # Visual Studio 6 build log 278 | *.plg 279 | 280 | # Visual Studio 6 workspace options file 281 | *.opt 282 | 283 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 284 | *.vbw 285 | 286 | # Visual Studio LightSwitch build output 287 | **/*.HTMLClient/GeneratedArtifacts 288 | **/*.DesktopClient/GeneratedArtifacts 289 | **/*.DesktopClient/ModelManifest.xml 290 | **/*.Server/GeneratedArtifacts 291 | **/*.Server/ModelManifest.xml 292 | _Pvt_Extensions 293 | 294 | # Paket dependency manager 295 | .paket/paket.exe 296 | paket-files/ 297 | 298 | # FAKE - F# Make 299 | .fake/ 300 | 301 | # CodeRush personal settings 302 | .cr/personal 303 | 304 | # Python Tools for Visual Studio (PTVS) 305 | __pycache__/ 306 | *.pyc 307 | 308 | # Cake - Uncomment if you are using it 309 | # tools/** 310 | # !tools/packages.config 311 | 312 | # Tabs Studio 313 | *.tss 314 | 315 | # Telerik's JustMock configuration file 316 | *.jmconfig 317 | 318 | # BizTalk build output 319 | *.btp.cs 320 | *.btm.cs 321 | *.odx.cs 322 | *.xsd.cs 323 | 324 | # OpenCover UI analysis results 325 | OpenCover/ 326 | 327 | # Azure Stream Analytics local run output 328 | ASALocalRun/ 329 | 330 | # MSBuild Binary and Structured Log 331 | *.binlog 332 | 333 | # NVidia Nsight GPU debugger configuration file 334 | *.nvuser 335 | 336 | # MFractors (Xamarin productivity tool) working folder 337 | .mfractor/ 338 | 339 | # Local History for Visual Studio 340 | .localhistory/ 341 | 342 | # BeatPulse healthcheck temp database 343 | healthchecksdb 344 | 345 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 346 | MigrationBackup/ 347 | .vscode/ 348 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) .NET Foundation and Contributors 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Test Applications 2 | 3 | This is where I store my test apps so that I can have them on all my machines. 4 | 5 | Feel free to use them. -------------------------------------------------------------------------------- /appwithalc/appwithalc/AssemblyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | public static class AssemblyExtensions 4 | { 5 | public static T CreateInstance(this Assembly assembly, string typeName) 6 | { 7 | var instance = assembly.CreateInstance(typeName); 8 | T castedInstance = (T)instance; 9 | return castedInstance; 10 | } 11 | } -------------------------------------------------------------------------------- /appwithalc/appwithalc/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using System.Runtime.Loader; 5 | using interfaces; 6 | using static System.Console; 7 | 8 | namespace appwithalc 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | Console.WriteLine("Hello ALC(World)!"); 15 | 16 | // print all ALCs 17 | PrintAlcs(); 18 | 19 | // get default ALC 20 | PrintAssemblies(AssemblyLoadContext.Default); 21 | 22 | 23 | var libPath = Path.Combine( 24 | AppContext.BaseDirectory, 25 | "library.dll" 26 | ); 27 | 28 | // create custom load context 29 | // load "library" assembly 30 | var myAlcName = "my custom ALC"; 31 | WriteLine(); 32 | WriteLine($"Load \"library\" assembly via new \"{myAlcName}\" ALC"); ; 33 | var myAlc = new AssemblyLoadContext(myAlcName); 34 | // load library 35 | var library = myAlc.LoadFromAssemblyPath(libPath); 36 | var foo = library.CreateInstance("library.Foo"); 37 | WriteLine($"Foo: {foo.GetFoo()}"); 38 | 39 | PrintAssemblies(myAlc); 40 | 41 | // print all ALCs 42 | PrintAlcs(); 43 | 44 | // load "library" assembly via Assembly.LoadFile 45 | // this will create an ALC just for it and any dependencies not in the default ALC 46 | // it will not conflict with the custom PrivateContext ALC created above 47 | WriteLine(); 48 | WriteLine($"Load \"library\" assembly via Assembly.LoadFile"); ; 49 | var library2 = Assembly.LoadFile(libPath); 50 | var foo2 = library.CreateInstance("library.Foo"); 51 | WriteLine($"Foo: {foo2.GetFoo()}"); 52 | 53 | // print all ALCs 54 | PrintAlcs(); 55 | 56 | } 57 | 58 | private static void PrintAlcs() 59 | { 60 | WriteLine(); 61 | WriteLine("Enumerate over all ALCs:"); 62 | foreach (var alc in AssemblyLoadContext.All) 63 | { 64 | WriteLine(alc.Name); 65 | } 66 | } 67 | 68 | private static void PrintAssemblies(AssemblyLoadContext context) 69 | { 70 | WriteLine(); 71 | WriteLine($"Enumerate over all assemblies in \"{context.Name}\" ALC:"); 72 | foreach (var assembly in context.Assemblies) 73 | { 74 | WriteLine(assembly.FullName); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /appwithalc/appwithalc/appwithalc.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Exe 10 | netcoreapp3.0 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /appwithalc/interfaces/IFoo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace interfaces 4 | { 5 | public interface IFoo 6 | { 7 | string GetFoo(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /appwithalc/interfaces/interfaces.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /appwithalc/library/Foo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using interfaces; 3 | 4 | namespace library 5 | { 6 | public class Foo : IFoo 7 | { 8 | public string GetFoo() => "Hello"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /appwithalc/library/library.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | netstandard2.0 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /badsize/Program.cs: -------------------------------------------------------------------------------- 1 | using static System.Console; 2 | using System.CommandLine; 3 | using System.Runtime.ExceptionServices; 4 | using System.Diagnostics; 5 | 6 | var directory = new Argument("directory"); 7 | var ignore = new Option>("--ignore") 8 | { 9 | Description = "substrings to ignore" 10 | }; 11 | var platform = new Option("--platform"); 12 | 13 | var rootCommand = new RootCommand("Sample app for System.CommandLine"); 14 | rootCommand.AddOption(ignore); 15 | rootCommand.AddOption(platform); 16 | rootCommand.AddArgument(directory); 17 | 18 | 19 | rootCommand.SetHandler((ignore, platform, directory) => 20 | { 21 | App(directory, platform, ignore); 22 | }, 23 | ignore, platform, directory); 24 | 25 | return await rootCommand.InvokeAsync(args); 26 | 27 | void App(DirectoryInfo dir, string? platform, List? ignore) 28 | { 29 | const string DOCKERFILE = "Dockerfile"; 30 | 31 | if (!dir.Exists) 32 | { 33 | return; 34 | } 35 | 36 | foreach (var file in dir.EnumerateFiles()) 37 | { 38 | if (!file.Name.StartsWith(DOCKERFILE)) 39 | { 40 | WriteLine($"Not a Dockerfile: {file.Name}"); 41 | continue; 42 | } 43 | 44 | if (ignore is not null && IsMatch(file.Name, ignore)) 45 | { 46 | WriteLine($"Skip: {file.Name}"); 47 | continue; 48 | } 49 | 50 | WriteLine($"Build: {file.Name}"); 51 | BuildDockerfile(file, platform); 52 | } 53 | 54 | PrintImages(); 55 | } 56 | 57 | bool IsMatch(string target, List ignoreWords) 58 | { 59 | foreach (var word in ignoreWords) 60 | { 61 | if (target.Contains(word)) 62 | { 63 | return true; 64 | } 65 | } 66 | 67 | return false; 68 | } 69 | 70 | void BuildDockerfile(FileInfo file, string? platform) 71 | { 72 | var parent = file.Directory?.FullName ?? throw new Exception($"Cannot find parent directory of {file.FullName}"); 73 | var platformArg = platform is null ? string.Empty : $"--platform {platform}"; 74 | string args = $"build --pull {platformArg} -t {file.Name.ToLowerInvariant()} -f {file.FullName} {file.Directory.FullName}"; 75 | var command = Process.Start("docker", args); 76 | command.WaitForExit(); 77 | } 78 | 79 | void PrintImages() 80 | { 81 | string args = $"images --filter=reference=dockerfile*"; 82 | var command = Process.Start("docker", args); 83 | command.WaitForExit(); 84 | } 85 | -------------------------------------------------------------------------------- /badsize/README.md: -------------------------------------------------------------------------------- 1 | # Build All Dockerfiles and show Size 2 | 3 | This tool builds all the Dockerfiles in a directory and then shows their size. 4 | 5 | ## Usage 6 | 7 | ```bash 8 | dotnet run path-to-directory 9 | ``` 10 | 11 | Dockerfile substrings can be skipped with `--ignore`. 12 | 13 | ```bash 14 | dotnet run --ignore nano --ignore windows path-to-directory 15 | ``` 16 | 17 | ## Sort images by size 18 | 19 | ```bash 20 | docker images --filter="reference=dockerfile*" | sort -k7 -h 21 | ``` 22 | 23 | ## Deleting images 24 | 25 | ```bash 26 | docker rmi -f $(docker images --filter="reference=dockerfile*" -q) 27 | ``` 28 | -------------------------------------------------------------------------------- /badsize/badsize.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /badsize/badsize.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "badsize", "badsize.csproj", "{B9A0E91B-CF9A-4D38-8F52-6E45B93AB58C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B9A0E91B-CF9A-4D38-8F52-6E45B93AB58C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B9A0E91B-CF9A-4D38-8F52-6E45B93AB58C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B9A0E91B-CF9A-4D38-8F52-6E45B93AB58C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B9A0E91B-CF9A-4D38-8F52-6E45B93AB58C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {16DCF093-5B01-4CCA-B047-4129D4BCE5BE} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /index-and-range/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using static System.Console; 3 | 4 | namespace index_and_range 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | // start with int[] 11 | int[] arrayOfNums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 12 | int lastNum = arrayOfNums[^1]; // 10 13 | int[] subArrayOfNums = arrayOfNums[2..6]; // {3, 4, 5, 6} 14 | 15 | PrintValues(nameof(arrayOfNums), arrayOfNums); 16 | WriteLine($"{nameof(lastNum)}: {lastNum}"); 17 | PrintValues(nameof(subArrayOfNums), subArrayOfNums); 18 | 19 | // Create a Memory using arrayofNums as input 20 | // Create no-copy slices of the array 21 | Memory memoryOfNums = arrayOfNums; 22 | Memory lastTwoNums = memoryOfNums[^2..]; 23 | Memory middleNums = memoryOfNums[4..8]; // {5, 6, 7, 8} 24 | 25 | PrintValues(nameof(memoryOfNums), memoryOfNums.Span); 26 | PrintValues(nameof(lastTwoNums), lastTwoNums.Span); 27 | PrintValues(nameof(middleNums), middleNums.Span); 28 | 29 | 30 | // Create a substring using a range 31 | string myString = "0123456789ABCDEF"; 32 | string substring = myString[0..5]; // "01234" 33 | 34 | PrintValues(nameof(myString), myString); 35 | PrintValues(nameof(substring), substring); 36 | 37 | // Create a Memory using a range 38 | ReadOnlyMemory myChars = myString.AsMemory(); 39 | ReadOnlyMemory firstChars = myChars[0..5]; // {'0', '1', '2', '3', '4'} 40 | 41 | PrintValues(nameof(myChars), myChars.Span); 42 | PrintValues(nameof(firstChars), firstChars.Span); 43 | 44 | // Get an offset with an Index 45 | Index indexFromEnd = Index.FromEnd(3); // equivalent to [^3] 46 | int offsetFromLength = indexFromEnd.GetOffset(10); // 7 47 | int value = arrayOfNums[offsetFromLength]; // 8 48 | 49 | WriteLine($"{nameof(indexFromEnd)}: {indexFromEnd}"); 50 | WriteLine($"{nameof(offsetFromLength)}: {offsetFromLength}"); 51 | WriteLine($"{nameof(value)}: {value}"); 52 | 53 | // Get an offset with a Range 54 | Range rangeFromEnd = 5..^0; 55 | (int offset, int length) = rangeFromEnd.GetOffsetAndLength(10); // offset = 5, length = 5 56 | Memory values = memoryOfNums.Slice(offset, length); // {6, 7, 8, 9, 10} 57 | 58 | PrintValues(nameof(values), values.Span); 59 | } 60 | 61 | static void PrintValues(string name, Span values) 62 | { 63 | Write($"{name}: "); 64 | var first = true; 65 | foreach(var v in values) 66 | { 67 | if (!first) 68 | { 69 | Write($",{v}"); 70 | 71 | } 72 | else 73 | { 74 | first = false; 75 | Write(v); 76 | } 77 | } 78 | WriteLine(); 79 | } 80 | 81 | static void PrintValues(string name, ReadOnlySpan values) 82 | { 83 | Write($"{name}: "); 84 | var first = true; 85 | foreach (var v in values) 86 | { 87 | if (!first) 88 | { 89 | Write($",{v}"); 90 | 91 | } 92 | else 93 | { 94 | first = false; 95 | Write(v); 96 | } 97 | } 98 | WriteLine(); 99 | } 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /index-and-range/index-and-range.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.0 6 | index_and_range 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /readstdin/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace readstdin 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | // If using VS Code, ensure you do not use (for this app): 10 | // "console": "internalConsole" 11 | // Instead use: 12 | // "console": "externalTerminal" 13 | 14 | // To run this program, try: 15 | // dotnet run 16 | // echo foo | dotnet run 17 | 18 | string line = null; 19 | if (Console.IsInputRedirected) 20 | { 21 | while ((line = Console.In.ReadLine()) is object) 22 | { 23 | Console.WriteLine(line); 24 | } 25 | } 26 | else 27 | { 28 | Console.WriteLine("I wanted content from standard in and only got this useless string"); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /readstdin/readstdin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.0 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /refstructforeach/Bar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | public ref struct Bar 5 | { 6 | private Span _data; 7 | private int _index; 8 | 9 | public Bar(Span data) 10 | { 11 | _data = data; 12 | _index = -1; 13 | } 14 | 15 | public object Current => _data[_index]; 16 | public Span.Enumerator GetEnumerator() 17 | { 18 | return _data.GetEnumerator(); 19 | } 20 | } -------------------------------------------------------------------------------- /refstructforeach/Foo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | public ref struct Foo 5 | { 6 | private Span _data; 7 | 8 | public Foo(Span data) 9 | { 10 | _data = data; 11 | } 12 | 13 | public int this[int i] => _data[i]; 14 | 15 | public int Length => _data.Length; 16 | 17 | // Could have just made this return "Foo" instead of creating a new type 18 | // No one wants the IEnumerator methods on the main type, so a nested type is better 19 | // This is the pattern used by Span as well. 20 | // Avoids these boiler-plate methods showing up in intellisense 21 | public Enumerator GetEnumerator() 22 | { 23 | return new Enumerator(_data); 24 | } 25 | 26 | public ref struct Enumerator 27 | { 28 | private Span _data; 29 | private int _index; 30 | 31 | public Enumerator(Span data) 32 | { 33 | _data = data; 34 | _index = -1; 35 | } 36 | 37 | public object Current => _data[_index]; 38 | 39 | public bool MoveNext() 40 | { 41 | _index++; 42 | return _index < _data.Length; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /refstructforeach/FooHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public ref struct TwoFooHolder 4 | { 5 | Foo _one; 6 | Foo _two; 7 | 8 | public TwoFooHolder(Foo one, Foo two) 9 | { 10 | _one = one; 11 | _two = two; 12 | } 13 | 14 | public Foo this[int i] 15 | { 16 | get 17 | { 18 | if (i == 0) 19 | { 20 | return _one; 21 | } 22 | else if (i == 1) 23 | { 24 | return _two; 25 | } 26 | throw new ArgumentOutOfRangeException(); 27 | } 28 | } 29 | 30 | public Enumerator GetEnumerator() 31 | { 32 | return new Enumerator(this); 33 | } 34 | 35 | public ref struct Enumerator 36 | { 37 | private TwoFooHolder _holder; 38 | private int _index; 39 | 40 | public Enumerator(TwoFooHolder holder) 41 | { 42 | _holder = holder; 43 | _index = -1; 44 | } 45 | 46 | public Foo Current => (_index == 0) ? _holder._one : _holder._two; 47 | 48 | public bool MoveNext() 49 | { 50 | _index++; 51 | return _index < 2; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /refstructforeach/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using static System.Console; 3 | 4 | namespace spanforeach 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | // This app demonstrates various patterns for using 11 | // forach with ref structs. 12 | // ref structs cannot implement interfaces, so IEnumerable isn't an option 13 | Span data = new int[] { 0, 1, 2, 3, 4, 5, 6}; 14 | var foo = new Foo(data); 15 | var bar = new Bar(data[2..^1]); 16 | 17 | WriteLine("foreach over foo, using custom enumerator"); 18 | foreach (var f in foo) 19 | { 20 | Console.WriteLine(f); 21 | } 22 | 23 | WriteLine("foreach over bar, using spans enumerator"); 24 | foreach (var b in bar) 25 | { 26 | Console.WriteLine(b); 27 | } 28 | 29 | WriteLine("foreach over a span directly"); 30 | foreach (var s in data) 31 | { 32 | Console.WriteLine(s); 33 | } 34 | 35 | // create holder value for remaining examples 36 | var holder = new TwoFooHolder(foo, new Foo(data[3..^2])); 37 | 38 | WriteLine("foreach over two Foos"); 39 | foreach(var f in holder) 40 | { 41 | foreach(var num in f) 42 | { 43 | WriteLine(num); 44 | } 45 | } 46 | 47 | WriteLine("indexer access over two Foos"); 48 | for (int i = 0; i < 2;i++) 49 | { 50 | var f = holder[i]; 51 | foreach(var num in f) 52 | { 53 | WriteLine(num); 54 | } 55 | } 56 | 57 | WriteLine("Randomly access Foos"); 58 | for (int i = 0; i < 2;i++) 59 | { 60 | var foo1 = holder[i]; 61 | var foo2 = holder[(i+1) % 2]; 62 | 63 | WriteLine($"Foo1 length: {foo1.Length}; Foo2 length: {foo2.Length}"); 64 | } 65 | } 66 | } 67 | } 68 | 69 | /* 70 | Output: 71 | 72 | foreach over foo, using custom enumerator 73 | 0 74 | 1 75 | 2 76 | 3 77 | 4 78 | 5 79 | 6 80 | foreach over bar, using spans enumerator 81 | 2 82 | 3 83 | 4 84 | 5 85 | foreach over a span directly 86 | 0 87 | 1 88 | 2 89 | 3 90 | 4 91 | 5 92 | 6 93 | foreach over two Foos 94 | 0 95 | 1 96 | 2 97 | 3 98 | 4 99 | 5 100 | 6 101 | 3 102 | 4 103 | indexer access over two Foos 104 | 0 105 | 1 106 | 2 107 | 3 108 | 4 109 | 5 110 | 6 111 | 3 112 | 4 113 | Randomly access Foos 114 | Foo1 length: 7; Foo2 length: 2 115 | Foo1 length: 2; Foo2 length: 7 116 | */ 117 | -------------------------------------------------------------------------------- /refstructforeach/refstructforeach.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.0 6 | 8.0 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /trace-assembly-loading/README.md: -------------------------------------------------------------------------------- 1 | # Trace Assembly Loading with Event Pipe 2 | 3 | This application demonstrates how to trace assembly loading in running applications, using the [dotnet-trace tool](https://docs.microsoft.com/dotnet/core/diagnostics/dotnet-trace). 4 | 5 | Currently, this system does not collect events at launch, but only after the dotnet-trace tool has attached to the process. This sample app halts execution at launch, for the purpose of demonstration, so that assembly loads events and related information can be collected. 6 | 7 | > Note: This scenario requires .NET 5.0 and later. 8 | 9 | ## Install dotnet-trace 10 | 11 | First, you need to [install dotnet-trace](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace). Use the following commands to install dotnet-trace (which assumes you have the .NET SDK installed): 12 | 13 | ```console 14 | dotnet tool install --global dotnet-trace 15 | ``` 16 | 17 | ## Build and start the app 18 | 19 | Build and start the app (demonstrated on Windows): 20 | 21 | ```console 22 | C:\git\testapps\trace-assembly-loading\trace-assembly-loading>dotnet build 23 | C:\git\testapps\trace-assembly-loading\trace-assembly-loading>bin\Debug\netcoreapp5.0\trace-assembly-loading.exe 24 | Hello World! 25 | Assemblies loaded: 26 | trace-assembly-loading, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 27 | Press any key to continue ... 28 | ``` 29 | 30 | ## Attach dotnet-trace to the app 31 | 32 | In a separate window, launch dotnet-trace. You will need to find the process ID for `trace-assembly-loading.exe` in task manger (in something similar). 33 | 34 | ```console 35 | C:\Users\rich>tasklist | findstr trace 36 | trace-assembly-loading.ex 23212 Console 1 15,412 K 37 | C:\Users\rich>dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4:4 --process-id 23212 38 | 39 | Provider Name Keywords Level Enabled By 40 | Microsoft-Windows-DotNETRuntime 0x0000000000000004 Informational(4) --providers 41 | 42 | Process : C:\git\testapps\trace-assembly-loading\trace-assembly-loading\bin\Debug\netcoreapp5.0\trace-assembly-loading.exe 43 | Output File : C:\Users\rich\trace.nettrace 44 | 45 | [00:00:00:31] Recording trace 72.466 (KB) 46 | Press or to exit... 47 | 48 | Trace completed. 49 | ``` 50 | 51 | ## View trace file in PerfView 52 | 53 | You can [view the trace file in PerfView](https://docs.microsoft.com/dotnet/core/diagnostics/dotnet-trace#view-the-trace-captured-from-dotnet-trace) (for Windows). 54 | 55 | The following demonstrates viewing assembly load information in Perfview. You need to change the directory location in PerfView to where the `.nettrace` file exists. 56 | 57 | Assembly loads: 58 | 59 | ![Trace assemblies -- loads](trace-assemblies-loads.png) 60 | 61 | Assembly loading time: 62 | 63 | ![Trace assemblies -- load times](trace-assemblies-loading-time.png) 64 | -------------------------------------------------------------------------------- /trace-assembly-loading/library/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace library 4 | { 5 | public class Class1 6 | { 7 | public static string Foo = "Foo"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /trace-assembly-loading/library/library.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /trace-assembly-loading/trace-assemblies-loading-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richlander/testapps/4dd5a77ce4bad047326ff829fcd29741ea5738fb/trace-assembly-loading/trace-assemblies-loading-time.png -------------------------------------------------------------------------------- /trace-assembly-loading/trace-assemblies-loads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richlander/testapps/4dd5a77ce4bad047326ff829fcd29741ea5738fb/trace-assembly-loading/trace-assemblies-loads.png -------------------------------------------------------------------------------- /trace-assembly-loading/trace-assembly-loading/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Loader; 3 | using library; 4 | using static System.Console; 5 | 6 | namespace trace_assembly_loading 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | WriteLine("Hello World!"); 13 | PrintAssemblies(); 14 | WriteLine("Press any key to continue ..."); 15 | ReadKey(); 16 | WriteLine("Call into `library` assembly"); 17 | GetFoo(); 18 | PrintAssemblies(); 19 | } 20 | 21 | static void PrintAssemblies() 22 | { 23 | WriteLine("Assemblies loaded:"); 24 | foreach (var asm in AssemblyLoadContext.Default.Assemblies) 25 | { 26 | if (asm.FullName.StartsWith("System")) {continue;} 27 | WriteLine(asm.FullName); 28 | } 29 | } 30 | 31 | static string GetFoo() 32 | { 33 | return library.Class1.Foo; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /trace-assembly-loading/trace-assembly-loading/trace-assembly-loading.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Exe 9 | netcoreapp5.0 10 | trace_assembly_loading 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /versioninfo-windowsforms/versioninfo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30028.174 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "versioninfo", "versioninfo\versioninfo.csproj", "{1DFC878C-A53E-45F7-B3A4-622D9A0DAAA8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1DFC878C-A53E-45F7-B3A4-622D9A0DAAA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1DFC878C-A53E-45F7-B3A4-622D9A0DAAA8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1DFC878C-A53E-45F7-B3A4-622D9A0DAAA8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1DFC878C-A53E-45F7-B3A4-622D9A0DAAA8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {B0EBC47E-F3F9-4E5D-B501-BBB3D2C325CA} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /versioninfo-windowsforms/versioninfo/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsApp1 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.listView1 = new System.Windows.Forms.ListView(); 32 | this.SuspendLayout(); 33 | // 34 | // listView1 35 | // 36 | this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 37 | | System.Windows.Forms.AnchorStyles.Left) 38 | | System.Windows.Forms.AnchorStyles.Right))); 39 | this.listView1.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 40 | this.listView1.HideSelection = false; 41 | this.listView1.Location = new System.Drawing.Point(0, 0); 42 | this.listView1.Name = "listView1"; 43 | this.listView1.Size = new System.Drawing.Size(798, 452); 44 | this.listView1.TabIndex = 1; 45 | this.listView1.UseCompatibleStateImageBehavior = false; 46 | // 47 | // Form1 48 | // 49 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 50 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 51 | this.ClientSize = new System.Drawing.Size(800, 450); 52 | this.Controls.Add(this.listView1); 53 | this.Name = "Form1"; 54 | this.Text = ".NET Version Information"; 55 | this.Load += new System.EventHandler(this.Form1_Load); 56 | this.ResumeLayout(false); 57 | 58 | } 59 | 60 | #endregion 61 | 62 | private System.Windows.Forms.ListView listView1; 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /versioninfo-windowsforms/versioninfo/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | 13 | namespace WindowsFormsApp1 14 | { 15 | public partial class Form1 : Form 16 | { 17 | public Form1() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | private void Form1_Load(object sender, EventArgs e) 23 | { 24 | listView1.Columns.Add("Information"); 25 | listView1.Columns[0].Width = 1000; 26 | listView1.View = View.List; 27 | 28 | var collection = new ListViewItem[] 29 | { 30 | 31 | new ListViewItem("**Runtime Information**"), 32 | new ListViewItem($"{nameof(RuntimeInformation.FrameworkDescription)}: {RuntimeInformation.FrameworkDescription}"), 33 | new ListViewItem($"CoreCLR Build: {((AssemblyInformationalVersionAttribute[])typeof(object).Assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false))[0].InformationalVersion.Split('+')[0]}"), 34 | new ListViewItem($"CoreCLR Hash: {((AssemblyInformationalVersionAttribute[])typeof(object).Assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false))[0].InformationalVersion.Split('+')[1]}"), 35 | new ListViewItem($"CoreFX Build: {((AssemblyInformationalVersionAttribute[])typeof(Uri).Assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false))[0].InformationalVersion.Split('+')[0]}"), 36 | new ListViewItem($"CoreFX Hash: {((AssemblyInformationalVersionAttribute[])typeof(Uri).Assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false))[0].InformationalVersion.Split('+')[1]}"), 37 | new ListViewItem(""), 38 | new ListViewItem("**Environment info**"), 39 | new ListViewItem($"{nameof(Environment.OSVersion)}: {Environment.OSVersion}"), 40 | new ListViewItem($"{nameof(RuntimeInformation.OSDescription)}: {RuntimeInformation.OSDescription}"), 41 | new ListViewItem($"{nameof(RuntimeInformation.OSArchitecture)}: {RuntimeInformation.OSArchitecture}"), 42 | new ListViewItem($"{nameof(Environment.ProcessorCount)}: {Environment.ProcessorCount}") 43 | }; 44 | 45 | foreach(var item in collection) 46 | { 47 | listView1.Items.Add(item); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /versioninfo-windowsforms/versioninfo/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /versioninfo-windowsforms/versioninfo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace WindowsFormsApp1 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.SetHighDpiMode(HighDpiMode.SystemAware); 18 | Application.EnableVisualStyles(); 19 | Application.SetCompatibleTextRenderingDefault(false); 20 | Application.Run(new Form1()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /versioninfo-windowsforms/versioninfo/versioninfo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net5.0 6 | true 7 | 8 | 9 | -------------------------------------------------------------------------------- /versioninfo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | using static System.Console; 6 | 7 | namespace versioninfo 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | WriteLine("**.NET Core info**"); 14 | WriteLine($"{nameof(Environment.Version)}: {Environment.Version}"); 15 | WriteLine($"{nameof(RuntimeInformation.FrameworkDescription)}: {RuntimeInformation.FrameworkDescription}"); 16 | WriteLine($"Libraries version: {((AssemblyInformationalVersionAttribute[])typeof(object).Assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute),false))[0].InformationalVersion.Split('+')[0]}"); 17 | WriteLine($"Libraries hash: {((AssemblyInformationalVersionAttribute[])typeof(object).Assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false))[0].InformationalVersion.Split('+')[1]}"); 18 | WriteLine(); 19 | WriteLine("**Environment info**"); 20 | WriteLine($"{nameof(RuntimeInformation.OSDescription)}: {RuntimeInformation.OSDescription}"); 21 | WriteLine($"{nameof(Environment.OSVersion)}: {Environment.OSVersion}"); 22 | WriteLine($"{nameof(RuntimeInformation.OSArchitecture)}: {RuntimeInformation.OSArchitecture}"); 23 | WriteLine($"{nameof(Environment.ProcessorCount)}: {Environment.ProcessorCount}"); 24 | WriteLine(); 25 | 26 | if(RuntimeInformation.OSDescription.StartsWith("Linux") && Directory.Exists("/sys/fs/cgroup")) 27 | { 28 | WriteLine("**CGroup info**"); 29 | WriteLine($"cfs_quota_us: {System.IO.File.ReadAllLines("/sys/fs/cgroup/cpu/cpu.cfs_quota_us")[0]}"); 30 | WriteLine($"memory.limit_in_bytes: {System.IO.File.ReadAllLines("/sys/fs/cgroup/memory/memory.limit_in_bytes")[0]}"); 31 | WriteLine($"memory.usage_in_bytes: {System.IO.File.ReadAllLines("/sys/fs/cgroup/memory/memory.usage_in_bytes")[0]}"); 32 | 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /versioninfo/README.md: -------------------------------------------------------------------------------- 1 | See https://github.com/dotnet/core/blob/master/samples/dotnet-runtimeinfo/README.md 2 | -------------------------------------------------------------------------------- /versioninfo/versioninfo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | LatestMajor 7 | MIT 8 | Displays .NET version and environment information. 9 | 10 | 11 | 12 | --------------------------------------------------------------------------------