├── .gitignore
├── ConvertToMsBuildSdk
├── App.config
├── AssemblyInfo.fs
├── ConvertToMsBuildSdk.fsproj
├── Program.fs
└── packages.config
├── DNTools.sln
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.user
2 | *.suo
3 | *.cache
4 | *.ncrunchsolution
5 | *.dgml
6 | bin
7 | obj
8 | packages
9 | .vs
10 | *~
11 | all.userprefs
12 | *.mdb
13 |
--------------------------------------------------------------------------------
/ConvertToMsBuildSdk/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ConvertToMsBuildSdk/AssemblyInfo.fs:
--------------------------------------------------------------------------------
1 | namespace ConvertToMsBuildSdk.AssemblyInfo
2 |
3 | open System.Reflection
4 | open System.Runtime.CompilerServices
5 | open 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 | []
11 | []
12 | []
13 | []
14 | []
15 | []
16 | []
17 | []
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | []
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 | []
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 | // You can specify all the values or you can default the Build and Revision Numbers
35 | // by using the '*' as shown below:
36 | // []
37 | []
38 | []
39 |
40 | do
41 | ()
--------------------------------------------------------------------------------
/ConvertToMsBuildSdk/ConvertToMsBuildSdk.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net7.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ConvertToMsBuildSdk/Program.fs:
--------------------------------------------------------------------------------
1 |
2 | open System.IO
3 | open System.Linq
4 | open System.Xml.Linq
5 |
6 | #nowarn "0077" // op_Explicit
7 | let inline (!>) (x : ^a) : ^b = (((^a or ^b) : (static member op_Explicit : ^a -> ^b) x))
8 |
9 |
10 | let NsMsBuild = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003")
11 | let NsNone = XNamespace.None
12 |
13 |
14 |
15 | let convertPackageConfig (projectFile : FileInfo) =
16 | let packageFileName = projectFile.Directory.GetFiles("packages.config").SingleOrDefault()
17 | if packageFileName |> isNull |> not then
18 | let xdoc = XDocument.Load (packageFileName.FullName)
19 | packageFileName.Delete()
20 |
21 | let pkgs = xdoc.Descendants(NsNone + "package")
22 | |> Seq.map (fun x -> XElement(NsNone + "PackageReference",
23 | XAttribute(NsNone + "Include", (!> x.Attribute(NsNone + "id") : string)),
24 | XAttribute(NsNone + "Version", (!> x.Attribute(NsNone + "version") : string))))
25 | XElement(NsNone + "ItemGroup", pkgs)
26 | else
27 | null
28 |
29 |
30 |
31 | // http://www.natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/
32 | let convertProject (projectFile : FileInfo) =
33 | let projectFileName = projectFile.Name |> Path.GetFileNameWithoutExtension
34 | let xdoc = XDocument.Load (projectFile.FullName)
35 |
36 | let rewrite (xel : XElement) =
37 | if xel |> isNull |> not then
38 | XElement(NsNone + xel.Name.LocalName,
39 | xel.Attributes() |> Seq.map (fun x -> XAttribute(NsNone + x.Name.LocalName, x.Value)),
40 | xel.Nodes() |> Seq.filter (fun x -> x.NodeType = System.Xml.XmlNodeType.Text))
41 | else
42 | null
43 |
44 | // https://docs.microsoft.com/en-us/dotnet/standard/frameworks
45 | let xTargetFx = match !> xdoc.Descendants(NsMsBuild + "TargetFrameworkVersion").First() : string with
46 | | "v3.5" -> "net35"
47 | | "v4.0" -> "net40"
48 | | "v4.5" -> "net45"
49 | | "v4.5.1" -> "net451"
50 | | "v4.5.2" -> "net452"
51 | | "v4.6" -> "net46"
52 | | "v4.6.1" -> "net461"
53 | | "v4.6.2" -> "net462"
54 | | "v4.7" -> "net47"
55 | | "v4.7.1" -> "net471"
56 | | "v4.7.2" -> "net472"
57 | | x -> failwithf "Unsupported TargetFrameworkVersion %A" x
58 | |> (fun x -> XElement(NsNone + "TargetFramework", x))
59 |
60 | let xPlatform = match !> xdoc.Descendants(NsMsBuild + "Platform").FirstOrDefault() : string with
61 | | null -> null
62 | | "AnyCPU" -> null
63 | | x -> XElement(NsNone + "PlatformTarget", x)
64 |
65 | let xunsafe = xdoc.Descendants(NsMsBuild + "AllowUnsafeBlocks").FirstOrDefault() |> rewrite
66 |
67 | let xSignAss = xdoc.Descendants(NsMsBuild + "SignAssembly").FirstOrDefault() |> rewrite
68 |
69 | let xOriginatorSign = xdoc.Descendants(NsMsBuild + "AssemblyOriginatorKeyFile").FirstOrDefault() |> rewrite
70 |
71 | let xAssName = match !> xdoc.Descendants(NsMsBuild + "AssemblyName").FirstOrDefault() : string with
72 | | x when x <> projectFileName -> XElement(NsNone + "AssemblyName", x)
73 | | _ -> null
74 |
75 | let xRootNs = match !> xdoc.Descendants(NsMsBuild + "RootNamespace").FirstOrDefault() : string with
76 | | x when x <> projectFileName -> XElement(NsNone + "RootNamespace", x)
77 | | _ -> null
78 |
79 | let xOutType = match !> xdoc.Descendants(NsMsBuild + "OutputType").FirstOrDefault() : string with
80 | | null -> null
81 | | "Library" -> null
82 | | x -> XElement(NsNone + "OutputType", x)
83 |
84 | let xWarnAsErr = xdoc.Descendants(NsMsBuild + "TreatWarningsAsErrors").FirstOrDefault() |> rewrite
85 |
86 | let xWarns = xdoc.Descendants(NsMsBuild + "WarningsAsErrors").FirstOrDefault() |> rewrite
87 |
88 | let isFSharp = xdoc.Descendants(NsMsBuild + "Compile")
89 | |> Seq.exists (fun x -> (!> x.Attribute(NsNone + "Include") : string).EndsWith(".fs"))
90 | let src = xdoc.Descendants(NsMsBuild + "Compile")
91 | |> Seq.filter (fun x -> isFSharp || (!> x.Attribute(NsNone + "Include") : string).StartsWith(".."))
92 | |> Seq.map rewrite
93 | let res = xdoc.Descendants(NsMsBuild + "EmbeddedResource")
94 | |> Seq.filter (fun x -> (!> x.Attribute(NsNone + "Include") : string).StartsWith(".."))
95 | |> Seq.map rewrite
96 | let content = xdoc.Descendants(NsMsBuild + "Content")
97 | |> Seq.map rewrite
98 | let none = xdoc.Descendants(NsMsBuild + "None")
99 | |> Seq.filter (fun x -> (!> x.Attribute(NsNone + "Include") : string) <> "packages.config")
100 | |> Seq.map rewrite
101 | let xSrc = XElement(NsNone + "ItemGroup", src, content, res, none)
102 |
103 | let prjRefs = xdoc.Descendants(NsMsBuild + "ProjectReference")
104 | |> Seq.map rewrite
105 | let xPrjRefs = if prjRefs.Any() then XElement(NsNone + "ItemGroup", prjRefs)
106 | else null
107 |
108 | let refs = xdoc.Descendants(NsMsBuild + "Reference")
109 | |> Seq.filter (fun x -> x.HasElements |> not)
110 | |> Seq.map rewrite
111 | let xRefs = if refs.Any() then XElement(NsNone + "ItemGroup", refs)
112 | else null
113 |
114 | let xPkgs = convertPackageConfig projectFile
115 |
116 | XDocument(
117 | XElement(NsNone + "Project",
118 | XAttribute(NsNone + "Sdk", "Microsoft.NET.Sdk"),
119 | XElement(NsNone + "PropertyGroup",
120 | XElement(NsNone + "AutoGenerateBindingRedirects", "true"),
121 | XElement(NsNone + "GenerateAssemblyInfo", "false"),
122 | xTargetFx,
123 | xPlatform,
124 | xunsafe,
125 | xSignAss,
126 | xOriginatorSign,
127 | xAssName,
128 | xRootNs,
129 | xOutType,
130 | xWarnAsErr,
131 | xWarns),
132 | xRefs,
133 | xPkgs,
134 | xSrc,
135 | xPrjRefs))
136 |
137 | let isCandidate (projectFile : FileInfo) =
138 | let xdoc = XDocument.Load (projectFile.FullName)
139 | xdoc.Root.Attribute(NsNone + "Sdk") |> isNull
140 |
141 |
142 | let saveProject (projectFile : FileInfo, content : XDocument) =
143 | content.Save (projectFile.FullName)
144 |
145 |
146 | let searchProjects (rootFolder : DirectoryInfo) =
147 | rootFolder.EnumerateFiles("*.csproj", SearchOption.AllDirectories)
148 | |> Seq.append (rootFolder.EnumerateFiles("*.vbproj", SearchOption.AllDirectories))
149 | |> Seq.append (rootFolder.EnumerateFiles("*.fsproj", SearchOption.AllDirectories))
150 |
151 | []
152 | let main argv =
153 | if argv |> Array.length = 0 then failwithf "Usage: ConvertToMsBuildSdk "
154 | let rootFolder = argv.[0] |> DirectoryInfo
155 | if rootFolder.Exists |> not then failwithf "Directory %A does not exist" rootFolder
156 |
157 | rootFolder |> searchProjects
158 | |> Seq.filter isCandidate
159 | |> Seq.map (fun x -> x, convertProject x)
160 | |> Seq.iter saveProject
161 | 0
162 |
163 |
--------------------------------------------------------------------------------
/ConvertToMsBuildSdk/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/DNTools.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27004.2009
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ConvertToMsBuildSdk", "ConvertToMsBuildSdk\ConvertToMsBuildSdk.fsproj", "{D426D8BE-EF8E-4B22-9040-80752C526B57}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {D426D8BE-EF8E-4B22-9040-80752C526B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {D426D8BE-EF8E-4B22-9040-80752C526B57}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {D426D8BE-EF8E-4B22-9040-80752C526B57}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {D426D8BE-EF8E-4B22-9040-80752C526B57}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {47078017-2B2D-42A5-90E5-7006415A49E1}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ConvertToMsBuildSdk
2 | ConvertToMsBuildSdk converts msbuild .NET projects to new project style (Sdk).
3 |
4 | Usage:
5 | ```
6 | ConvertToMsBuildSdk
7 | ```
8 |
9 | It will look for projects (*.csproj, *.vbproj, *.fsproj) and convert them to new format.
10 |
11 | What is being converted is covered here for the most part:
12 | http://www.natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/
13 |
14 | ## Restrictions
15 | * NuGet packages are converted to PackageReference. Paket is not supported for the moment.
16 | * Imports are discarded
17 | * DefineConstants are discarded
18 | * AutoGenerateBindingRedirects is forced to true
19 | * GenerateAssemblyInfo is forced to false
20 | * only .net fx 3.5+ is supported
21 |
22 | ## Disclaimer
23 | Converted projects are overwritten !!
24 | I can't be liable if you lose something or things do not work as expected !
25 | You have been warned !
26 |
27 | ## License
28 | Do what you want with this source code!
29 |
--------------------------------------------------------------------------------