├── .gitattributes ├── .gitignore ├── ExampleProjects ├── VS2013 │ ├── ClassLibrary1 │ │ ├── Class1.cs │ │ ├── ClassLibrary1.csproj │ │ └── Properties │ │ │ └── AssemblyInfo.cs │ ├── ClassLibrary2 │ │ ├── Class1.cs │ │ ├── ClassLibrary2.csproj │ │ └── Properties │ │ │ └── AssemblyInfo.cs │ ├── ConsoleApplication1 │ │ ├── App.config │ │ ├── ConsoleApplication1.csproj │ │ ├── Program.cs │ │ └── Properties │ │ │ └── AssemblyInfo.cs │ └── VS2013.sln └── vs2019 │ ├── AspNetCore3.1 │ ├── AspNetCore3.1.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json │ ├── ClassLibraryNetFramework │ ├── Class1.cs │ ├── ClassLibraryNetFramework.csproj │ └── Properties │ │ └── AssemblyInfo.cs │ ├── ClassLibraryNetStandard │ ├── Class1.cs │ └── ClassLibraryNetStandard.csproj │ ├── Database1 │ └── Database1.sqlproj │ └── VS2019.sln ├── README.md ├── References ├── Microsoft.VisualStudio.Shell.11.0.dll └── Microsoft.VisualStudio.Shell.Framework.dll ├── Src ├── TargetFrameworkMigrator │ ├── Annotations.cs │ ├── Frameworks.xml │ ├── GlobalSuppressions.cs │ ├── Guids.cs │ ├── Key.snk │ ├── Migrator.cs │ ├── PkgCmdID.cs │ ├── ProjectsUpdateList.Designer.cs │ ├── ProjectsUpdateList.cs │ ├── ProjectsUpdateList.resx │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Resources │ │ ├── Images.png │ │ └── Package.ico │ ├── SortableBindingList.cs │ ├── TargetFrameworkMigrator.csproj │ ├── TargetFrameworkMigrator.vsct │ ├── TargetFrameworkMigratorPackage.cs │ └── VSPackage.resx └── TargetFrameworkMigratorVSIX │ ├── Properties │ └── AssemblyInfo.cs │ ├── TargetFrameworkMigratorVSIX.csproj │ ├── icon.png │ ├── preview.png │ └── source.extension.vsixmanifest ├── TargetFrameworkMigrator.sln ├── TargetFrameworkMigrator.sln.DotSettings ├── Tests ├── IntegrationTests.testsettings ├── TargetFrameworkMigrator_IntegrationTests │ ├── IntegrationTest Library │ │ ├── NativeMethods.cs │ │ ├── Utils.cs │ │ └── WindowPurger.cs │ ├── Key.snk │ ├── MenuItemTest.cs │ ├── PackageTest.cs │ ├── SignOff-Tests │ │ ├── CPPProjectTests.cs │ │ ├── CSharpProjectTests.cs │ │ ├── SolutionTests.cs │ │ └── VBProjectTests.cs │ └── TargetFrameworkMigrator_IntegrationTests.csproj ├── TargetFrameworkMigrator_UnitTests │ ├── Key.snk │ ├── MenuItemTests │ │ ├── MenuItemCallback.cs │ │ └── UIShellServiceMock.cs │ ├── PackageTest.cs │ └── TargetFrameworkMigrator_UnitTests.csproj └── UnitTests.testsettings └── appveyor.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | .vs 44 | 45 | # Build results 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | *_i.c 49 | *_p.c 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.vspscc 64 | .builds 65 | *.dotCover 66 | 67 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 68 | #packages/ 69 | 70 | # Visual C++ cache files 71 | ipch/ 72 | *.aps 73 | *.ncb 74 | *.opensdf 75 | *.sdf 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | 81 | # ReSharper is a .NET coding add-in 82 | _ReSharper* 83 | 84 | # Installshield output folder 85 | [Ee]xpress 86 | 87 | # DocProject is a documentation generator add-in 88 | DocProject/buildhelp/ 89 | DocProject/Help/*.HxT 90 | DocProject/Help/*.HxC 91 | DocProject/Help/*.hhc 92 | DocProject/Help/*.hhk 93 | DocProject/Help/*.hhp 94 | DocProject/Help/Html2 95 | DocProject/Help/html 96 | 97 | # Click-Once directory 98 | publish 99 | 100 | # Others 101 | [Bb]in 102 | [Oo]bj 103 | sql 104 | TestResults 105 | *.Cache 106 | ClientBin 107 | stylecop.* 108 | ~$* 109 | *.dbmdl 110 | Generated_Code #added for RIA/Silverlight projects 111 | 112 | # Backup & report files from converting an old project file to a newer 113 | # Visual Studio version. Backup files are not needed, because we have git ;-) 114 | _UpgradeReport_Files/ 115 | Backup*/ 116 | UpgradeLog*.XML 117 | 118 | 119 | 120 | ############ 121 | ## Windows 122 | ############ 123 | 124 | # Windows image file caches 125 | Thumbs.db 126 | 127 | # Folder config file 128 | Desktop.ini 129 | 130 | 131 | ############# 132 | ## Python 133 | ############# 134 | 135 | *.py[co] 136 | 137 | # Packages 138 | *.egg 139 | *.egg-info 140 | dist 141 | build 142 | eggs 143 | parts 144 | bin 145 | var 146 | sdist 147 | develop-eggs 148 | .installed.cfg 149 | 150 | # Installer logs 151 | pip-log.txt 152 | 153 | # Unit test / coverage reports 154 | .coverage 155 | .tox 156 | 157 | #Translations 158 | *.mo 159 | 160 | #Mr Developer 161 | .mr.developer.cfg 162 | 163 | # Mac crap 164 | .DS_Store 165 | 166 | /packages -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ClassLibrary1/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClassLibrary1 8 | { 9 | public class Class1 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ClassLibrary1/ClassLibrary1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D0A85A17-68B1-4C74-A0CB-07C2B1EF071E} 8 | Library 9 | Properties 10 | ClassLibrary1 11 | ClassLibrary1 12 | v4.5.1 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ClassLibrary1/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ClassLibrary1")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ClassLibrary1")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("35e527a5-b7bc-4050-aa9a-b4f95a31d956")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ClassLibrary2/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ClassLibrary2 7 | { 8 | public class Class1 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ClassLibrary2/ClassLibrary2.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 12.0 6 | Debug 7 | AnyCPU 8 | {8bbca690-0bc7-4e66-af12-46a0a50fb3cd} 9 | Library 10 | Properties 11 | ClassLibrary2 12 | ClassLibrary2 13 | en-US 14 | 512 15 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 16 | Profile32 17 | v4.6 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ClassLibrary2/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ClassLibrary2")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ClassLibrary2")] 14 | [assembly: AssemblyCopyright("Copyright © 2019")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ConsoleApplication1/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ConsoleApplication1/ConsoleApplication1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4E04E2F9-B7C6-4DE4-941A-2D2591B396C3} 8 | Exe 9 | Properties 10 | ConsoleApplication1 11 | ConsoleApplication1 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ConsoleApplication1/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ConsoleApplication1 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/ConsoleApplication1/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleApplication1")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleApplication1")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("14fc5154-2d3b-4421-813f-9a0d3399cbe4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ExampleProjects/VS2013/VS2013.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.csproj", "{4E04E2F9-B7C6-4DE4-941A-2D2591B396C3}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{D0A85A17-68B1-4C74-A0CB-07C2B1EF071E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary2", "ClassLibrary2\ClassLibrary2.csproj", "{8BBCA690-0BC7-4E66-AF12-46A0A50FB3CD}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {4E04E2F9-B7C6-4DE4-941A-2D2591B396C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {4E04E2F9-B7C6-4DE4-941A-2D2591B396C3}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {4E04E2F9-B7C6-4DE4-941A-2D2591B396C3}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {4E04E2F9-B7C6-4DE4-941A-2D2591B396C3}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {D0A85A17-68B1-4C74-A0CB-07C2B1EF071E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {D0A85A17-68B1-4C74-A0CB-07C2B1EF071E}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {D0A85A17-68B1-4C74-A0CB-07C2B1EF071E}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {D0A85A17-68B1-4C74-A0CB-07C2B1EF071E}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {8BBCA690-0BC7-4E66-AF12-46A0A50FB3CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {8BBCA690-0BC7-4E66-AF12-46A0A50FB3CD}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {8BBCA690-0BC7-4E66-AF12-46A0A50FB3CD}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {8BBCA690-0BC7-4E66-AF12-46A0A50FB3CD}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/AspNetCore3.1/AspNetCore3.1.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | AspNetCore3._1 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/AspNetCore3.1/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace AspNetCore3._1 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/AspNetCore3.1/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:54685", 7 | "sslPort": 44332 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "AspNetCore3._1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/AspNetCore3.1/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Hosting; 10 | 11 | namespace AspNetCore3._1 12 | { 13 | public class Startup 14 | { 15 | // This method gets called by the runtime. Use this method to add services to the container. 16 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 17 | public void ConfigureServices(IServiceCollection services) 18 | { 19 | } 20 | 21 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 22 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 23 | { 24 | if (env.IsDevelopment()) 25 | { 26 | app.UseDeveloperExceptionPage(); 27 | } 28 | 29 | app.UseRouting(); 30 | 31 | app.UseEndpoints(endpoints => 32 | { 33 | endpoints.MapGet("/", async context => 34 | { 35 | await context.Response.WriteAsync("Hello World!"); 36 | }); 37 | }); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/AspNetCore3.1/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/AspNetCore3.1/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/ClassLibraryNetFramework/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClassLibraryNetFramework 8 | { 9 | public class Class1 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/ClassLibraryNetFramework/ClassLibraryNetFramework.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 4fa3cbac-f5e2-4091-9276-6d24da8ed49c 8 | Library 9 | Properties 10 | ClassLibraryNetFramework 11 | ClassLibraryNetFramework 12 | v4.7.2 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/ClassLibraryNetFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ClassLibraryNetFramework")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ClassLibraryNetFramework")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4fa3cbac-f5e2-4091-9276-6d24da8ed49c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/ClassLibraryNetStandard/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClassLibraryNetStandard 4 | { 5 | public class Class1 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/ClassLibraryNetStandard/ClassLibraryNetStandard.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/Database1/Database1.sqlproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | Database1 7 | 2.0 8 | 4.1 9 | {e361d84a-fd8b-412f-a216-c5c539954338} 10 | Microsoft.Data.Tools.Schema.Sql.Sql130DatabaseSchemaProvider 11 | Database 12 | 13 | 14 | Database1 15 | Database1 16 | 1033, CI 17 | BySchemaAndSchemaType 18 | True 19 | v4.5 20 | CS 21 | Properties 22 | False 23 | True 24 | True 25 | 26 | 27 | bin\Release\ 28 | $(MSBuildProjectName).sql 29 | False 30 | pdbonly 31 | true 32 | false 33 | true 34 | prompt 35 | 4 36 | 37 | 38 | bin\Debug\ 39 | $(MSBuildProjectName).sql 40 | false 41 | true 42 | full 43 | false 44 | true 45 | true 46 | prompt 47 | 4 48 | 49 | 50 | 11.0 51 | 52 | True 53 | 11.0 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /ExampleProjects/vs2019/VS2019.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29609.76 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "Database1", "Database1\Database1.sqlproj", "{E361D84A-FD8B-412F-A216-C5C539954338}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore3.1", "AspNetCore3.1\AspNetCore3.1.csproj", "{F7A8A5F6-7728-4389-AB7B-5A82605172AB}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassLibraryNetStandard", "ClassLibraryNetStandard\ClassLibraryNetStandard.csproj", "{ECF16FB3-40B8-4D14-AFFF-1A9F10BB5955}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryNetFramework", "ClassLibraryNetFramework\ClassLibraryNetFramework.csproj", "{4FA3CBAC-F5E2-4091-9276-6D24DA8ED49C}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {E361D84A-FD8B-412F-A216-C5C539954338}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E361D84A-FD8B-412F-A216-C5C539954338}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E361D84A-FD8B-412F-A216-C5C539954338}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 23 | {E361D84A-FD8B-412F-A216-C5C539954338}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {E361D84A-FD8B-412F-A216-C5C539954338}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {E361D84A-FD8B-412F-A216-C5C539954338}.Release|Any CPU.Deploy.0 = Release|Any CPU 26 | {F7A8A5F6-7728-4389-AB7B-5A82605172AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {F7A8A5F6-7728-4389-AB7B-5A82605172AB}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {F7A8A5F6-7728-4389-AB7B-5A82605172AB}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {F7A8A5F6-7728-4389-AB7B-5A82605172AB}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {ECF16FB3-40B8-4D14-AFFF-1A9F10BB5955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {ECF16FB3-40B8-4D14-AFFF-1A9F10BB5955}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {ECF16FB3-40B8-4D14-AFFF-1A9F10BB5955}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {ECF16FB3-40B8-4D14-AFFF-1A9F10BB5955}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {4FA3CBAC-F5E2-4091-9276-6D24DA8ED49C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {4FA3CBAC-F5E2-4091-9276-6D24DA8ED49C}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {4FA3CBAC-F5E2-4091-9276-6D24DA8ED49C}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {4FA3CBAC-F5E2-4091-9276-6D24DA8ED49C}.Release|Any CPU.Build.0 = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | GlobalSection(ExtensibilityGlobals) = postSolution 43 | SolutionGuid = {54C0E49D-3ABA-4B8D-8708-D8F2A281E324} 44 | EndGlobalSection 45 | EndGlobal 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TargetFrameworkMigrator 2 | ======================= 3 | 4 | [![Visual Studio Marketplace Version](https://vsmarketplacebadge.apphb.com/version/PavelSamokha.TargetFrameworkMigrator.svg)](https://marketplace.visualstudio.com/items?itemName=PavelSamokha.TargetFrameworkMigrator) 5 | 6 | [![Build status](https://ci.appveyor.com/api/projects/status/asrqt7urcujs06lp/branch/master?svg=true)](https://ci.appveyor.com/project/304NotModified/targetframeworkmigrator/branch/master) 7 | 8 | 9 | Visual Studio Bulk Change Target Framework Extension 10 | 11 | Migrate all your .Net projects to another .Net Framework Version at once. 12 | 13 | Please note, SDK style projects are not supported yet! 14 | 15 | If you have solution with many projects and want to migrate to new version of .Net framework with just Visual Studio, you must manually change target framework in properties of every project. With this extension you can update all projects at one click. 16 | 17 | Features: 18 | 19 | * Support .Net Frameworks 2.0-4.8 20 | * Support solution folders 21 | 22 | 23 | ## How to use 24 | 25 | Tools -> Target Framework Migrator 26 | 27 | ![image](https://user-images.githubusercontent.com/5808377/71218148-bdb45a00-22c0-11ea-9347-13d37c299b7d.png) 28 | 29 | Select projects and press "Migrate" 30 | 31 | ![image](https://user-images.githubusercontent.com/5808377/71218330-5ea31500-22c1-11ea-8aa8-de62af5ca6c4.png) 32 | 33 | 34 | Development 35 | =================== 36 | 37 | Use Visual Studio 2017 or 2019. The integration tests are currently broken. 38 | 39 | Frameworks list 40 | ------------------- 41 | 42 | Edit Frameworks.xml in main project to add new framework. 43 | Where to get Id for new framework? I get it via runtime (change one project's framework in visual studio project properties and get it's Id in debug mode). 44 | 45 | How to debug visual studio extension 46 | ------------------------------------ 47 | 48 | Set "Run external program" in Debug to Visual Studio devenv.exe (e.g. C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\\devenv.exe) and command line arguments to `/rootsuffix Exp` 49 | 50 | ![image](https://user-images.githubusercontent.com/5808377/71218359-81352e00-22c1-11ea-8843-4661c57f3442.png) 51 | 52 | 53 | Roadmap 54 | ================= 55 | 56 | - 1.7: .NET 4.7-4.8 support, VS2019 support, bugfixes 57 | - Next: SDK support 58 | -------------------------------------------------------------------------------- /References/Microsoft.VisualStudio.Shell.11.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/References/Microsoft.VisualStudio.Shell.11.0.dll -------------------------------------------------------------------------------- /References/Microsoft.VisualStudio.Shell.Framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/References/Microsoft.VisualStudio.Shell.Framework.dll -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Frameworks.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. Project-level 3 | // suppressions either have no target or are given a specific target 4 | // and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Error List, point to "Suppress Message(s)", and click "In Project 8 | // Suppression File". You do not need to add suppressions to this 9 | // file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")] 12 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Stil", "IDE0008:Expliziten Typ verwenden", Justification = "")] 13 | 14 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Guids.cs: -------------------------------------------------------------------------------- 1 | // Guids.cs 2 | // MUST match guids.h 3 | using System; 4 | 5 | namespace VHQLabs.TargetFrameworkMigrator 6 | { 7 | static class GuidList 8 | { 9 | public const string guidTargetFrameworkMigratorPkgString = "4c5b2b2f-17b1-4b85-aceb-f5e8865dc05a"; 10 | public const string guidTargetFrameworkMigratorCmdSetString = "bbba49fb-2ebd-4110-a269-fc45a929fab9"; 11 | 12 | public static readonly Guid guidTargetFrameworkMigratorCmdSet = new Guid(guidTargetFrameworkMigratorCmdSetString); 13 | }; 14 | } -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Src/TargetFrameworkMigrator/Key.snk -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Migrator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Pavel Samokha 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | using System.Xml; 13 | using EnvDTE; 14 | using EnvDTE80; 15 | 16 | namespace VSChangeTargetFrameworkExtension 17 | { 18 | public class Migrator 19 | { 20 | private readonly DTE applicationObject; 21 | private ProjectsUpdateList projectsUpdateList; 22 | private List frameworkModels; 23 | 24 | private object syncRoot = new object(); 25 | 26 | public Migrator(DTE applicationObject) 27 | { 28 | this.applicationObject = applicationObject; 29 | 30 | frameworkModels = new List(); 31 | 32 | var folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 33 | 34 | var frameworks = new XmlDocument(); 35 | frameworks.Load(Path.Combine(folderPath, "Frameworks.xml")); 36 | foreach (XmlNode node in frameworks.DocumentElement.ChildNodes) 37 | frameworkModels.Add(new FrameworkModel { Id = uint.Parse(node.Attributes["Id"].Value), Name = node.Attributes["Name"].Value }); 38 | } 39 | 40 | private bool isSolutionLoaded = true; 41 | private SynchronizationContext synchronizationContext; 42 | 43 | public void Show() 44 | { 45 | lock (syncRoot) 46 | { 47 | synchronizationContext = SynchronizationContext.Current; 48 | 49 | projectsUpdateList = new ProjectsUpdateList(); 50 | 51 | projectsUpdateList.UpdateFired += Update; 52 | projectsUpdateList.ReloadFired += ReloadProjects; 53 | 54 | projectsUpdateList.Frameworks = frameworkModels; 55 | 56 | projectsUpdateList.State = "Waiting all projects are loaded..."; 57 | 58 | if (applicationObject.Solution == null) 59 | { 60 | projectsUpdateList.State = "No solution"; 61 | } 62 | else 63 | { 64 | if (isSolutionLoaded) 65 | ReloadProjects(); 66 | } 67 | 68 | projectsUpdateList.StartPosition = FormStartPosition.CenterScreen; 69 | projectsUpdateList.TopMost = true; 70 | projectsUpdateList.ShowDialog(); 71 | 72 | } 73 | } 74 | 75 | public void OnBeforeSolutionLoaded() 76 | { 77 | lock (syncRoot) 78 | { 79 | if (projectsUpdateList != null) 80 | projectsUpdateList.State = "Waiting all projects are loaded..."; 81 | 82 | isSolutionLoaded = false; 83 | 84 | } 85 | } 86 | 87 | public void OnAfterSolutionLoaded() 88 | { 89 | lock (syncRoot) 90 | { 91 | isSolutionLoaded = true; 92 | 93 | if (projectsUpdateList != null && projectsUpdateList.Visible) 94 | ReloadProjects(); 95 | } 96 | } 97 | 98 | private void ReloadProjects() 99 | { 100 | var projectModels = LoadProjects(); 101 | 102 | projectsUpdateList.State = projectModels.Count == 0 ? "No .Net projects" : String.Empty; 103 | 104 | projectsUpdateList.Projects = projectModels; 105 | } 106 | 107 | private List LoadProjects() 108 | { 109 | Projects projects = applicationObject.Solution.Projects; 110 | 111 | if (projects.Count == 0) 112 | { 113 | return new List(); 114 | } 115 | 116 | var projectModels = MapProjects(projects.OfType()); 117 | 118 | projectModels = projectModels 119 | .Where(pm => pm.HasFramework) 120 | .ToList(); 121 | return projectModels; 122 | } 123 | 124 | private List MapProjects(IEnumerable projects) 125 | { 126 | List projectModels = new List(); 127 | foreach (Project p in projects) 128 | { 129 | if (p == null) 130 | continue; 131 | 132 | if (p.Kind == ProjectKinds.vsProjectKindSolutionFolder) 133 | { 134 | var projectItems = p.ProjectItems.OfType(); 135 | var subProjects = projectItems.Select(pi => pi.SubProject); 136 | projectModels.AddRange(MapProjects(subProjects)); 137 | } 138 | else 139 | { 140 | var projectModel = MapProject(p); 141 | projectModels.Add(projectModel); 142 | } 143 | } 144 | return projectModels; 145 | } 146 | 147 | private static ProjectModel MapProject(Project p) 148 | { 149 | var projectModel = new ProjectModel 150 | { 151 | Name = p.Name, 152 | DteProject = p, 153 | }; 154 | if (p.Properties == null) return projectModel; 155 | 156 | 157 | try 158 | { 159 | // check if not applicable for current project 160 | if (p.Properties.Item("TargetFramework") == null || 161 | p.Properties.Item("TargetFrameworkMoniker") == null) return projectModel; 162 | } 163 | catch (ArgumentException e) 164 | { 165 | Debug.WriteLine("ArgumentException on " + projectModel + e); 166 | return projectModel; 167 | } 168 | 169 | try 170 | { 171 | var frameworkModel = new FrameworkModel 172 | { 173 | Id = (uint)p.Properties.Item("TargetFramework").Value, 174 | Name = (string)p.Properties.Item("TargetFrameworkMoniker").Value 175 | }; 176 | projectModel.Framework = frameworkModel; 177 | } 178 | catch (ArgumentException e) //possible when project still loading 179 | { 180 | Debug.WriteLine("ArgumentException on " + projectModel + e); 181 | } 182 | catch (InvalidCastException e) //for some projects with wrong types 183 | { 184 | Debug.WriteLine("InvalidCastException on " + projectModel + e); 185 | } 186 | return projectModel; 187 | } 188 | 189 | async void Update() 190 | { 191 | FrameworkModel frameworkModel = projectsUpdateList.SelectedFramework; 192 | 193 | projectsUpdateList.State = "Updating..."; 194 | 195 | await UpdateFrameworks(frameworkModel); 196 | 197 | projectsUpdateList.Projects = LoadProjects(); 198 | 199 | projectsUpdateList.State = "Done"; 200 | } 201 | 202 | private Task UpdateFrameworks(FrameworkModel frameworkModel) 203 | { 204 | return Task.Run(() => 205 | { 206 | var enumerable = projectsUpdateList.Projects.Where(p => p.IsSelected); 207 | 208 | foreach (var projectModel in enumerable) 209 | { 210 | try 211 | { 212 | projectModel.DteProject.Properties.Item("TargetFrameworkMoniker").Value = frameworkModel.Name; 213 | 214 | synchronizationContext.Post(o => 215 | { 216 | var pm = (ProjectModel)o; 217 | projectsUpdateList.State = string.Format("Updating... {0} done", pm.Name); 218 | }, projectModel); 219 | } 220 | catch (COMException e) //possible "project unavailable" for unknown reasons 221 | { 222 | Debug.WriteLine("COMException on " + projectModel.Name + e); 223 | } 224 | } 225 | }); 226 | } 227 | } 228 | } -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/PkgCmdID.cs: -------------------------------------------------------------------------------- 1 | // PkgCmdID.cs 2 | // MUST match PkgCmdID.h 3 | using System; 4 | 5 | namespace VHQLabs.TargetFrameworkMigrator 6 | { 7 | static class PkgCmdIDList 8 | { 9 | public const uint cmdidTargetFrameworkMigrator = 0x100; 10 | 11 | 12 | }; 13 | } -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/ProjectsUpdateList.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace VSChangeTargetFrameworkExtension 2 | { 3 | partial class ProjectsUpdateList 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 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectsUpdateList)); 32 | this.dataGridView1 = new System.Windows.Forms.DataGridView(); 33 | this.Update = new System.Windows.Forms.DataGridViewCheckBoxColumn(); 34 | this.ProjectName = new System.Windows.Forms.DataGridViewTextBoxColumn(); 35 | this.Framework = new System.Windows.Forms.DataGridViewTextBoxColumn(); 36 | this.comboBox1 = new System.Windows.Forms.ComboBox(); 37 | this.button1 = new System.Windows.Forms.Button(); 38 | this.button2 = new System.Windows.Forms.Button(); 39 | this.button3 = new System.Windows.Forms.Button(); 40 | this.label1 = new System.Windows.Forms.Label(); 41 | this.reloadButton = new System.Windows.Forms.Button(); 42 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); 43 | this.SuspendLayout(); 44 | // 45 | // dataGridView1 46 | // 47 | this.dataGridView1.AllowUserToAddRows = false; 48 | this.dataGridView1.AllowUserToDeleteRows = false; 49 | this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 50 | | System.Windows.Forms.AnchorStyles.Left) 51 | | System.Windows.Forms.AnchorStyles.Right))); 52 | this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 53 | this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 54 | this.Update, 55 | this.ProjectName, 56 | this.Framework}); 57 | this.dataGridView1.Location = new System.Drawing.Point(12, 71); 58 | this.dataGridView1.Name = "dataGridView1"; 59 | this.dataGridView1.Size = new System.Drawing.Size(666, 283); 60 | this.dataGridView1.TabIndex = 0; 61 | // 62 | // Update 63 | // 64 | this.Update.DataPropertyName = "IsSelected"; 65 | this.Update.HeaderText = "Update"; 66 | this.Update.Name = "Update"; 67 | // 68 | // ProjectName 69 | // 70 | this.ProjectName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 71 | this.ProjectName.DataPropertyName = "Name"; 72 | this.ProjectName.HeaderText = "Project Name"; 73 | this.ProjectName.Name = "ProjectName"; 74 | this.ProjectName.ReadOnly = true; 75 | // 76 | // Framework 77 | // 78 | this.Framework.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 79 | this.Framework.DataPropertyName = "Framework"; 80 | this.Framework.HeaderText = "Current Framework"; 81 | this.Framework.Name = "Framework"; 82 | this.Framework.ReadOnly = true; 83 | // 84 | // comboBox1 85 | // 86 | this.comboBox1.FormattingEnabled = true; 87 | this.comboBox1.Location = new System.Drawing.Point(12, 12); 88 | this.comboBox1.Name = "comboBox1"; 89 | this.comboBox1.Size = new System.Drawing.Size(307, 21); 90 | this.comboBox1.TabIndex = 1; 91 | // 92 | // button1 93 | // 94 | this.button1.Location = new System.Drawing.Point(12, 39); 95 | this.button1.Name = "button1"; 96 | this.button1.Size = new System.Drawing.Size(75, 23); 97 | this.button1.TabIndex = 2; 98 | this.button1.Text = "Select All"; 99 | this.button1.UseVisualStyleBackColor = true; 100 | this.button1.Click += new System.EventHandler(this.button1_Click); 101 | // 102 | // button2 103 | // 104 | this.button2.Location = new System.Drawing.Point(93, 39); 105 | this.button2.Name = "button2"; 106 | this.button2.Size = new System.Drawing.Size(75, 23); 107 | this.button2.TabIndex = 3; 108 | this.button2.Text = "Select None"; 109 | this.button2.UseVisualStyleBackColor = true; 110 | this.button2.Click += new System.EventHandler(this.button2_Click); 111 | // 112 | // button3 113 | // 114 | this.button3.Location = new System.Drawing.Point(325, 10); 115 | this.button3.Name = "button3"; 116 | this.button3.Size = new System.Drawing.Size(76, 52); 117 | this.button3.TabIndex = 4; 118 | this.button3.Text = "Migrate"; 119 | this.button3.UseVisualStyleBackColor = true; 120 | this.button3.Click += new System.EventHandler(this.button3_Click); 121 | // 122 | // label1 123 | // 124 | this.label1.AutoSize = true; 125 | this.label1.Location = new System.Drawing.Point(408, 13); 126 | this.label1.Name = "label1"; 127 | this.label1.Size = new System.Drawing.Size(0, 13); 128 | this.label1.TabIndex = 5; 129 | // 130 | // reloadButton 131 | // 132 | this.reloadButton.Location = new System.Drawing.Point(174, 39); 133 | this.reloadButton.Name = "reloadButton"; 134 | this.reloadButton.Size = new System.Drawing.Size(145, 23); 135 | this.reloadButton.TabIndex = 6; 136 | this.reloadButton.Text = "Reload Projects List"; 137 | this.reloadButton.UseVisualStyleBackColor = true; 138 | this.reloadButton.Click += new System.EventHandler(this.reloadButton_Click); 139 | // 140 | // ProjectsUpdateList 141 | // 142 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 143 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 144 | this.ClientSize = new System.Drawing.Size(690, 366); 145 | this.Controls.Add(this.reloadButton); 146 | this.Controls.Add(this.label1); 147 | this.Controls.Add(this.button3); 148 | this.Controls.Add(this.button2); 149 | this.Controls.Add(this.button1); 150 | this.Controls.Add(this.comboBox1); 151 | this.Controls.Add(this.dataGridView1); 152 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 153 | this.Name = "ProjectsUpdateList"; 154 | this.Text = "Target Framework Migrator"; 155 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); 156 | this.ResumeLayout(false); 157 | this.PerformLayout(); 158 | 159 | } 160 | 161 | #endregion 162 | 163 | private System.Windows.Forms.DataGridView dataGridView1; 164 | private System.Windows.Forms.ComboBox comboBox1; 165 | private System.Windows.Forms.Button button1; 166 | private System.Windows.Forms.Button button2; 167 | private System.Windows.Forms.Button button3; 168 | private new System.Windows.Forms.DataGridViewCheckBoxColumn Update; 169 | private System.Windows.Forms.DataGridViewTextBoxColumn ProjectName; 170 | private System.Windows.Forms.DataGridViewTextBoxColumn Framework; 171 | private System.Windows.Forms.Label label1; 172 | private System.Windows.Forms.Button reloadButton; 173 | } 174 | } -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/ProjectsUpdateList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Pavel Samokha 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Runtime.CompilerServices; 7 | using System.Threading.Tasks; 8 | using System.Windows.Forms; 9 | using EnvDTE; 10 | using VSChangeTargetFrameworkExtension.Annotations; 11 | 12 | namespace VSChangeTargetFrameworkExtension 13 | { 14 | public partial class ProjectsUpdateList : Form 15 | { 16 | public event Action UpdateFired; 17 | public event Action ReloadFired; 18 | 19 | public ProjectsUpdateList() 20 | { 21 | InitializeComponent(); 22 | dataGridView1.AutoGenerateColumns = false; 23 | comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; 24 | } 25 | 26 | public List Frameworks 27 | { 28 | set 29 | { 30 | comboBox1.DataSource = value; 31 | } 32 | } 33 | public List Projects 34 | { 35 | set 36 | { 37 | var wrapperBindingList = new SortableBindingList(value); 38 | try 39 | { 40 | dataGridView1.DataSource = wrapperBindingList; 41 | dataGridView1.Refresh(); 42 | } 43 | catch (InvalidOperationException) 44 | { 45 | Invoke(new EventHandler(delegate 46 | { 47 | dataGridView1.DataSource = wrapperBindingList; 48 | dataGridView1.Refresh(); 49 | })); 50 | } 51 | } 52 | get 53 | { 54 | SortableBindingList wrapperBindingList = null; 55 | try 56 | { 57 | wrapperBindingList = (SortableBindingList)dataGridView1.DataSource; 58 | } 59 | catch (InvalidOperationException) 60 | { 61 | Invoke(new EventHandler(delegate 62 | { 63 | wrapperBindingList = (SortableBindingList)dataGridView1.DataSource; 64 | })); 65 | } 66 | return wrapperBindingList.WrappedList; 67 | } 68 | } 69 | 70 | public FrameworkModel SelectedFramework 71 | { 72 | get 73 | { 74 | FrameworkModel model = null; 75 | Invoke(new EventHandler(delegate 76 | { 77 | model = (FrameworkModel)comboBox1.SelectedItem; 78 | })); 79 | return model; 80 | } 81 | } 82 | 83 | public string State 84 | { 85 | set 86 | { 87 | try 88 | { 89 | label1.Text = value; 90 | } 91 | catch (InvalidOperationException) 92 | { 93 | Invoke(new EventHandler(delegate 94 | { 95 | label1.Text = value; 96 | })); 97 | } 98 | } 99 | } 100 | 101 | private async void button3_Click(object sender, EventArgs e) 102 | { 103 | var onUpdate = UpdateFired; 104 | if (onUpdate != null) 105 | await Task.Run(() => 106 | { 107 | onUpdate.Invoke(); 108 | }); 109 | } 110 | 111 | private void button1_Click(object sender, EventArgs e) 112 | { 113 | foreach (var projectModel in Projects) 114 | { 115 | projectModel.IsSelected = true; 116 | } 117 | dataGridView1.Refresh(); 118 | } 119 | 120 | private void button2_Click(object sender, EventArgs e) 121 | { 122 | foreach (var projectModel in Projects) 123 | { 124 | projectModel.IsSelected = false; 125 | } 126 | dataGridView1.Refresh(); 127 | } 128 | 129 | private void reloadButton_Click(object sender, EventArgs e) 130 | { 131 | var onReloadFired = ReloadFired; 132 | if (onReloadFired != null) 133 | onReloadFired.Invoke(); 134 | } 135 | } 136 | 137 | public class ProjectModel : INotifyPropertyChanged 138 | { 139 | private bool isSelected; 140 | private string name; 141 | 142 | public bool IsSelected 143 | { 144 | get 145 | { 146 | return isSelected; 147 | } 148 | set 149 | { 150 | isSelected = value; 151 | OnPropertyChanged(); 152 | } 153 | } 154 | 155 | public string Name 156 | { 157 | get 158 | { 159 | return name; 160 | } 161 | set 162 | { 163 | name = value; 164 | OnPropertyChanged(); 165 | } 166 | } 167 | 168 | public FrameworkModel Framework 169 | { 170 | get; set; 171 | } 172 | 173 | public bool HasFramework 174 | { 175 | get 176 | { 177 | return Framework != null; 178 | } 179 | } 180 | 181 | public Project DteProject 182 | { 183 | get; set; 184 | } 185 | 186 | public override string ToString() 187 | { 188 | return string.Format("{0}", Name); 189 | } 190 | 191 | public event PropertyChangedEventHandler PropertyChanged; 192 | 193 | [NotifyPropertyChangedInvocator] 194 | protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 195 | { 196 | var handler = PropertyChanged; 197 | if (handler != null) 198 | handler(this, new PropertyChangedEventArgs(propertyName)); 199 | } 200 | } 201 | 202 | public class FrameworkModel : IComparable 203 | { 204 | public string Name 205 | { 206 | get; set; 207 | } 208 | public uint Id 209 | { 210 | get; set; 211 | } 212 | 213 | public override string ToString() 214 | { 215 | return string.Format("{0}", Name); 216 | } 217 | 218 | // support comparison so we can sort by properties of this type 219 | public int CompareTo(object obj) 220 | { 221 | return StringComparer.Ordinal.Compare(this.Name, ((FrameworkModel)obj).Name); 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/ProjectsUpdateList.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | True 125 | 126 | 127 | True 128 | 129 | 130 | 131 | 132 | AAABAAEAGBgAAAEAIACICQAAFgAAACgAAAAYAAAAMAAAAAEAIAAAAAAAAAkAABMLAAATCwAAAAAAAAAA 133 | AAAAAAABAAAABwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAA 134 | AAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAABwAAAAF5eXmNqKiotqSkpLyjo6O8o6OjvKOj 135 | o7yjo6O8o6OjvKOjo7yjo6O8o6OjvKOjo7yjo6O8o6OjvKOjo7yjo6O8o6OjvKOjo7yjo6O8o6OjvKOj 136 | o7ykpKS8nJycowAAAAd4eHiO7e3t/+zs7P/r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr 137 | 6//r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/u7u73AAAAAt4eHiO7u7u/+jo 138 | 6P/m5ub/5ubm/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+jo 139 | 6P/o6Oj/6Ojo/+jo6P/r6+v/u7u73AAAAAt4eHiO7+/v/+np6f/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo 140 | 6P/o6Oj/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6urq/+rq6v/s7Oz/u7u73AAA 141 | AAt4eHiO8PDw/8fHx//Gxsb/6enp/+np6f/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq 142 | 6v/r6+v/6+vr/+vr6//r6+v/39/f/4uMi//u7u7/vLy83AAAAAt4eHiO8fHx/729vf84OTj/x8fH/+vr 143 | 6//r6+v/q6ur/5eXl/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5f/7Ozs/+zs7P/g4OD/UFFQ/11d 144 | Xf/v7+//vb293AAAAAt4eHiO8vLy/72+vf8sLSz/ODk4/8jIyP/s7Oz/oqKi/83Nzf/a2tr/2tra/9ra 145 | 2v/a2tr/2tra/9ra2v98fHz/7e3t/+Hh4f9RUVH/LS4t/11eXf/w8PD/vb293AAAAAt4eHiO8/Pz/7+/ 146 | v/8tLS3/LS0t/11dXf/t7e3/o6Oj/+vr6//u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v98fHz/7+/v/7Ky 147 | sv8tLi3/LS4t/11eXf/x8fH/vr6+3AAAAAt4eHiO9PT0/8DAwP8tLi3/UVJR/+Pj4//v7+//o6Oj/8fH 148 | x//IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP99fX3/8PDw//Dw8P+nqKf/LS4t/15fXv/y8vL/v7+/3AAA 149 | AAt4eHiO9fX1/8DBwP9SUlL/5OTk//Dw8P/w8PD/rq6u/5qamv+ampr/mpqa/5ubm/+bm5v/m5ub/5ub 150 | m/+bm5v/8fHx//Ly8v/y8vL/qKio/19fX//z8/P/v7+/3AAAAAt4eHiO9vb2/9ra2v/l5eX/8vLy//Ly 151 | 8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz/87P 152 | zv/19fX/wMDA3AAAAAt4eHiO9/f3//T09P/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T0 153 | 9P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/wMDA3AAAAAt4eHiO+Pj4//X1 154 | 9f/09PT/9PT0//X19f/19fX/5ubm/9fX1//Y2Nj/2NjY/9jY2P/Y2Nj/2NjY/9jY2P/Y2Nj/9vb2//b2 155 | 9v/29vb/9vb2//b29v/39/f/wcHB3AAAAAt4eHiO+fn5//b29v/29vb/9vb2//b29v/29vb/p6en/4CA 156 | gP+AgID/gYGB/4GBgf+BgYH/gYGB/4GBgf+BgYH/9/f3//f39//39/f/+Pj4//j4+P/4+Pj/wsLC3AAA 157 | AAt4eHiO+vr6//j4+P/39/f/9/f3//f39//39/f/+Pj4//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4 158 | +P/4+Pj/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/wsLC3AAAAAt4eHiO+/v7//n5+f/5+fn/+fn5//n5 159 | +f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/6+vr/+vr6//r6+v/6+vr/+vr6//r6 160 | +v/6+vr/wsLC3AAAAAt4eHiO/Pz8//r6+v/6+vr/+vr6//r6+v/6+vr/s7Oz/6CgoP+goKD/oKCg/6Gh 161 | of+hoaH/oaGh/6Ghof+hoaH/+/v7//v7+//7+/v/+/v7//z8/P/8/Pz/w8PD3AAAAAt4eHiO/f39//v7 162 | +//7+/v/+/v7//v7+//7+/v/vr6+/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD//f39//39 163 | /f/9/f3//f39//39/f/9/f3/xMTE3AAAAAt4eHiO/v7+//39/f/9/f3//f39//39/f/9/f3//f39//39 164 | /f/9/f3//f39//39/f/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/xMTE3AAA 165 | AAt4eHiO//////7+/v/+/v7//v7+//7+/v/+/v7//v7+//////////////////////////////////// 166 | ////////////////////////////////////////xcXF3AAAAAt4eHiO//////////////////////// 167 | //////////////////////////////////////////////////////////////////////////////// 168 | ////////xcXF3AAAAAt5eXmN//////////////////////////////////////////////////////// 169 | ////////////////////////////////////////////////////////x8fH2QAAAAd8fHyKp6enf6am 170 | poCmpqaApqamgKampoCmpqaApqamgKampoCmpqaApqamgKampoCmpqaApqamgKampoCmpqaApqamgKam 171 | poCmpqaApqamgKampoCmpqaAnp6edQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 172 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 173 | AAA= 174 | 175 | 176 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Resources; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("TargetFrameworkMigrator")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("VHQLabs")] 14 | [assembly: AssemblyProduct("TargetFrameworkMigrator")] 15 | [assembly: AssemblyCopyright("")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | [assembly: ComVisible(false)] 19 | [assembly: CLSCompliant(false)] 20 | [assembly: NeutralResourcesLanguage("en-US")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Revision and Build Numbers 30 | // by using the '*' as shown below: 31 | 32 | [assembly: AssemblyVersion("1.5.0.0")] 33 | [assembly: AssemblyFileVersion("1.5.0.0")] 34 | 35 | [assembly: InternalsVisibleTo("TargetFrameworkMigrator_IntegrationTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d7bd8b3a855b93a51230422b4d24e84a28f1ffae0ac3852fa8251ad77d54a03ce7e8a1f71026c51642cffed98dddd92219c27bbb6e5521a2258a147b00726ba1e879125b9b34633b9e71d206ee89922ae51ed490044707113b616db909063e4ff12a248cc2914500b4a40b6a5082e1c435407ba39727cc66b929f5b9193d98db")] 36 | [assembly: InternalsVisibleTo("TargetFrameworkMigrator_UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d7bd8b3a855b93a51230422b4d24e84a28f1ffae0ac3852fa8251ad77d54a03ce7e8a1f71026c51642cffed98dddd92219c27bbb6e5521a2258a147b00726ba1e879125b9b34633b9e71d206ee89922ae51ed490044707113b616db909063e4ff12a248cc2914500b4a40b6a5082e1c435407ba39727cc66b929f5b9193d98db")] 37 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Dieser Code wurde von einem Tool generiert. 4 | // Laufzeitversion:4.0.30319.42000 5 | // 6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn 7 | // der Code erneut generiert wird. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace VHQLabs.TargetFrameworkMigrator { 12 | using System; 13 | 14 | 15 | /// 16 | /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. 17 | /// 18 | // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert 19 | // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. 20 | // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen 21 | // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VHQLabs.TargetFrameworkMigrator.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle 51 | /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 11 | 12 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | text/microsoft-resx 119 | 120 | 121 | 2.0 122 | 123 | 124 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 125 | 126 | 127 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 128 | 129 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Resources/Images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Src/TargetFrameworkMigrator/Resources/Images.png -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/Resources/Package.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Src/TargetFrameworkMigrator/Resources/Package.ico -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/SortableBindingList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace VSChangeTargetFrameworkExtension 11 | { 12 | /// 13 | /// List wrapper class to provide basic sorting operations when bound to a DataGrid view. 14 | /// From the Apache 2.0 licensed project http://betimvwframework.codeplex.com/ 15 | /// Small changes to make it easier to use in the TargetFrameworkMigrator project. 16 | /// 17 | public class SortableBindingList : BindingList 18 | { 19 | private List wrappedList; 20 | private readonly Dictionary> comparers; 21 | private bool isSorted; 22 | private ListSortDirection listSortDirection; 23 | private PropertyDescriptor propertyDescriptor; 24 | 25 | public SortableBindingList(List wrappedList) 26 | : base(wrappedList) 27 | { 28 | this.wrappedList = wrappedList; 29 | this.comparers = new Dictionary>(); 30 | } 31 | 32 | public List WrappedList 33 | { 34 | get { return wrappedList; } 35 | } 36 | 37 | protected override bool SupportsSortingCore 38 | { 39 | get { return true; } 40 | } 41 | 42 | protected override bool IsSortedCore 43 | { 44 | get { return this.isSorted; } 45 | } 46 | 47 | protected override PropertyDescriptor SortPropertyCore 48 | { 49 | get { return this.propertyDescriptor; } 50 | } 51 | 52 | protected override ListSortDirection SortDirectionCore 53 | { 54 | get { return this.listSortDirection; } 55 | } 56 | 57 | protected override bool SupportsSearchingCore 58 | { 59 | get { return true; } 60 | } 61 | 62 | protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) 63 | { 64 | List itemsList = (List)this.Items; 65 | 66 | Type propertyType = property.PropertyType; 67 | PropertyComparer comparer; 68 | if (!this.comparers.TryGetValue(propertyType, out comparer)) 69 | { 70 | comparer = new PropertyComparer(property, direction); 71 | this.comparers.Add(propertyType, comparer); 72 | } 73 | 74 | comparer.SetPropertyAndDirection(property, direction); 75 | itemsList.Sort(comparer); 76 | 77 | this.propertyDescriptor = property; 78 | this.listSortDirection = direction; 79 | this.isSorted = true; 80 | 81 | this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 82 | } 83 | 84 | protected override void RemoveSortCore() 85 | { 86 | this.isSorted = false; 87 | this.propertyDescriptor = base.SortPropertyCore; 88 | this.listSortDirection = base.SortDirectionCore; 89 | 90 | this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 91 | } 92 | 93 | protected override int FindCore(PropertyDescriptor property, object key) 94 | { 95 | int count = this.Count; 96 | for (int i = 0; i < count; ++i) 97 | { 98 | T element = this[i]; 99 | if (property.GetValue(element).Equals(key)) 100 | { 101 | return i; 102 | } 103 | } 104 | 105 | return -1; 106 | } 107 | } 108 | 109 | /// 110 | /// helper class for supporting comparison operations in SortableBindingList 111 | /// 112 | /// 113 | public class PropertyComparer : IComparer 114 | { 115 | private readonly IComparer comparer; 116 | private PropertyDescriptor propertyDescriptor; 117 | private int reverse; 118 | 119 | public PropertyComparer(PropertyDescriptor property, ListSortDirection direction) 120 | { 121 | this.propertyDescriptor = property; 122 | Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType); 123 | this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null); 124 | this.SetListSortDirection(direction); 125 | } 126 | 127 | #region IComparer Members 128 | 129 | public int Compare(T x, T y) 130 | { 131 | return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y)); 132 | } 133 | 134 | #endregion 135 | 136 | private void SetPropertyDescriptor(PropertyDescriptor descriptor) 137 | { 138 | this.propertyDescriptor = descriptor; 139 | } 140 | 141 | private void SetListSortDirection(ListSortDirection direction) 142 | { 143 | this.reverse = direction == ListSortDirection.Ascending ? 1 : -1; 144 | } 145 | 146 | public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction) 147 | { 148 | this.SetPropertyDescriptor(descriptor); 149 | this.SetListSortDirection(direction); 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/TargetFrameworkMigrator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 15.0 5 | 11.0 6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 7 | 8 | 9 | 10 | 11 | 4.0 12 | true 13 | 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 0 25 | 1.0.0.%2a 26 | false 27 | false 28 | true 29 | 30 | 31 | true 32 | bin\x86\Debug\ 33 | DEBUG;TRACE 34 | full 35 | x86 36 | prompt 37 | MinimumRecommendedRules.ruleset 38 | 39 | 40 | bin\x86\Release\ 41 | CODE_ANALYSIS;TRACE 42 | true 43 | pdbonly 44 | x86 45 | true 46 | prompt 47 | MinimumRecommendedRules.ruleset 48 | 49 | 50 | 51 | Debug 52 | AnyCPU 53 | 2.0 54 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274} 55 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 56 | Library 57 | Properties 58 | VHQLabs.TargetFrameworkMigrator 59 | TargetFrameworkMigrator 60 | True 61 | Key.snk 62 | v4.6.2 63 | 64 | 65 | true 66 | full 67 | false 68 | bin\Debug\ 69 | DEBUG;TRACE 70 | prompt 71 | 4 72 | 73 | 74 | pdbonly 75 | true 76 | bin\Release\ 77 | TRACE 78 | prompt 79 | 4 80 | true 81 | False 82 | False 83 | 84 | 85 | 86 | False 87 | 88 | 89 | False 90 | 91 | 92 | False 93 | 94 | 95 | False 96 | 97 | 98 | 99 | 100 | False 101 | ..\..\References\Microsoft.VisualStudio.Shell.11.0.dll 102 | 103 | 104 | False 105 | ..\..\References\Microsoft.VisualStudio.Shell.Framework.dll 106 | 107 | 108 | 109 | 110 | 111 | 112 | true 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | Form 130 | 131 | 132 | ProjectsUpdateList.cs 133 | 134 | 135 | True 136 | True 137 | Resources.resx 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | ProjectsUpdateList.cs 149 | 150 | 151 | ResXFileCodeGenerator 152 | Resources.Designer.cs 153 | Designer 154 | 155 | 156 | true 157 | VSPackage 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | Menus.ctmenu 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | PreserveNewest 174 | true 175 | 176 | 177 | 178 | 179 | 180 | False 181 | .NET Framework 3.5 SP1 182 | false 183 | 184 | 185 | 186 | true 187 | 188 | 189 | 190 | 197 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/TargetFrameworkMigrator.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 36 | 37 | 38 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 63 | 64 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/TargetFrameworkMigratorPackage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Pavel Samokha 2 | using System; 3 | using System.Diagnostics; 4 | using System.Globalization; 5 | using System.Runtime.InteropServices; 6 | using System.ComponentModel.Design; 7 | using System.Threading; 8 | using System.Windows.Forms; 9 | using EnvDTE; 10 | using Microsoft.Win32; 11 | using Microsoft.VisualStudio; 12 | using Microsoft.VisualStudio.Shell.Interop; 13 | using Microsoft.VisualStudio.OLE.Interop; 14 | using Microsoft.VisualStudio.Shell; 15 | using VSChangeTargetFrameworkExtension; 16 | using IServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; 17 | using Thread = System.Threading.Thread; 18 | 19 | namespace VHQLabs.TargetFrameworkMigrator 20 | { 21 | /// 22 | /// This is the class that implements the package exposed by this assembly. 23 | /// 24 | /// The minimum requirement for a class to be considered a valid package for Visual Studio 25 | /// is to implement the IVsPackage interface and register itself with the shell. 26 | /// This package uses the helper classes defined inside the Managed Package Framework (MPF) 27 | /// to do it: it derives from the Package class that provides the implementation of the 28 | /// IVsPackage interface and uses the registration attributes defined in the framework to 29 | /// register itself and its components with the shell. 30 | /// 31 | // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is 32 | // a package. 33 | [PackageRegistration(UseManagedResourcesOnly = true)] 34 | // This attribute is used to register the information needed to show this package 35 | // in the Help/About dialog of Visual Studio. 36 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] 37 | // This attribute is needed to let the shell know that this package exposes some menus. 38 | [ProvideMenuResource("Menus.ctmenu", 1)] 39 | [Guid(GuidList.guidTargetFrameworkMigratorPkgString)] 40 | public sealed class TargetFrameworkMigratorPackage : Package 41 | { 42 | /// 43 | /// Default constructor of the package. 44 | /// Inside this method you can place any initialization code that does not require 45 | /// any Visual Studio service because at this point the package object is created but 46 | /// not sited yet inside Visual Studio environment. The place to do all the other 47 | /// initialization is the Initialize method. 48 | /// 49 | public TargetFrameworkMigratorPackage() 50 | { 51 | Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString())); 52 | } 53 | 54 | 55 | 56 | ///////////////////////////////////////////////////////////////////////////// 57 | // Overridden Package Implementation 58 | #region Package Members 59 | 60 | /// 61 | /// Initialization of the package; this method is called right after the package is sited, so this is the place 62 | /// where you can put all the initialization code that rely on services provided by VisualStudio. 63 | /// 64 | protected override void Initialize() 65 | { 66 | Debug.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); 67 | base.Initialize(); 68 | 69 | // Add our command handlers for menu (commands must exist in the .vsct file) 70 | OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 71 | if ( null != mcs ) 72 | { 73 | DTE dte = (DTE)GetService(typeof(DTE)); 74 | 75 | if (dte != null) 76 | { 77 | migrator = new Migrator(dte); 78 | 79 | var serviceProvider = new ServiceProvider((IServiceProvider)dte); 80 | solutionLoadEvents = new SolutionLoadEvents(serviceProvider); 81 | synchronizationContext = SynchronizationContext.Current; 82 | 83 | solutionLoadEvents.BeforeSolutionLoaded += () => 84 | { 85 | synchronizationContext.Post(_ => migrator.OnBeforeSolutionLoaded(), null); 86 | }; 87 | 88 | solutionLoadEvents.AfterSolutionLoaded += () => 89 | { 90 | synchronizationContext.Post(_ => migrator.OnAfterSolutionLoaded(), null); 91 | }; 92 | } 93 | 94 | // Create the command for the menu item. 95 | CommandID menuCommandID = new CommandID(GuidList.guidTargetFrameworkMigratorCmdSet, (int)PkgCmdIDList.cmdidTargetFrameworkMigrator); 96 | MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID); 97 | mcs.AddCommand(menuItem); 98 | } 99 | } 100 | #endregion 101 | 102 | private SynchronizationContext synchronizationContext; 103 | private SolutionLoadEvents solutionLoadEvents; 104 | private Migrator migrator; 105 | 106 | /// 107 | /// This function is the callback used to execute a command when the a menu item is clicked. 108 | /// See the Initialize method to see how the menu item is associated to this function using 109 | /// the OleMenuCommandService service and the MenuCommand class. 110 | /// 111 | private void MenuItemCallback(object sender, EventArgs e) 112 | { 113 | DTE dte = (DTE)GetService(typeof(DTE)); 114 | 115 | migrator?.Show(); 116 | } 117 | 118 | } 119 | 120 | public class SolutionLoadEvents:IVsSolutionLoadEvents, IVsSolutionEvents, IDisposable 121 | { 122 | private IVsSolution solution; 123 | private uint solutionEventsCookie; 124 | 125 | public SolutionLoadEvents(ServiceProvider serviceProvider) 126 | { 127 | solution = serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution; 128 | if (solution != null) 129 | { 130 | solution.AdviseSolutionEvents(this, out solutionEventsCookie); 131 | } 132 | } 133 | 134 | 135 | 136 | public event Action BeforeSolutionLoaded; 137 | public event Action AfterSolutionLoaded; 138 | 139 | public int OnBeforeOpenSolution(string pszSolutionFilename) 140 | { 141 | var @event = BeforeSolutionLoaded; 142 | if (@event != null) 143 | @event.Invoke(); 144 | 145 | return VSConstants.S_OK; 146 | } 147 | 148 | public int OnBeforeBackgroundSolutionLoadBegins() 149 | { 150 | return VSConstants.S_OK; 151 | } 152 | 153 | public int OnQueryBackgroundLoadProjectBatch(out bool pfShouldDelayLoadToNextIdle) 154 | { 155 | pfShouldDelayLoadToNextIdle = false; 156 | return VSConstants.S_OK; 157 | } 158 | 159 | public int OnBeforeLoadProjectBatch(bool fIsBackgroundIdleBatch) 160 | { 161 | return VSConstants.S_OK; 162 | } 163 | 164 | public int OnAfterLoadProjectBatch(bool fIsBackgroundIdleBatch) 165 | { 166 | return VSConstants.S_OK; 167 | } 168 | 169 | public int OnAfterBackgroundSolutionLoadComplete() 170 | { 171 | var @event = AfterSolutionLoaded; 172 | if(@event != null) 173 | @event.Invoke(); 174 | 175 | return VSConstants.S_OK; 176 | } 177 | 178 | public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) 179 | { 180 | return VSConstants.S_OK; 181 | } 182 | 183 | public int OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel) 184 | { 185 | return VSConstants.S_OK; 186 | } 187 | 188 | public int OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved) 189 | { 190 | return VSConstants.S_OK; 191 | } 192 | 193 | public int OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy) 194 | { 195 | return VSConstants.S_OK; 196 | } 197 | 198 | public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel) 199 | { 200 | return VSConstants.S_OK; 201 | } 202 | 203 | public int OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy) 204 | { 205 | return VSConstants.S_OK; 206 | } 207 | 208 | public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution) 209 | { 210 | return VSConstants.S_OK; 211 | } 212 | 213 | public int OnQueryCloseSolution(object pUnkReserved, ref int pfCancel) 214 | { 215 | return VSConstants.S_OK; 216 | } 217 | 218 | public int OnBeforeCloseSolution(object pUnkReserved) 219 | { 220 | return VSConstants.S_OK; 221 | } 222 | 223 | public int OnAfterCloseSolution(object pUnkReserved) 224 | { 225 | return VSConstants.S_OK; 226 | } 227 | 228 | public void Dispose() 229 | { 230 | if (solution != null && solutionEventsCookie != 0) 231 | { 232 | GC.SuppressFinalize(this); 233 | solution.UnadviseSolutionEvents(solutionEventsCookie); 234 | AfterSolutionLoaded = null; 235 | BeforeSolutionLoaded = null; 236 | solutionEventsCookie = 0; 237 | solution = null; 238 | } 239 | } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigrator/VSPackage.resx: -------------------------------------------------------------------------------- 1 |  2 | 12 | 13 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | text/microsoft-resx 120 | 121 | 122 | 2.0 123 | 124 | 125 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 126 | 127 | 128 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 129 | 130 | 131 | 132 | TargetFrameworkMigrator 133 | 134 | 135 | Bulk Change .Net Projects Target Frameworks 136 | 137 | 138 | Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 139 | 140 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigratorVSIX/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TargetFrameworkMigratorVSIX")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TargetFrameworkMigratorVSIX")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyVersion("1.1.0.0")] 33 | [assembly: AssemblyFileVersion("1.1.0.0")] 34 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigratorVSIX/TargetFrameworkMigratorVSIX.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 15.0 5 | 11.0 6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 7 | 8 | 9 | 10 | 11 | 4.0 12 | 13 | Program 14 | $(DevEnvDir)\devenv.exe 15 | /rootsuffix Exp 16 | 17 | 18 | true 19 | bin\x86\Debug\ 20 | DEBUG;TRACE 21 | full 22 | x86 23 | prompt 24 | MinimumRecommendedRules.ruleset 25 | 26 | 27 | bin\x86\Release\ 28 | TRACE 29 | true 30 | pdbonly 31 | x86 32 | prompt 33 | MinimumRecommendedRules.ruleset 34 | 35 | 36 | false 37 | 38 | 39 | 40 | Debug 41 | AnyCPU 42 | 2.0 43 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 44 | {8B249EC9-DA90-46DA-B5AB-F2E523206109} 45 | Library 46 | Properties 47 | TargetFrameworkMigrator 48 | TargetFrameworkMigrator 49 | v4.6.2 50 | false 51 | false 52 | false 53 | false 54 | false 55 | false 56 | 57 | 58 | true 59 | full 60 | false 61 | bin\Debug\ 62 | DEBUG;TRACE 63 | prompt 64 | 4 65 | 66 | 67 | pdbonly 68 | true 69 | bin\Release\ 70 | TRACE 71 | prompt 72 | 4 73 | False 74 | 75 | 76 | 77 | 78 | 79 | 80 | Designer 81 | 82 | 83 | 84 | 85 | Always 86 | true 87 | 88 | 89 | Always 90 | true 91 | 92 | 93 | 94 | 95 | {39cec1d1-affa-4e29-9f6d-f5e976207274} 96 | TargetFrameworkMigrator 97 | 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /Src/TargetFrameworkMigratorVSIX/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Src/TargetFrameworkMigratorVSIX/icon.png -------------------------------------------------------------------------------- /Src/TargetFrameworkMigratorVSIX/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Src/TargetFrameworkMigratorVSIX/preview.png -------------------------------------------------------------------------------- /Src/TargetFrameworkMigratorVSIX/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Target Framework Migrator 6 | Change all your .Net projects Target Framework at once 7 | icon.png 8 | preview.png 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /TargetFrameworkMigrator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29609.76 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{83F41A10-B8A1-4B99-9729-A65C595ECE81}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetFrameworkMigratorVSIX", "Src\TargetFrameworkMigratorVSIX\TargetFrameworkMigratorVSIX.csproj", "{8B249EC9-DA90-46DA-B5AB-F2E523206109}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetFrameworkMigrator", "Src\TargetFrameworkMigrator\TargetFrameworkMigrator.csproj", "{39CEC1D1-AFFA-4E29-9F6D-F5E976207274}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetFrameworkMigrator_IntegrationTests", "Tests\TargetFrameworkMigrator_IntegrationTests\TargetFrameworkMigrator_IntegrationTests.csproj", "{01FA1704-36DE-4C83-AACD-23A51281E0FD}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetFrameworkMigrator_UnitTests", "Tests\TargetFrameworkMigrator_UnitTests\TargetFrameworkMigrator_UnitTests.csproj", "{79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{AC6673EA-5CD9-4461-856B-ECB322831AA0}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Debug|X64 = Debug|X64 22 | Debug|x86 = Debug|x86 23 | Release|Any CPU = Release|Any CPU 24 | Release|X64 = Release|X64 25 | Release|x86 = Release|x86 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Debug|X64.ActiveCfg = Debug|Any CPU 31 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Debug|x86.ActiveCfg = Debug|x86 32 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Debug|x86.Build.0 = Debug|x86 33 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Release|X64.ActiveCfg = Release|Any CPU 36 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Release|x86.ActiveCfg = Release|x86 37 | {8B249EC9-DA90-46DA-B5AB-F2E523206109}.Release|x86.Build.0 = Release|x86 38 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Debug|X64.ActiveCfg = Debug|Any CPU 41 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Debug|x86.ActiveCfg = Debug|x86 42 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Debug|x86.Build.0 = Debug|x86 43 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Release|X64.ActiveCfg = Release|Any CPU 46 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Release|x86.ActiveCfg = Release|x86 47 | {39CEC1D1-AFFA-4E29-9F6D-F5E976207274}.Release|x86.Build.0 = Release|x86 48 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Debug|X64.ActiveCfg = Debug|Any CPU 51 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Debug|x86.ActiveCfg = Debug|x86 52 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Debug|x86.Build.0 = Debug|x86 53 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Release|X64.ActiveCfg = Release|Any CPU 56 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Release|x86.ActiveCfg = Release|x86 57 | {01FA1704-36DE-4C83-AACD-23A51281E0FD}.Release|x86.Build.0 = Release|x86 58 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Debug|X64.ActiveCfg = Debug|Any CPU 61 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Debug|x86.ActiveCfg = Debug|x86 62 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Debug|x86.Build.0 = Debug|x86 63 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Release|Any CPU.ActiveCfg = Release|Any CPU 64 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Release|Any CPU.Build.0 = Release|Any CPU 65 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Release|X64.ActiveCfg = Release|Any CPU 66 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Release|x86.ActiveCfg = Release|x86 67 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5}.Release|x86.Build.0 = Release|x86 68 | EndGlobalSection 69 | GlobalSection(SolutionProperties) = preSolution 70 | HideSolutionNode = FALSE 71 | EndGlobalSection 72 | GlobalSection(NestedProjects) = preSolution 73 | {01FA1704-36DE-4C83-AACD-23A51281E0FD} = {AC6673EA-5CD9-4461-856B-ECB322831AA0} 74 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5} = {AC6673EA-5CD9-4461-856B-ECB322831AA0} 75 | EndGlobalSection 76 | GlobalSection(ExtensibilityGlobals) = postSolution 77 | SolutionGuid = {328E24A1-CD5B-4AF3-9E4D-192FBA5943C2} 78 | EndGlobalSection 79 | EndGlobal 80 | -------------------------------------------------------------------------------- /TargetFrameworkMigrator.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | Copyright (c) 2013 Pavel Samokha -------------------------------------------------------------------------------- /Tests/IntegrationTests.testsettings: -------------------------------------------------------------------------------- 1 | 2 | 7 | This test run configuration uses the VS IDE host type in the test run. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/IntegrationTest Library/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | This code is licensed under the Visual Studio SDK license terms. 5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | 10 | ***************************************************************************/ 11 | 12 | namespace Microsoft.VsSDK.IntegrationTestLibrary 13 | { 14 | using System; 15 | using System.Collections.Generic; 16 | using System.Text; 17 | using System.Runtime.InteropServices; 18 | using System.Threading; 19 | using Microsoft.VisualStudio.Shell.Interop; 20 | 21 | /// 22 | /// Defines pinvoked utility methods and internal VS Constants 23 | /// 24 | internal static class NativeMethods 25 | { 26 | internal delegate bool CallBack(IntPtr hwnd, IntPtr lParam); 27 | 28 | // Declare two overloaded SendMessage functions 29 | [DllImport("user32.dll")] 30 | internal static extern UInt32 SendMessage(IntPtr hWnd, UInt32 Msg, 31 | UInt32 wParam, IntPtr lParam); 32 | 33 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 34 | internal static extern bool PeekMessage([In, Out] ref Microsoft.VisualStudio.OLE.Interop.MSG msg, HandleRef hwnd, int msgMin, int msgMax, int remove); 35 | 36 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 37 | internal static extern bool TranslateMessage([In, Out] ref Microsoft.VisualStudio.OLE.Interop.MSG msg); 38 | 39 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 40 | internal static extern int DispatchMessage([In] ref Microsoft.VisualStudio.OLE.Interop.MSG msg); 41 | 42 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 43 | internal static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool attach); 44 | 45 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 46 | internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 47 | 48 | [DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 49 | internal static extern uint GetCurrentThreadId(); 50 | 51 | [DllImport("user32")] 52 | internal static extern int EnumChildWindows(IntPtr hwnd, CallBack x, IntPtr y); 53 | 54 | [DllImport("user32")] 55 | internal static extern bool IsWindowVisible(IntPtr hDlg); 56 | 57 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 58 | internal static extern IntPtr SetFocus(IntPtr hWnd); 59 | 60 | [DllImport("user32")] 61 | internal static extern int GetClassName(IntPtr hWnd, 62 | StringBuilder className, 63 | int stringLength); 64 | [DllImport("user32")] 65 | internal static extern int GetWindowText(IntPtr hWnd, StringBuilder className, int stringLength); 66 | 67 | 68 | [DllImport("user32")] 69 | internal static extern bool EndDialog(IntPtr hDlg, int result); 70 | 71 | [DllImport("Kernel32")] 72 | internal static extern long GetLastError(); 73 | 74 | internal const int QS_KEY = 0x0001, 75 | QS_MOUSEMOVE = 0x0002, 76 | QS_MOUSEBUTTON = 0x0004, 77 | QS_POSTMESSAGE = 0x0008, 78 | QS_TIMER = 0x0010, 79 | QS_PAINT = 0x0020, 80 | QS_SENDMESSAGE = 0x0040, 81 | QS_HOTKEY = 0x0080, 82 | QS_ALLPOSTMESSAGE = 0x0100, 83 | QS_MOUSE = QS_MOUSEMOVE | QS_MOUSEBUTTON, 84 | QS_INPUT = QS_MOUSE | QS_KEY, 85 | QS_ALLEVENTS = QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY, 86 | QS_ALLINPUT = QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE; 87 | 88 | internal const int Facility_Win32 = 7; 89 | 90 | internal const int WM_CLOSE = 0x0010; 91 | 92 | internal const int 93 | S_FALSE = 0x00000001, 94 | S_OK = 0x00000000, 95 | 96 | IDOK = 1, 97 | IDCANCEL = 2, 98 | IDABORT = 3, 99 | IDRETRY = 4, 100 | IDIGNORE = 5, 101 | IDYES = 6, 102 | IDNO = 7, 103 | IDCLOSE = 8, 104 | IDHELP = 9, 105 | IDTRYAGAIN = 10, 106 | IDCONTINUE = 11; 107 | 108 | internal static long HResultFromWin32(long error) 109 | { 110 | if (error <= 0) 111 | { 112 | return error; 113 | } 114 | 115 | return ((error & 0x0000FFFF) | (Facility_Win32 << 16) | 0x80000000); 116 | } 117 | 118 | /// 119 | /// Please use this "approved" method to compare file names. 120 | /// 121 | public static bool IsSamePath(string file1, string file2) 122 | { 123 | if (file1 == null || file1.Length == 0) 124 | { 125 | return (file2 == null || file2.Length == 0); 126 | } 127 | 128 | Uri uri1 = null; 129 | Uri uri2 = null; 130 | 131 | try 132 | { 133 | if (!Uri.TryCreate(file1, UriKind.Absolute, out uri1) || !Uri.TryCreate(file2, UriKind.Absolute, out uri2)) 134 | { 135 | return false; 136 | } 137 | 138 | if (uri1 != null && uri1.IsFile && uri2 != null && uri2.IsFile) 139 | { 140 | return 0 == String.Compare(uri1.LocalPath, uri2.LocalPath, StringComparison.OrdinalIgnoreCase); 141 | } 142 | 143 | return file1 == file2; 144 | } 145 | catch (UriFormatException e) 146 | { 147 | System.Diagnostics.Trace.WriteLine("Exception " + e.Message); 148 | } 149 | 150 | return false; 151 | } 152 | 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/IntegrationTest Library/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using System.Reflection; 5 | using System.Diagnostics; 6 | using System.Collections; 7 | using System.Collections.Generic; 8 | using System.ComponentModel.Design; 9 | using System.Runtime.InteropServices; 10 | using Microsoft.VisualStudio.Shell.Interop; 11 | using Microsoft.VisualStudio.Shell; 12 | using EnvDTE; 13 | using EnvDTE80; 14 | using Microsoft.Win32; 15 | using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; 16 | using Microsoft.VisualStudio.TestTools.UnitTesting; 17 | using Microsoft.VSSDK.Tools.VsIdeTesting; 18 | using Microsoft.VisualStudio; 19 | 20 | namespace Microsoft.VsSDK.IntegrationTestLibrary 21 | { 22 | /// 23 | /// 24 | public class TestUtils 25 | { 26 | 27 | #region Methods: Handling embedded resources 28 | /// 29 | /// Gets the embedded file identified by the resource name, and converts the 30 | /// file into a string. 31 | /// 32 | /// In VS, is DefaultNamespace.FileName? 33 | /// 34 | public static string GetEmbeddedStringResource(Assembly assembly, string resourceName) 35 | { 36 | string result = null; 37 | 38 | // Use the .NET procedure for loading a file embedded in the assembly 39 | Stream stream = assembly.GetManifestResourceStream(resourceName); 40 | if (stream != null) 41 | { 42 | // Convert bytes to string 43 | byte[] fileContentsAsBytes = new byte[stream.Length]; 44 | stream.Read(fileContentsAsBytes, 0, (int)stream.Length); 45 | result = Encoding.Default.GetString(fileContentsAsBytes); 46 | } 47 | else 48 | { 49 | // Embedded resource not found - list available resources 50 | Debug.WriteLine("Unable to find the embedded resource file '" + resourceName + "'."); 51 | Debug.WriteLine(" Available resources:"); 52 | foreach (string aResourceName in assembly.GetManifestResourceNames()) 53 | { 54 | Debug.WriteLine(" " + aResourceName); 55 | } 56 | } 57 | 58 | return result; 59 | } 60 | /// 61 | /// 62 | /// 63 | /// 64 | /// 65 | /// 66 | /// 67 | public static void WriteEmbeddedResourceToFile(Assembly assembly, string embeddedResourceName, string fileName) 68 | { 69 | // Get file contents 70 | string fileContents = GetEmbeddedStringResource(assembly, embeddedResourceName); 71 | if (fileContents == null) 72 | throw new ApplicationException("Failed to get embedded resource '" + embeddedResourceName + "' from assembly '" + assembly.FullName); 73 | 74 | // Write to file 75 | StreamWriter sw = new StreamWriter(fileName); 76 | sw.Write(fileContents); 77 | sw.Close(); 78 | } 79 | 80 | /// 81 | /// Writes an embedded resource to a file. 82 | /// 83 | /// The name of the assembly that the embedded resource is defined. 84 | /// The name of the embedded resource. 85 | /// The file to write the embedded resource's content. 86 | public static void WriteEmbeddedResourceToBinaryFile(Assembly assembly, string embeddedResourceName, string fileName) 87 | { 88 | // Get file contents 89 | Stream stream = assembly.GetManifestResourceStream(embeddedResourceName); 90 | if (stream == null) 91 | throw new InvalidOperationException("Failed to get embedded resource '" + embeddedResourceName + "' from assembly '" + assembly.FullName); 92 | 93 | // Write to file 94 | BinaryWriter sw = null; 95 | FileStream fs = null; 96 | try 97 | { 98 | byte[] fileContentsAsBytes = new byte[stream.Length]; 99 | stream.Read(fileContentsAsBytes, 0, (int)stream.Length); 100 | 101 | FileMode mode = FileMode.CreateNew; 102 | if (File.Exists(fileName)) 103 | { 104 | mode = FileMode.Truncate; 105 | } 106 | 107 | fs = new FileStream(fileName, mode); 108 | 109 | sw = new BinaryWriter(fs); 110 | sw.Write(fileContentsAsBytes); 111 | } 112 | finally 113 | { 114 | if (fs != null) 115 | { 116 | fs.Close(); 117 | } 118 | if (sw != null) 119 | { 120 | sw.Close(); 121 | } 122 | } 123 | } 124 | 125 | #endregion 126 | 127 | #region Methods: Handling temporary files and directories 128 | /// 129 | /// Returns the first available file name on the form 130 | /// [baseFileName]i.[extension] 131 | /// where [i] starts at 1 and increases until there is an available file name 132 | /// in the given directory. Also creates an empty file with that name to mark 133 | /// that file as occupied. 134 | /// 135 | /// Directory that the file should live in. 136 | /// 137 | /// may be null, in which case the .[extension] part 138 | /// is not added. 139 | /// Full file name. 140 | public static string GetNewFileName(string directory, string baseFileName, string extension) 141 | { 142 | // Get the new file name 143 | string fileName = GetNewFileOrDirectoryNameWithoutCreatingAnything(directory, baseFileName, extension); 144 | 145 | // Create an empty file to mark it as taken 146 | StreamWriter sw = new StreamWriter(fileName); 147 | 148 | sw.Write(""); 149 | sw.Close(); 150 | return fileName; 151 | } 152 | /// 153 | /// Returns the first available directory name on the form 154 | /// [baseDirectoryName]i 155 | /// where [i] starts at 1 and increases until there is an available directory name 156 | /// in the given directory. Also creates the directory to mark it as occupied. 157 | /// 158 | /// Directory that the file should live in. 159 | /// 160 | /// Full directory name. 161 | public static string GetNewDirectoryName(string directory, string baseDirectoryName) 162 | { 163 | // Get the new file name 164 | string directoryName = GetNewFileOrDirectoryNameWithoutCreatingAnything(directory, baseDirectoryName, null); 165 | 166 | // Create an empty directory to make it as occupied 167 | Directory.CreateDirectory(directoryName); 168 | 169 | return directoryName; 170 | } 171 | 172 | /// 173 | /// 174 | /// 175 | /// 176 | /// 177 | /// 178 | /// 179 | private static string GetNewFileOrDirectoryNameWithoutCreatingAnything(string directory, string baseFileName, string extension) 180 | { 181 | // - get a file name that we can use 182 | string fileName; 183 | int i = 1; 184 | 185 | string fullFileName = null; 186 | while (true) 187 | { 188 | // construct next file name 189 | fileName = baseFileName + i; 190 | if (extension != null) 191 | fileName += '.' + extension; 192 | 193 | // check if that file exists in the directory 194 | fullFileName = Path.Combine(directory, fileName); 195 | 196 | if (!File.Exists(fullFileName) && !Directory.Exists(fullFileName)) 197 | break; 198 | else 199 | i++; 200 | } 201 | 202 | return fullFileName; 203 | } 204 | #endregion 205 | 206 | #region Methods: Handling solutions 207 | /// 208 | /// Closes the currently open solution (if any), and creates a new solution with the given name. 209 | /// 210 | /// Name of new solution. 211 | public void CreateEmptySolution(string directory, string solutionName) 212 | { 213 | CloseCurrentSolution(__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave); 214 | 215 | string solutionDirectory = GetNewDirectoryName(directory, solutionName); 216 | 217 | // Create and force save solution 218 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)); 219 | solutionService.CreateSolution(solutionDirectory, solutionName, (uint)__VSCREATESOLUTIONFLAGS.CSF_SILENT); 220 | solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0); 221 | DTE dte = VsIdeTestHostContext.Dte; 222 | Assert.AreEqual(solutionName + ".sln", Path.GetFileName(dte.Solution.FileName), "Newly created solution has wrong Filename"); 223 | } 224 | 225 | public void CloseCurrentSolution(__VSSLNSAVEOPTIONS saveoptions) 226 | { 227 | // Get solution service 228 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)); 229 | 230 | // Close already open solution 231 | solutionService.CloseSolutionElement((uint)saveoptions, null, 0); 232 | } 233 | 234 | public void ForceSaveSolution() 235 | { 236 | // Get solution service 237 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)); 238 | 239 | // Force-save the solution 240 | solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0); 241 | } 242 | 243 | /// 244 | /// Get current number of open project in solution 245 | /// 246 | /// 247 | public int ProjectCount() 248 | { 249 | // Get solution service 250 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)); 251 | object projectCount; 252 | solutionService.GetProperty((int)__VSPROPID.VSPROPID_ProjectCount, out projectCount); 253 | return (int)projectCount; 254 | } 255 | #endregion 256 | 257 | #region Methods: Handling projects 258 | /// 259 | /// Creates a project. 260 | /// 261 | /// Name of new project. 262 | /// Name of project template to use 263 | /// language 264 | /// New project. 265 | public void CreateProjectFromTemplate(string projectName, string templateName, string language, bool exclusive) 266 | { 267 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE)); 268 | 269 | Solution2 sol = dte.Solution as Solution2; 270 | string projectTemplate = sol.GetProjectTemplate(templateName, language); 271 | 272 | // - project name and directory 273 | string solutionDirectory = Directory.GetParent(dte.Solution.FullName).FullName; 274 | string projectDirectory = GetNewDirectoryName(solutionDirectory, projectName); 275 | 276 | dte.Solution.AddFromTemplate(projectTemplate, projectDirectory, projectName, false); 277 | } 278 | #endregion 279 | 280 | #region Methods: Handling project items 281 | /// 282 | /// Create a new item in the project 283 | /// 284 | /// the parent collection for the new item 285 | /// 286 | /// 287 | /// 288 | /// 289 | public ProjectItem AddNewItemFromVsTemplate(ProjectItems parent, string templateName, string language, string name) 290 | { 291 | if (parent == null) 292 | throw new ArgumentException("project"); 293 | if (name == null) 294 | throw new ArgumentException("name"); 295 | 296 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE)); 297 | 298 | Solution2 sol = dte.Solution as Solution2; 299 | 300 | string filename = sol.GetProjectItemTemplate(templateName, language); 301 | 302 | parent.AddFromTemplate(filename, name); 303 | 304 | return parent.Item(name); 305 | } 306 | 307 | /// 308 | /// Save an open document. 309 | /// 310 | /// for filebased documents this is the full path to the document 311 | public void SaveDocument(string documentMoniker) 312 | { 313 | // Get document cookie and hierarchy for the file 314 | IVsRunningDocumentTable runningDocumentTableService = (IVsRunningDocumentTable)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsRunningDocumentTable)); 315 | uint docCookie; 316 | IntPtr docData; 317 | IVsHierarchy hierarchy; 318 | uint itemId; 319 | runningDocumentTableService.FindAndLockDocument( 320 | (uint)Microsoft.VisualStudio.Shell.Interop._VSRDTFLAGS.RDT_NoLock, 321 | documentMoniker, 322 | out hierarchy, 323 | out itemId, 324 | out docData, 325 | out docCookie); 326 | 327 | // Save the document 328 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)); 329 | solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, hierarchy, docCookie); 330 | } 331 | 332 | public void CloseInEditorWithoutSaving(string fullFileName) 333 | { 334 | // Get the RDT service 335 | IVsRunningDocumentTable runningDocumentTableService = (IVsRunningDocumentTable)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsRunningDocumentTable)); 336 | Assert.IsNotNull(runningDocumentTableService, "Failed to get the Running Document Table Service"); 337 | 338 | // Get our document cookie and hierarchy for the file 339 | uint docCookie; 340 | IntPtr docData; 341 | IVsHierarchy hierarchy; 342 | uint itemId; 343 | runningDocumentTableService.FindAndLockDocument( 344 | (uint)Microsoft.VisualStudio.Shell.Interop._VSRDTFLAGS.RDT_NoLock, 345 | fullFileName, 346 | out hierarchy, 347 | out itemId, 348 | out docData, 349 | out docCookie); 350 | 351 | // Get the SolutionService 352 | IVsSolution solutionService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)) as IVsSolution; 353 | Assert.IsNotNull(solutionService, "Failed to get IVsSolution service"); 354 | 355 | // Close the document 356 | solutionService.CloseSolutionElement( 357 | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave, 358 | hierarchy, 359 | docCookie); 360 | } 361 | #endregion 362 | 363 | #region Methods: Handling Toolwindows 364 | public bool CanFindToolwindow(Guid persistenceGuid) 365 | { 366 | IVsUIShell uiShellService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; 367 | Assert.IsNotNull(uiShellService); 368 | IVsWindowFrame windowFrame; 369 | int hr = uiShellService.FindToolWindow((uint)__VSFINDTOOLWIN.FTW_fFindFirst, ref persistenceGuid, out windowFrame); 370 | Assert.IsTrue(hr == VSConstants.S_OK); 371 | 372 | return (windowFrame != null); 373 | } 374 | #endregion 375 | 376 | #region Methods: Loading packages 377 | public IVsPackage LoadPackage(Guid packageGuid) 378 | { 379 | IVsShell shellService = (IVsShell)VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsShell)); 380 | IVsPackage package; 381 | shellService.LoadPackage(ref packageGuid, out package); 382 | Assert.IsNotNull(package, "Failed to load package"); 383 | return package; 384 | } 385 | #endregion 386 | 387 | /// 388 | /// Executes a Command (menu item) in the given context 389 | /// 390 | public void ExecuteCommand(CommandID cmd) 391 | { 392 | object Customin = null; 393 | object Customout = null; 394 | string guidString = cmd.Guid.ToString("B").ToUpper(); 395 | int cmdId = cmd.ID; 396 | DTE dte = VsIdeTestHostContext.Dte; 397 | dte.Commands.Raise(guidString, cmdId, ref Customin, ref Customout); 398 | } 399 | 400 | } 401 | } 402 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/IntegrationTest Library/WindowPurger.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Microsoft.VsSDK.IntegrationTestLibrary 3 | { 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Runtime.InteropServices; 8 | using System.Threading; 9 | using Microsoft.VisualStudio.Shell.Interop; 10 | using Microsoft.VisualStudio.Shell; 11 | 12 | /// 13 | /// This class is responsible to close dialog boxes that pop up during different VS Calls 14 | /// 15 | internal class WindowPurger : IDisposable 16 | { 17 | /// 18 | /// The default number of milliseconds to wait for the threads to signal to terminate. 19 | /// 20 | private const int DefaultMillisecondsToWait = 3500; 21 | 22 | /// 23 | /// Object used for synchronization between thread calls. 24 | /// 25 | internal static volatile object Mutex = new object(); 26 | 27 | /// 28 | /// The IVsUIShell. This cannot be queried on the working thread from the service provider. Must be done in the main thread.!! 29 | /// 30 | private IVsUIShell uiShell; 31 | 32 | /// 33 | /// The button to "press" on the dialog. 34 | /// 35 | private int buttonAction; 36 | 37 | /// 38 | /// Thread signales to the calling thread that it is done. 39 | /// 40 | private bool exitThread = false; 41 | 42 | /// 43 | /// Calling thread signales to this thread to die. 44 | /// 45 | private AutoResetEvent threadDone = new AutoResetEvent(false); 46 | 47 | /// 48 | /// The queued thread started. 49 | /// 50 | private AutoResetEvent threadStarted = new AutoResetEvent(false); 51 | 52 | /// 53 | /// The result of the dialogbox closing for all the dialog boxes. That is if there are two of them and one fails this will be false. 54 | /// 55 | private bool dialogBoxCloseResult = false; 56 | 57 | /// 58 | /// The expected text to see on the dialog box. If set the thread will continue finding the dialog box with this text. 59 | /// 60 | private string expectedDialogBoxText = String.Empty; 61 | 62 | /// 63 | /// The number of the same dialog boxes to wait for. 64 | /// This is for scenarios when two dialog boxes with the same text are popping up. 65 | /// 66 | private int numberOfDialogsToWaitFor = 1; 67 | 68 | /// 69 | /// Has the object been disposed. 70 | /// 71 | private bool isDisposed; 72 | 73 | /// 74 | /// Overloaded ctor. 75 | /// 76 | /// The botton to "press" on the dialog box. 77 | /// The number of dialog boxes with the same message to wait for. This is the situation when the same action pops up two of the same dialog boxes 78 | /// The expected window title to find. 79 | internal WindowPurger(int buttonAction, int numberOfDialogsToWaitFor, string expectedWindowTitle) 80 | { 81 | this.buttonAction = buttonAction; 82 | this.numberOfDialogsToWaitFor = numberOfDialogsToWaitFor; 83 | this.expectedDialogBoxText = expectedWindowTitle; 84 | } 85 | 86 | /// 87 | /// Overloaded ctor. 88 | /// 89 | /// The botton to "press" on the dialog box. 90 | /// The number of dialog boxes with the same message to wait for. This is the situation when the same action pops up two of the same dialog boxes 91 | internal WindowPurger(int buttonAction, int numberOfDialogsToWaitFor) 92 | { 93 | this.buttonAction = buttonAction; 94 | this.numberOfDialogsToWaitFor = numberOfDialogsToWaitFor; 95 | } 96 | 97 | /// 98 | /// Overloaded ctor. 99 | /// 100 | /// The botton to "press" on the dialog box. 101 | /// The expected window title to check for. 102 | internal WindowPurger(int buttonAction, string expectedWindowTitle) 103 | { 104 | this.buttonAction = buttonAction; 105 | this.expectedDialogBoxText = expectedWindowTitle; 106 | } 107 | 108 | /// 109 | /// Overloaded ctor. 110 | /// 111 | /// The botton to "press" on the dialog box. 112 | internal WindowPurger(int buttonAction) 113 | { 114 | this.buttonAction = buttonAction; 115 | } 116 | 117 | /// 118 | #region IDisposable Members 119 | 120 | void IDisposable.Dispose() 121 | { 122 | if (this.isDisposed) 123 | { 124 | return; 125 | } 126 | 127 | this.WaitForDialogThreadToTerminate(); 128 | 129 | this.isDisposed = true; 130 | } 131 | 132 | /// 133 | /// Spawns a thread that will start listening to dialog boxes. 134 | /// 135 | internal void Start() 136 | { 137 | // We ask for the uishell here since we cannot do that on the therad that we will spawn. 138 | IVsUIShell uiShell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell; 139 | 140 | if (uiShell == null) 141 | { 142 | throw new InvalidOperationException("Could not get the uiShell from the serviceProvider"); 143 | } 144 | 145 | this.uiShell = uiShell; 146 | 147 | System.Threading.Thread thread = new System.Threading.Thread(new ThreadStart(this.HandleDialogBoxes)); 148 | thread.Start(); 149 | 150 | // We should never deadlock here, hence do not use the lock. Wait to be sure that the thread started. 151 | this.threadStarted.WaitOne(3500, false); 152 | } 153 | 154 | /// 155 | /// Waits for the dialog box close thread to terminate. If the thread does not signal back within millisecondsToWait that it is shutting down, 156 | /// then it will tell to the thread to do it. 157 | /// 158 | internal bool WaitForDialogThreadToTerminate() 159 | { 160 | return this.WaitForDialogThreadToTerminate(DefaultMillisecondsToWait); 161 | } 162 | 163 | /// 164 | /// Waits for the dialog box close thread to terminate. If the thread does not signal back within millisecondsToWait that it is shutting down, 165 | /// then it will tell to the thread to do it. 166 | /// 167 | /// The number milliseconds to wait for until the dialog purger thread is signaled to terminate. This is just for safe precaution that we do not hang. 168 | /// The result of the dialog boxes closing 169 | internal bool WaitForDialogThreadToTerminate(int numberOfMillisecondsToWait) 170 | { 171 | bool signaled = false; 172 | 173 | // We give millisecondsToWait sec to bring up and close the dialog box. 174 | signaled = this.threadDone.WaitOne(numberOfMillisecondsToWait, false); 175 | 176 | // Kill the thread since a timeout occured. 177 | if (!signaled) 178 | { 179 | lock (Mutex) 180 | { 181 | // Set the exit thread to true. Next time the thread will kill itselfes if it sees 182 | this.exitThread = true; 183 | } 184 | 185 | // Wait for the thread to finish. We should never deadlock here. 186 | this.threadDone.WaitOne(); 187 | } 188 | 189 | return this.dialogBoxCloseResult; 190 | } 191 | 192 | /// 193 | /// This is the thread method. 194 | /// 195 | private void HandleDialogBoxes() 196 | { 197 | // No synchronization numberOfDialogsToWaitFor since it is readonly 198 | IntPtr[] hwnds = new IntPtr[this.numberOfDialogsToWaitFor]; 199 | bool[] dialogBoxCloseResults = new bool[this.numberOfDialogsToWaitFor]; 200 | 201 | try 202 | { 203 | // Signal that we started 204 | lock (Mutex) 205 | { 206 | this.threadStarted.Set(); 207 | } 208 | 209 | // The loop will be exited either if a message is send by the caller thread or if we found the dialog. If a message box text is specified the loop will not exit until the dialog is found. 210 | bool stayInLoop = true; 211 | int dialogBoxesToWaitFor = 1; 212 | 213 | while (stayInLoop) 214 | { 215 | int hwndIndex = dialogBoxesToWaitFor - 1; 216 | 217 | // We need to lock since the caller might set context to null. 218 | lock (Mutex) 219 | { 220 | if (this.exitThread) 221 | { 222 | break; 223 | } 224 | 225 | // We protect the shell too from reentrency. 226 | this.uiShell.GetDialogOwnerHwnd(out hwnds[hwndIndex]); 227 | } 228 | 229 | if (hwnds[hwndIndex] != IntPtr.Zero) 230 | { 231 | StringBuilder windowText = new StringBuilder(256); 232 | NativeMethods.GetWindowText(hwnds[hwndIndex], windowText, windowText.Capacity); 233 | 234 | if (windowText.ToString().Equals(this.expectedDialogBoxText)) 235 | { 236 | lock (Mutex) 237 | { 238 | var result = NativeMethods.SendMessage(hwnds[hwndIndex], NativeMethods.WM_CLOSE, 0, IntPtr.Zero); 239 | 240 | dialogBoxCloseResults[hwndIndex] = (result == 0); 241 | if (dialogBoxesToWaitFor++ >= this.numberOfDialogsToWaitFor) 242 | { 243 | stayInLoop = false; 244 | } 245 | } 246 | } 247 | } 248 | } 249 | } 250 | finally 251 | { 252 | //Let the main thread run a possible close command. 253 | System.Threading.Thread.Sleep(2000); 254 | 255 | foreach (IntPtr hwnd in hwnds) 256 | { 257 | // At this point the dialog should be closed, if not attempt to close it. 258 | if (hwnd != IntPtr.Zero) 259 | { 260 | NativeMethods.SendMessage(hwnd, NativeMethods.WM_CLOSE, 0, new IntPtr(0)); 261 | } 262 | } 263 | 264 | lock (Mutex) 265 | { 266 | // Be optimistic. 267 | this.dialogBoxCloseResult = true; 268 | 269 | for (int i = 0; i < dialogBoxCloseResults.Length; i++) 270 | { 271 | if (!dialogBoxCloseResults[i]) 272 | { 273 | this.dialogBoxCloseResult = false; 274 | break; 275 | } 276 | } 277 | 278 | this.threadDone.Set(); 279 | } 280 | } 281 | } 282 | 283 | #endregion 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Tests/TargetFrameworkMigrator_IntegrationTests/Key.snk -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/MenuItemTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.ComponentModel.Design; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.VisualStudio.OLE.Interop; 6 | using Microsoft.VisualStudio.Shell.Interop; 7 | using Microsoft.VisualStudio.Shell; 8 | using Microsoft.VsSDK.IntegrationTestLibrary; 9 | using Microsoft.VSSDK.Tools.VsIdeTesting; 10 | using System.Diagnostics; 11 | 12 | namespace TargetFrameworkMigrator_IntegrationTests 13 | { 14 | [TestClass()] 15 | public class MenuItemTest 16 | { 17 | private delegate void ThreadInvoker(); 18 | 19 | private TestContext testContextInstance; 20 | 21 | /// 22 | ///Gets or sets the test context which provides 23 | ///information about and functionality for the current test run. 24 | /// 25 | public TestContext TestContext 26 | { 27 | get 28 | { 29 | return testContextInstance; 30 | } 31 | set 32 | { 33 | testContextInstance = value; 34 | } 35 | } 36 | 37 | /// 38 | ///A test for lauching the command and closing the associated dialogbox 39 | /// 40 | [TestMethod()] 41 | [HostType("VS IDE")] 42 | public void LaunchCommand() 43 | { 44 | UIThreadInvoker.Invoke((ThreadInvoker)delegate() 45 | { 46 | CommandID menuItemCmd = new CommandID(VHQLabs.TargetFrameworkMigrator.GuidList.guidTargetFrameworkMigratorCmdSet, (int)VHQLabs.TargetFrameworkMigrator.PkgCmdIDList.cmdidTargetFrameworkMigrator); 47 | 48 | // Create the DialogBoxListener Thread. 49 | string expectedDialogBoxText = string.Format(CultureInfo.CurrentCulture, "Target Framework Migrator"); 50 | WindowPurger purger = new WindowPurger(NativeMethods.IDOK, expectedDialogBoxText); 51 | 52 | try 53 | { 54 | purger.Start(); 55 | 56 | TestUtils testUtils = new TestUtils(); 57 | testUtils.ExecuteCommand(menuItemCmd); 58 | } 59 | finally 60 | { 61 | Assert.IsTrue(purger.WaitForDialogThreadToTerminate(), "The window was not shown"); 62 | } 63 | }); 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/PackageTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | using Microsoft.VSSDK.Tools.VsIdeTesting; 7 | using Microsoft.VisualStudio.Shell.Interop; 8 | using Microsoft.VisualStudio.Shell; 9 | using EnvDTE; 10 | 11 | namespace TargetFrameworkMigrator_IntegrationTests 12 | { 13 | /// 14 | /// Integration test for package validation 15 | /// 16 | [TestClass] 17 | public class PackageTest 18 | { 19 | private delegate void ThreadInvoker(); 20 | 21 | private TestContext testContextInstance; 22 | 23 | /// 24 | ///Gets or sets the test context which provides 25 | ///information about and functionality for the current test run. 26 | /// 27 | public TestContext TestContext 28 | { 29 | get 30 | { 31 | return testContextInstance; 32 | } 33 | set 34 | { 35 | testContextInstance = value; 36 | } 37 | } 38 | 39 | [TestMethod] 40 | [HostType("VS IDE")] 41 | public void PackageLoadTest() 42 | { 43 | UIThreadInvoker.Invoke((ThreadInvoker)delegate() 44 | { 45 | 46 | //Get the Shell Service 47 | IVsShell shellService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsShell)) as IVsShell; 48 | Assert.IsNotNull(shellService); 49 | 50 | //Validate package load 51 | IVsPackage package; 52 | Guid packageGuid = new Guid(VHQLabs.TargetFrameworkMigrator.GuidList.guidTargetFrameworkMigratorPkgString); 53 | Assert.IsTrue(0 == shellService.LoadPackage(ref packageGuid, out package)); 54 | Assert.IsNotNull(package, "Package failed to load"); 55 | 56 | }); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/SignOff-Tests/CPPProjectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.VsSDK.IntegrationTestLibrary; 6 | using Microsoft.VSSDK.Tools.VsIdeTesting; 7 | using EnvDTE; 8 | using System.IO; 9 | 10 | namespace TargetFrameworkMigrator_IntegrationTests.IntegrationTests 11 | { 12 | [TestClass] 13 | public class CPPProjectTests 14 | { 15 | #region fields 16 | private delegate void ThreadInvoker(); 17 | private TestContext _testContext; 18 | #endregion 19 | 20 | #region properties 21 | /// 22 | ///Gets or sets the test context which provides 23 | ///information about and functionality for the current test run. 24 | /// 25 | public TestContext TestContext 26 | { 27 | get { return _testContext; } 28 | set { _testContext = value; } 29 | } 30 | #endregion 31 | 32 | #region ctors 33 | public CPPProjectTests() 34 | { 35 | } 36 | #endregion 37 | 38 | #region Additional test attributes 39 | // 40 | // You can use the following additional attributes as you write your tests: 41 | // 42 | // Use ClassInitialize to run code before running the first test in the class 43 | // [ClassInitialize()] 44 | // public static void MyClassInitialize(TestContext testContext) { } 45 | // 46 | // Use ClassCleanup to run code after all tests in a class have run 47 | // [ClassCleanup()] 48 | // public static void MyClassCleanup() { } 49 | // 50 | // Use TestInitialize to run code before running each test 51 | // [TestInitialize()] 52 | // public void MyTestInitialize() { } 53 | // 54 | // Use TestCleanup to run code after each test has run 55 | // [TestCleanup()] 56 | // public void MyTestCleanup() { } 57 | // 58 | #endregion 59 | 60 | [HostType("VS IDE")] 61 | [TestMethod] 62 | public void CPPWinformsApplication() 63 | { 64 | UIThreadInvoker.Invoke((ThreadInvoker)delegate() 65 | { 66 | //Solution and project creation parameters 67 | string solutionName = "CPPWinApp"; 68 | string projectName = "CPPWinApp"; 69 | 70 | //Template parameters 71 | string projectType = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; 72 | string projectTemplateName = Path.Combine("vcNet", "mc++appwiz.vsz"); 73 | 74 | string itemTemplateName = "newc++file.cpp"; 75 | string newFileName = "Test.cpp"; 76 | 77 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE)); 78 | 79 | TestUtils testUtils = new TestUtils(); 80 | 81 | testUtils.CreateEmptySolution(TestContext.TestDir, solutionName); 82 | Assert.AreEqual(0, testUtils.ProjectCount()); 83 | 84 | //Add new CPP Windows application project to existing solution 85 | string solutionDirectory = Directory.GetParent(dte.Solution.FullName).FullName; 86 | string projectDirectory = TestUtils.GetNewDirectoryName(solutionDirectory, projectName); 87 | string projectTemplatePath = Path.Combine(dte.Solution.get_TemplatePath(projectType), projectTemplateName); 88 | Assert.IsTrue(File.Exists(projectTemplatePath), string.Format("Could not find template file: {0}", projectTemplatePath)); 89 | dte.Solution.AddFromTemplate(projectTemplatePath, projectDirectory, projectName, false); 90 | 91 | //Verify that the new project has been added to the solution 92 | Assert.AreEqual(1, testUtils.ProjectCount()); 93 | 94 | //Get the project 95 | Project project = dte.Solution.Item(1); 96 | Assert.IsNotNull(project); 97 | Assert.IsTrue(string.Compare(project.Name, projectName, StringComparison.InvariantCultureIgnoreCase) == 0); 98 | 99 | //Verify Adding new code file to project 100 | string newItemTemplatePath = Path.Combine(dte.Solution.ProjectItemsTemplatePath(projectType), itemTemplateName); 101 | Assert.IsTrue(File.Exists(newItemTemplatePath)); 102 | ProjectItem item = project.ProjectItems.AddFromTemplate(newItemTemplatePath, newFileName); 103 | Assert.IsNotNull(item); 104 | 105 | }); 106 | } 107 | 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/SignOff-Tests/CSharpProjectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.VsSDK.IntegrationTestLibrary; 6 | using Microsoft.VSSDK.Tools.VsIdeTesting; 7 | 8 | namespace TargetFrameworkMigrator_IntegrationTests.IntegrationTests 9 | { 10 | [TestClass] 11 | public class CSharpProjectTests 12 | { 13 | #region fields 14 | private delegate void ThreadInvoker(); 15 | private TestContext _testContext; 16 | #endregion 17 | 18 | #region properties 19 | /// 20 | ///Gets or sets the test context which provides 21 | ///information about and functionality for the current test run. 22 | /// 23 | public TestContext TestContext 24 | { 25 | get { return _testContext; } 26 | set { _testContext = value; } 27 | } 28 | #endregion 29 | 30 | #region ctors 31 | public CSharpProjectTests() 32 | { 33 | } 34 | #endregion 35 | 36 | #region Additional test attributes 37 | // 38 | // You can use the following additional attributes as you write your tests: 39 | // 40 | // Use ClassInitialize to run code before running the first test in the class 41 | // [ClassInitialize()] 42 | // public static void MyClassInitialize(TestContext testContext) { } 43 | // 44 | // Use ClassCleanup to run code after all tests in a class have run 45 | // [ClassCleanup()] 46 | // public static void MyClassCleanup() { } 47 | // 48 | // Use TestInitialize to run code before running each test 49 | // [TestInitialize()] 50 | // public void MyTestInitialize() { } 51 | // 52 | // Use TestCleanup to run code after each test has run 53 | // [TestCleanup()] 54 | // public void MyTestCleanup() { } 55 | // 56 | #endregion 57 | 58 | [TestMethod] 59 | [HostType("VS IDE")] 60 | public void WinformsApplication() 61 | { 62 | UIThreadInvoker.Invoke((ThreadInvoker)delegate() 63 | { 64 | TestUtils testUtils = new TestUtils(); 65 | 66 | testUtils.CreateEmptySolution(TestContext.TestDir, "CSWinApp"); 67 | Assert.AreEqual(0, testUtils.ProjectCount()); 68 | 69 | //Create Winforms application project 70 | //TestUtils.CreateProjectFromTemplate("MyWindowsApp", "Windows Application", "CSharp", false); 71 | //Assert.AreEqual(1, TestUtils.ProjectCount()); 72 | 73 | //TODO Verify that we can debug launch the application 74 | 75 | //TODO Set Break point and verify that will hit 76 | 77 | //TODO Verify Adding new project item to project 78 | 79 | }); 80 | } 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/SignOff-Tests/SolutionTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using Microsoft.VisualStudio.Shell.Interop; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | using Microsoft.VSSDK.Tools.VsIdeTesting; 7 | using EnvDTE; 8 | using System.IO; 9 | using Microsoft.VsSDK.IntegrationTestLibrary; 10 | 11 | 12 | namespace TargetFrameworkMigrator_IntegrationTests.IntegrationTests 13 | { 14 | [TestClass] 15 | public class SolutionTests 16 | { 17 | #region fields 18 | private delegate void ThreadInvoker(); 19 | private TestContext _testContext; 20 | #endregion 21 | 22 | #region properties 23 | /// 24 | ///Gets or sets the test context which provides 25 | ///information about and functionality for the current test run. 26 | /// 27 | public TestContext TestContext 28 | { 29 | get { return _testContext; } 30 | set { _testContext = value; } 31 | } 32 | #endregion 33 | 34 | 35 | #region ctors 36 | public SolutionTests() 37 | { 38 | } 39 | 40 | #endregion 41 | 42 | [TestMethod] 43 | [HostType("VS IDE")] 44 | public void CreateEmptySolution() 45 | { 46 | UIThreadInvoker.Invoke((ThreadInvoker)delegate() 47 | { 48 | TestUtils testUtils = new TestUtils(); 49 | testUtils.CloseCurrentSolution(__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave); 50 | testUtils.CreateEmptySolution(TestContext.TestDir, "EmptySolution"); 51 | }); 52 | } 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/SignOff-Tests/VBProjectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.VsSDK.IntegrationTestLibrary; 6 | using Microsoft.VSSDK.Tools.VsIdeTesting; 7 | using EnvDTE; 8 | 9 | namespace TargetFrameworkMigrator_IntegrationTests.IntegrationTests 10 | { 11 | [TestClass] 12 | public class VisualBasicProjectTests 13 | { 14 | #region fields 15 | private delegate void ThreadInvoker(); 16 | private TestContext _testContext; 17 | #endregion 18 | 19 | #region properties 20 | /// 21 | ///Gets or sets the test context which provides 22 | ///information about and functionality for the current test run. 23 | /// 24 | public TestContext TestContext 25 | { 26 | get { return _testContext; } 27 | set { _testContext = value; } 28 | } 29 | #endregion 30 | 31 | #region ctors 32 | public VisualBasicProjectTests() 33 | { 34 | } 35 | #endregion 36 | 37 | #region Additional test attributes 38 | // 39 | // You can use the following additional attributes as you write your tests: 40 | // 41 | // Use ClassInitialize to run code before running the first test in the class 42 | // [ClassInitialize()] 43 | // public static void MyClassInitialize(TestContext testContext) { } 44 | // 45 | // Use ClassCleanup to run code after all tests in a class have run 46 | // [ClassCleanup()] 47 | // public static void MyClassCleanup() { } 48 | // 49 | // Use TestInitialize to run code before running each test 50 | // [TestInitialize()] 51 | // public void MyTestInitialize() { } 52 | // 53 | // Use TestCleanup to run code after each test has run 54 | // [TestCleanup()] 55 | // public void MyTestCleanup() { } 56 | // 57 | #endregion 58 | 59 | [HostType("VS IDE")] 60 | [TestMethod] 61 | public void VBWinformsApplication() 62 | { 63 | UIThreadInvoker.Invoke((ThreadInvoker)delegate() 64 | { 65 | //Solution and project creation parameters 66 | string solutionName = "VBWinApp"; 67 | string projectName = "VBWinApp"; 68 | 69 | //Template parameters 70 | string language = "VisualBasic"; 71 | string projectTemplateName = "WindowsApplication.Zip"; 72 | string itemTemplateName = "CodeFile.zip"; 73 | string newFileName = "Test.vb"; 74 | 75 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE)); 76 | 77 | TestUtils testUtils = new TestUtils(); 78 | 79 | testUtils.CreateEmptySolution(TestContext.TestDir, solutionName); 80 | Assert.AreEqual(0, testUtils.ProjectCount()); 81 | 82 | //Add new Windows application project to existing solution 83 | testUtils.CreateProjectFromTemplate(projectName, projectTemplateName, language, false); 84 | 85 | //Verify that the new project has been added to the solution 86 | Assert.AreEqual(1, testUtils.ProjectCount()); 87 | 88 | //Get the project 89 | Project project = dte.Solution.Item(1); 90 | Assert.IsNotNull(project); 91 | Assert.IsTrue(string.Compare(project.Name, projectName, StringComparison.InvariantCultureIgnoreCase) == 0); 92 | 93 | //Verify Adding new code file to project 94 | ProjectItem newCodeFileItem = testUtils.AddNewItemFromVsTemplate(project.ProjectItems, itemTemplateName, language, newFileName); 95 | Assert.IsNotNull(newCodeFileItem, "Could not create new project item"); 96 | 97 | }); 98 | } 99 | 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_IntegrationTests/TargetFrameworkMigrator_IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 2.0 7 | {01FA1704-36DE-4C83-AACD-23A51281E0FD} 8 | Library 9 | Properties 10 | TargetFrameworkMigrator_IntegrationTests 11 | TargetFrameworkMigrator_IntegrationTests 12 | v4.6.2 13 | 512 14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | Key.snk 36 | 37 | 38 | true 39 | 40 | 41 | true 42 | bin\x86\Debug\ 43 | DEBUG;TRACE 44 | full 45 | x86 46 | prompt 47 | MinimumRecommendedRules.ruleset 48 | 49 | 50 | bin\x86\Release\ 51 | TRACE 52 | true 53 | pdbonly 54 | x86 55 | prompt 56 | MinimumRecommendedRules.ruleset 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | true 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | {39cec1d1-affa-4e29-9f6d-f5e976207274} 97 | TargetFrameworkMigrator 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_UnitTests/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ian1971/TargetFrameworkMigrator/fbe78ae82be2c645b72cc348093a4b45b5934372/Tests/TargetFrameworkMigrator_UnitTests/Key.snk -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_UnitTests/MenuItemTests/MenuItemCallback.cs: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | This code is licensed under the Visual Studio SDK license terms. 5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | 10 | ***************************************************************************/ 11 | 12 | using System; 13 | using System.Collections; 14 | using System.Text; 15 | using System.Reflection; 16 | using System.ComponentModel.Design; 17 | using Microsoft.VsSDK.UnitTestLibrary; 18 | using Microsoft.VisualStudio.Shell.Interop; 19 | using Microsoft.VisualStudio.TestTools.UnitTesting; 20 | using Microsoft.VisualStudio.Shell; 21 | using VHQLabs.TargetFrameworkMigrator; 22 | 23 | namespace TargetFrameworkMigrator_UnitTests.MenuItemTests 24 | { 25 | [TestClass()] 26 | public class MenuItemTest 27 | { 28 | /// 29 | /// Verify that a new menu command object gets added to the OleMenuCommandService. 30 | /// This action takes place In the Initialize method of the Package object 31 | /// 32 | [TestMethod] 33 | 34 | public void InitializeMenuCommand() 35 | { 36 | // Create the package 37 | IVsPackage package = new TargetFrameworkMigratorPackage() as IVsPackage; 38 | Assert.IsNotNull(package, "The object does not implement IVsPackage"); 39 | 40 | // Create a basic service provider 41 | OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices(); 42 | 43 | // Site the package 44 | Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK"); 45 | 46 | //Verify that the menu command can be found 47 | CommandID menuCommandID = new CommandID(VHQLabs.TargetFrameworkMigrator.GuidList.guidTargetFrameworkMigratorCmdSet, (int)VHQLabs.TargetFrameworkMigrator.PkgCmdIDList.cmdidTargetFrameworkMigrator); 48 | System.Reflection.MethodInfo info = typeof(Package).GetMethod("GetService", BindingFlags.Instance | BindingFlags.NonPublic); 49 | Assert.IsNotNull(info); 50 | OleMenuCommandService mcs = info.Invoke(package, new object[] { (typeof(IMenuCommandService)) }) as OleMenuCommandService; 51 | Assert.IsNotNull(mcs.FindCommand(menuCommandID)); 52 | } 53 | 54 | [TestMethod] 55 | public void MenuItemCallback() 56 | { 57 | // Create the package 58 | IVsPackage package = new TargetFrameworkMigratorPackage() as IVsPackage; 59 | Assert.IsNotNull(package, "The object does not implement IVsPackage"); 60 | 61 | // Create a basic service provider 62 | OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices(); 63 | 64 | // Create a UIShell service mock and proffer the service so that it can called from the MenuItemCallback method 65 | BaseMock uishellMock = UIShellServiceMock.GetUiShellInstance(); 66 | serviceProvider.AddService(typeof(SVsUIShell), uishellMock, true); 67 | 68 | // Site the package 69 | Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK"); 70 | 71 | //Invoke private method on package class and observe that the method does not throw 72 | System.Reflection.MethodInfo info = package.GetType().GetMethod("MenuItemCallback", BindingFlags.Instance | BindingFlags.NonPublic); 73 | Assert.IsNotNull(info, "Failed to get the private method MenuItemCallback throug refplection"); 74 | info.Invoke(package, new object[] { null, null }); 75 | 76 | //Clean up services 77 | serviceProvider.RemoveService(typeof(SVsUIShell)); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_UnitTests/MenuItemTests/UIShellServiceMock.cs: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | This code is licensed under the Visual Studio SDK license terms. 5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | 10 | ***************************************************************************/ 11 | 12 | using System; 13 | using Microsoft.VisualStudio; 14 | using Microsoft.VisualStudio.Shell.Interop; 15 | using Microsoft.VsSDK.UnitTestLibrary; 16 | 17 | namespace TargetFrameworkMigrator_UnitTests 18 | { 19 | static class UIShellServiceMock 20 | { 21 | private static GenericMockFactory uiShellFactory; 22 | 23 | #region UiShell Getters 24 | /// 25 | /// Returns an IVsUiShell that does not implement any methods 26 | /// 27 | /// 28 | internal static BaseMock GetUiShellInstance() 29 | { 30 | if (uiShellFactory == null) 31 | { 32 | uiShellFactory = new GenericMockFactory("UiShell", new Type[] { typeof(IVsUIShell), typeof(IVsUIShellOpenDocument) }); 33 | } 34 | BaseMock uiShell = uiShellFactory.GetInstance(); 35 | return uiShell; 36 | } 37 | 38 | /// 39 | /// Get an IVsUiShell that implements SetWaitCursor, SaveDocDataToFile, ShowMessageBox 40 | /// 41 | /// uishell mock 42 | internal static BaseMock GetUiShellInstance0() 43 | { 44 | BaseMock uiShell = GetUiShellInstance(); 45 | string name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "SetWaitCursor"); 46 | uiShell.AddMethodCallback(name, new EventHandler(SetWaitCursorCallBack)); 47 | 48 | name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "SaveDocDataToFile"); 49 | uiShell.AddMethodCallback(name, new EventHandler(SaveDocDataToFileCallBack)); 50 | 51 | name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "ShowMessageBox"); 52 | uiShell.AddMethodCallback(name, new EventHandler(ShowMessageBoxCallBack)); 53 | return uiShell; 54 | } 55 | #endregion 56 | 57 | #region Callbacks 58 | private static void SetWaitCursorCallBack(object caller, CallbackArgs arguments) 59 | { 60 | arguments.ReturnValue = VSConstants.S_OK; 61 | } 62 | 63 | private static void SaveDocDataToFileCallBack(object caller, CallbackArgs arguments) 64 | { 65 | arguments.ReturnValue = VSConstants.S_OK; 66 | } 67 | 68 | private static void ShowMessageBoxCallBack(object caller, CallbackArgs arguments) 69 | { 70 | arguments.ReturnValue = VSConstants.S_OK; 71 | arguments.SetParameter(10, (int)System.Windows.Forms.DialogResult.Yes); 72 | } 73 | 74 | #endregion 75 | } 76 | } -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_UnitTests/PackageTest.cs: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | This code is licensed under the Visual Studio SDK license terms. 5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | 10 | ***************************************************************************/ 11 | 12 | using System; 13 | using System.Collections; 14 | using System.Text; 15 | using System.Reflection; 16 | using Microsoft.VsSDK.UnitTestLibrary; 17 | using Microsoft.VisualStudio.Shell.Interop; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | using VHQLabs.TargetFrameworkMigrator; 20 | 21 | namespace TargetFrameworkMigrator_UnitTests 22 | { 23 | [TestClass()] 24 | public class PackageTest 25 | { 26 | [TestMethod()] 27 | public void CreateInstance() 28 | { 29 | TargetFrameworkMigratorPackage package = new TargetFrameworkMigratorPackage(); 30 | } 31 | 32 | [TestMethod()] 33 | public void IsIVsPackage() 34 | { 35 | TargetFrameworkMigratorPackage package = new TargetFrameworkMigratorPackage(); 36 | Assert.IsNotNull(package as IVsPackage, "The object does not implement IVsPackage"); 37 | } 38 | 39 | [TestMethod()] 40 | public void SetSite() 41 | { 42 | // Create the package 43 | IVsPackage package = new TargetFrameworkMigratorPackage() as IVsPackage; 44 | Assert.IsNotNull(package, "The object does not implement IVsPackage"); 45 | 46 | // Create a basic service provider 47 | OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices(); 48 | 49 | // Site the package 50 | Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK"); 51 | 52 | // Unsite the package 53 | Assert.AreEqual(0, package.SetSite(null), "SetSite(null) did not return S_OK"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/TargetFrameworkMigrator_UnitTests/TargetFrameworkMigrator_UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 2.0 7 | {79F8DBB8-E7C4-4899-A3BA-753BDB952BB5} 8 | Library 9 | Properties 10 | TargetFrameworkMigrator_UnitTests 11 | TargetFrameworkMigrator_UnitTests 12 | v4.7.2 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | Key.snk 35 | 36 | 37 | true 38 | 39 | 40 | true 41 | bin\x86\Debug\ 42 | DEBUG;TRACE 43 | full 44 | x86 45 | prompt 46 | MinimumRecommendedRules.ruleset 47 | 48 | 49 | bin\x86\Release\ 50 | TRACE 51 | true 52 | pdbonly 53 | x86 54 | prompt 55 | MinimumRecommendedRules.ruleset 56 | 57 | 58 | 59 | 60 | False 61 | ..\..\References\Microsoft.VisualStudio.Shell.11.0.dll 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | {39cec1d1-affa-4e29-9f6d-f5e976207274} 94 | TargetFrameworkMigrator 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Tests/UnitTests.testsettings: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | This test run configuration is used for running the unit tests 9 | 10 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | skip_tags: true 3 | skip_branch_with_pr: true 4 | image: Visual Studio 2017 5 | configuration: Release 6 | build: 7 | project: TargetFrameworkMigrator.sln 8 | parallel: true 9 | verbosity: minimal 10 | test: 11 | assemblies: 12 | only: 13 | - '**/TargetFrameworkMigrator_UnitTests.dll' 14 | artifacts: 15 | - path: Src\TargetFrameworkMigratorVSIX\**\*.vsix --------------------------------------------------------------------------------