zoukankan      html  css  js  c++  java
  • Visual Studio Version Interoperability

    Visual Studio Version Interoperability

    Home
    Articles
    Admin Tools
    Code Snippets
    Samples/Demos
    Work In Progress
    Archives
    Links
    About Me

    Introduction

    Microsoft officially released Visual Studio 2008 in February 2008 and Visual Studio 2010 in May 2010.  However, many users were disappointed that the file format for the older Visual Studio "project files" was not backwards compatible.

    • If you open an older Visual Studio project with a newer version of Visual Studio, you will be prompted for a conversion wizard.
    • The conversion is "one way"... once converted, the project can no longer be opened with the previous version.
    • If you selected "no" at the conversion wizard, Visual Studio just exits, and the project is not opened

    So, what if you decided to do a phased rollout of the newer Visual Studio... where some programmers are still running VS2005/VS2008?  Any project that been touched by VS2008/VS2010 is now inaccessible to the users of VS2005/VS2008.

    One solution would be to keep both the older Visual Studio on your system when you install the newer version.  Both versions co-exists peacefully.   However, that doesn't solve the problem of "accidently" converting a project.  Also, Visual Studio is huge (particularly if you install the MSDN documentation).

    But wait... I heard that Visual Studio has the ability to target multiple versions of the  Framework!   Yes, that's true, but the project files that target the .Net Framework 2.0 are still not backwards compatible with the older versions.

    Another problem exists when you download source code from the internet that's in a different format from what you've got installed.

    Project Converter

    The technique described in this article uses an external utility to convert between the Visual Studio project file formats.  It can be run on systems which do not have any version of Visual Stuido installed at all.

    ProjectConverter Screen Shot

    The program can be launched as a normal windows application or it can be installed in order to get a new Explorer "shell extension" that adds ProjectConverter to the "Open With" option when right-clicking on a *.sln file.

    "Open With" screen shot

    Note: This utility just edits the project files... it does not edit the source code itself.  It does not attempt to resolve references that may be specific to a particular version of the Framework.  For example, if you have a .Net Framework 3.5 application that uses LINQ, this utility will not somehow magically convert the source code so that it will compile on VS2005 .

    The Solution (*.sln) file

    The solution file is a text-based file that contains information about one or more projects.  Below is a typical solution file:

    Microsoft Visual Studio Solution File, Format Version 10.00
    # Visual Studio 2008
    Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ProjectConverter", 
     "ProjectConverter.vbproj", "{B637ACFD-0AFC-4FBB-A8C0-602B5ABA62F0}"
    EndProject
    Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Setup", "Setup\Setup.vdproj", 
     "{09667F41-0E35-4D40-A0A9-E71BA6740D93}"
    EndProject
    Global
      GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
      EndGlobalSection
      GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {B637ACFD-0AFC-4FBB-A8C0-602B5ABA62F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {B637ACFD-0AFC-4FBB-A8C0-602B5ABA62F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {B637ACFD-0AFC-4FBB-A8C0-602B5ABA62F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {B637ACFD-0AFC-4FBB-A8C0-602B5ABA62F0}.Release|Any CPU.Build.0 =Release|Any CPU
        {09667F41-0E35-4D40-A0A9-E71BA6740D93}.Debug|Any CPU.ActiveCfg = Debug
        {09667F41-0E35-4D40-A0A9-E71BA6740D93}.Release|Any CPU.ActiveCfg = Release
      EndGlobalSection
      GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
      EndGlobalSection
    EndGlobal

    You can see file file format marker and Project version is in the first few lines.   The version number in this file sets the number you see in the solution file's icon (er, well... using the following "translation"):

    Product Name Product Version File Format
    Visual Studio .Net v7.0 7
    Visual Studio .Net 2003  v7.1 8
    Visual Studio 2005 v8.0 9
    Visual Studio 2008 v9.0 10
    Visual Studio 2010 v10.0 11

    The Project (*.vbproj, *.csproj, and *.vcproj) files

    Below is a typical XML-based project file.   The items that require tweaking to be compatible between the different versions are highlighted in yellow.

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProductVersion>9.0.21022</ProductVersion>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{B637ACFD-0AFC-4FBB-A8C0-602B5ABA62F0}</ProjectGuid>
        <OutputType>WinExe</OutputType>
        <StartupObject>ProjectConverter.My.MyApplication</StartupObject>
        <RootNamespace>ProjectConverter</RootNamespace>
        <AssemblyName>ProjectConverter</AssemblyName>
        <FileAlignment>512</FileAlignment>
        <MyType>WindowsForms</MyType>
        <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
        <OptionExplicit>On</OptionExplicit>
        <OptionCompare>Binary</OptionCompare>
        <OptionStrict>Off</OptionStrict>
        <OptionInfer>On</OptionInfer>
        <ApplicationIcon>Icon1.ico</ApplicationIcon>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <DebugSymbols>true</DebugSymbols>
        <DebugType>full</DebugType>
        <DefineDebug>true</DefineDebug>
        <DefineTrace>true</DefineTrace>
        <OutputPath>bin\Debug\</OutputPath>
        <DocumentationFile>
        </DocumentationFile>
        <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
        <DebugType>pdbonly</DebugType>
        <DefineDebug>false</DefineDebug>
        <DefineTrace>true</DefineTrace>
        <Optimize>true</Optimize>
        <OutputPath>bin\Release\</OutputPath>
        <DocumentationFile>
        </DocumentationFile>
        <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
      </PropertyGroup>
      <ItemGroup>
        <Reference Include="System" />
        <Reference Include="System.Data" />
        <Reference Include="System.Deployment" />
        <Reference Include="System.Drawing" />
        <Reference Include="System.Windows.Forms" />
        <Reference Include="System.Xml" />
      </ItemGroup>
      <ItemGroup>
        <Import Include="Microsoft.VisualBasic" />
        <Import Include="System" />
        <Import Include="System.Collections" />
        <Import Include="System.Collections.Generic" />
        <Import Include="System.Data" />
        <Import Include="System.Drawing" />
        <Import Include="System.Diagnostics" />
        <Import Include="System.Windows.Forms" />
      </ItemGroup>
      <ItemGroup>
        <Compile Include="fmMain.vb">
          <SubType>Form</SubType>
        </Compile>
        <Compile Include="fmMain.Designer.vb">
          <DependentUpon>fmMain.vb</DependentUpon>
          <SubType>Form</SubType>
        </Compile>
        <Compile Include="My Project\AssemblyInfo.vb" />
        <Compile Include="My Project\Application.Designer.vb">
          <AutoGen>True</AutoGen>
          <DependentUpon>Application.myapp</DependentUpon>
        </Compile>
        <Compile Include="My Project\Resources.Designer.vb">
          <AutoGen>True</AutoGen>
          <DesignTime>True</DesignTime>
          <DependentUpon>Resources.resx</DependentUpon>
        </Compile>
        <Compile Include="My Project\Settings.Designer.vb">
          <AutoGen>True</AutoGen>
          <DependentUpon>Settings.settings</DependentUpon>
          <DesignTimeSharedInput>True</DesignTimeSharedInput>
        </Compile>
      </ItemGroup>
      <ItemGroup>
        <EmbeddedResource Include="fmMain.resx">
          <DependentUpon>fmMain.vb</DependentUpon>
          <SubType>Designer</SubType>
        </EmbeddedResource>
        <EmbeddedResource Include="My Project\Resources.resx">
          <Generator>VbMyResourcesResXFileCodeGenerator</Generator>
          <LastGenOutput>Resources.Designer.vb</LastGenOutput>
          <CustomToolNamespace>My.Resources</CustomToolNamespace>
          <SubType>Designer</SubType>
        </EmbeddedResource>
      </ItemGroup>
      <ItemGroup>
        <None Include="app.config" />
        <None Include="My Project\Application.myapp">
          <Generator>MyApplicationCodeGenerator</Generator>
          <LastGenOutput>Application.Designer.vb</LastGenOutput>
        </None>
        <None Include="My Project\Settings.settings">
          <Generator>SettingsSingleFileGenerator</Generator>
          <CustomToolNamespace>My</CustomToolNamespace>
          <LastGenOutput>Settings.Designer.vb</LastGenOutput>
        </None>
      </ItemGroup>
      <ItemGroup>
        <Content Include="Icon1.ico" />
      </ItemGroup>
      <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
      <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
           Other similar extension points exist, see Microsoft.Common.targets.
      <Target Name="BeforeBuild">
      </Target>
      <Target Name="AfterBuild">
      </Target>
      -->
    </Project>

    The differences in the two file formats are summarized below:

    Element VS2005 VS2008 VS2010
    Tools Version absent 3.5 4.0
    Product Version 8.0.50727  9.0.21022 absent
    Old Tools Version absent 2.0 (if converted) 3.5
    Target Framework Version absent 2.0 4.0
    Bootstrapper .NET Framework 2.0 .NET Framework 2.0 (x86) many
    Import Project $(MSBuildBinPath) $(MSBuildToolsPath) $(MSBuildToolsPath

    Other Project types

    The Deployment Project type (*.vdproj) files appear to be backward compatible and therefore do not require conversion.

    There is a completely new project file format for C/C++ in VS2010, so this utility will not be able to convert C/C++ projects to or from this new format. Sorry...

    Note: No other project types are supported by this utility.

    Source Code

    If you're interested in the inner-workings of the ProjectConverter application, take a look at the following, otherwise just skip this section and download the installer file below.

    We edit the text-based solution file first and get the list of subordinate projects that are associated with the solution.  The solution file has a binary "marker" at the beginning of  the file... so that means we need to use both the binary and text readers/writers to manipulate the file.

    ' First we read the solution file and build a list of 
    ' project files that we find inside.  We need both a binary
    ' reader and stream reader.
    fs = New FileStream(tbSolutionFile.Text, FileMode.Open)
    sr = New StreamReader(fs)
    br = New BinaryReader(fs)
    
    ' let's read Unicode Byte Order Mark (with CRLF)
    bom = br.ReadBytes(5)
    
    ' if we don't have a BOM, we create a default one
    If bom(0) <> &HEF Then
        bom(0) = &HEF
        bom(1) = &HBB
        bom(2) = &HBF
        bom(3) = &HD
        bom(4) = &HA
    
        ' rewind the streamreaders
        fs.Seek(0, SeekOrigin.Begin)
    End If
    
    sc = New StringCollection
    Do While sr.Peek() >= 0
        buf = sr.ReadLine
    
        ' no need for any fancy parsing routines
        If buf.StartsWith("Microsoft Visual Studio Solution File, Format Version") Then
            ' Yes, I know, this looks counter intuitive... but format version numbers
            ' do not match the Visual Studio version numbers.
            Select Case ConvertTo
                Case Versions.Version8
                    sc.Add("Microsoft Visual Studio Solution File, Format Version 9.00")
                Case Versions.Version9
                    sc.Add("Microsoft Visual Studio Solution File, Format Version 10.00")
                Case Versions.Version10
                    sc.Add("Microsoft Visual Studio Solution File, Format Version 11.00")
            End Select
            Continue Do
        End If
    
        If buf.StartsWith("# Visual") Then
            Select Case ConvertTo
                Case Versions.Version8
                    sc.Add("# Visual Studio 2005")
                Case Versions.Version9
                    sc.Add("# Visual Studio 2008")
                Case Versions.Version10
                    sc.Add("# Visual Studio 2010")
            End Select
            Continue Do
        End If
    
        sc.Add(buf)
    
        ' parse the project files
        If buf.StartsWith("Project(") Then
            Dim ProjParts(), ProjFile, ProjExt As String
    
            ProjParts = buf.Split(","c)
            If ProjParts.Length = 3 Then
                ProjFile = Path.GetDirectoryName(tbSolutionFile.Text) & "\" & _
                 ProjParts(1).Trim.Trim(Chr(34))
                ' we only support VB, C#, and C/C++ project types so that means 
                ' we do not attempt to convert Deployment Projects (*.vdproj)
                Try
                    ProjExt = Path.GetExtension(ProjFile)
                    If ProjExt = ".vbproj" Or ProjExt = ".csproj" Then
                        ' convert the VB/C# project files
                        If ConvertProject(ProjFile, ExistingVersion) Then
                            ProjCount += 1
                        End If
                    ElseIf ProjExt = ".vcproj" Or ProjExt = ".vcxproj" Then
                        ' convert the C/C++project files
                        If ConvertVCProject(ProjFile, ExistingVersion) Then
                            ProjCount += 1
                        End If
                    End If
                Catch ex As Exception
                    MsgBox("Could not convert project file" & vbCr & ex.Message, _
                     MsgBoxStyle.Critical, "Error")
                    ' TODO:  Perform a "rollback" on those files that
                    ' got converted so far?
                    Exit Sub
                End Try
            End If
        End If
    Loop
    fs.Close()
    
    ' OK now it's time to save the converted Solution file
    fs = New FileStream(tbSolutionFile.Text, FileMode.Open)
    sw = New StreamWriter(fs)
    bw = New BinaryWriter(fs)
    
    ' write the BOM bytes (using the BinaryWriter)
    bw.Write(bom)
    bw.Flush()
    
    ' write the remaining text (using the StreamWriter)
    For Each buf In sc
        sw.WriteLine(buf)
    Next
    sw.Flush()
    fs.Close()
    

    Next, we edit the XML-based project files using the XML Document Object Model (XDOM) routines.  Admittedly, using XDOM is a bit more complicated, since you're selecting elements and attributes to add/delete/modify.

    '
    ' Convert the VB and C# Project file
    '
    Private Function ConvertProject(ByVal ProjFile As String, ByVal ExistingVersion As Double) _
     As Boolean
        Dim xd As Xml.XmlDocument
        Dim xnsm As Xml.XmlNamespaceManager
        Dim xn, xtemp As Xml.XmlNode
        Dim temp As String
    
        xd = New Xml.XmlDocument
        xd.Load(ProjFile)
    
        xnsm = New Xml.XmlNamespaceManager(New Xml.NameTable())
        xnsm.AddNamespace("prj", "http://schemas.microsoft.com/developer/msbuild/2003")
    
        ' let's do a quick sanity check to make sure we've got the
        ' version that we're expecting.  Hey, it happens
        xn = xd.SelectSingleNode("/prj:Project", xnsm)
        If xn IsNot Nothing Then
            xtemp = xn.Attributes("ToolsVersion")
            If xtemp IsNot Nothing Then
                ' converting to VS2008, but project is already at VS2008
                If ConvertTo = Versions.Version9 And xtemp.InnerText = "3.5" Then
                    ' exit quietly
                    Return False
                End If
                ' converting to VS2010, but project is already at VS2010
                If ConvertTo = Versions.Version10 And xtemp.InnerText = "4.0" Then
                    ' exit quietly
                    Return False
                End If
            Else
                ' If converting to VS2005, but project is already at VS2005
                If ConvertTo = Versions.Version8 Then
                    ' exit quietly
                    Return False
                End If
            End If
        Else
            ' no such node?  That's bad, very bad...
            Throw New ApplicationException("Invalid project file")
        End If
    
        ' the ToolsVersion attribute (we already have selected that node)
        xn.Attributes.Remove(xn.Attributes("ToolsVersion"))
        Select Case ConvertTo
            Case Versions.Version8
                ' it gets removed
            Case Versions.Version9
                ' add the attribute
                xtemp = xd.CreateAttribute("ToolsVersion")
                xtemp.Value = "3.5"
                xn.Attributes.Append(CType(xtemp, Xml.XmlAttribute))
            Case Versions.Version10
                ' add the attribute
                xtemp = xd.CreateAttribute("ToolsVersion")
                xtemp.Value = "4.0"
                xn.Attributes.Append(CType(xtemp, Xml.XmlAttribute))
        End Select
    
        ' the ProjectVersion element
        xn = xd.SelectSingleNode("/prj:Project/prj:PropertyGroup/prj:ProductVersion", xnsm)
        If xn IsNot Nothing Then
            Select Case ConvertTo
                Case Versions.Version8
                    xn.InnerText = My.Settings.VS2005_Version
                Case Versions.Version9
                    xn.InnerText = My.Settings.VS2008_Version
                Case Versions.Version10
                    ' not used... strange
                    xn.InnerText = ""
            End Select
        End If
    
        ' the OldToolsVersion element in the first PropertyGoup
        xn = xd.SelectSingleNode("/prj:Project/prj:PropertyGroup", xnsm)
        xtemp = xd.SelectSingleNode("/prj:Project/prj:PropertyGroup/prj:OldToolsVersion", xnsm)
        If xtemp IsNot Nothing Then
            xn.RemoveChild(xtemp)
        End If
        Select Case ConvertTo
            Case Versions.Version8
                ' it gets removed
            Case Versions.Version9
                ' add a new element
                ' Note: this doesn't appear to be added in every project type, 
                ' but I bet it's harmless
                xtemp = xd.CreateElement("OldToolsVersion", xnsm.LookupNamespace("prj"))
                xtemp.AppendChild(xd.CreateTextNode("2.0"))
                xn.AppendChild(xtemp)
            Case Versions.Version10
                ' add a new element
                xtemp = xd.CreateElement("OldToolsVersion", xnsm.LookupNamespace("prj"))
                xtemp.AppendChild(xd.CreateTextNode("3.5"))
                xn.AppendChild(xtemp)
        End Select
    
        ' remove/tweak the optional TargetFrameworkVersion element
        xn = xd.SelectSingleNode("/prj:Project/prj:PropertyGroup", xnsm)
        xtemp = xd.SelectSingleNode("/prj:Project/prj:PropertyGroup/prj:TargetFrameworkVersion", _
         xnsm)
        If xtemp IsNot Nothing Then
            xn.RemoveChild(xtemp)
        End If
        Select Case ConvertTo
            Case Versions.Version8
                ' it gets removed
            Case Versions.Version9
                xtemp = xd.CreateElement("TargetFrameworkVersion", xnsm.LookupNamespace("prj"))
                xtemp.AppendChild(xd.CreateTextNode("v3.5"))
                xn.AppendChild(xtemp)
            Case Versions.Version10
                xtemp = xd.CreateElement("TargetFrameworkVersion", xnsm.LookupNamespace("prj"))
                xtemp.AppendChild(xd.CreateTextNode("v4.0"))
                xn.AppendChild(xtemp)
        End Select
    
        ' the optional BootStrapper elements.  I only remove the inappropriate values, I
        ' do not attempt to add the newer values
        Select Case ConvertTo
            Case Versions.Version8
                ' alter the value for the ProductName element using the older framework tag
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.2.0""]", xnsm)
                If xn IsNot Nothing Then
                    xtemp = xn.SelectSingleNode("prj:ProductName", xnsm)
                    xtemp.FirstChild.Value = ".NET Framework 2.0"
                End If
                ' remove the newer framework options
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.3.0""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.3.5""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Client.3.5""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.3.5.SP1""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Windows.Installer.3.1""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
            Case Versions.Version9
                ' alter the value for the ProjectName using the newer framework tag
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.2.0""]", xnsm)
                If xn IsNot Nothing Then
                    xtemp = xn.SelectSingleNode("prj:ProductName", xnsm)
                    xtemp.FirstChild.Value = ".NET Framework 2.0 %28x86%29"
                End If
    
                ' remove the newer framework options
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Client.3.5""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.3.5.SP1""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Windows.Installer.3.1""]", xnsm)
                If Not xn Is Nothing Then
                    xn.ParentNode.RemoveChild(xn)
                End If
            Case Versions.Version10
                ' alter the value for the ProjectName using the newer framework tag
                xn = xd.SelectSingleNode("/prj:Project/prj:ItemGroup/prj:BootstrapperPackage" & _
                 "[@Include=""Microsoft.Net.Framework.2.0""]", xnsm)
                If xn IsNot Nothing Then
                    xtemp = xn.SelectSingleNode("prj:ProductName", xnsm)
                    xtemp.FirstChild.Value = ".NET Framework 2.0 %28x86%29"
                End If
        End Select
    
        ' The MSBuildToolsPath vs MSBuildBinPath environmental variable.  Oddly enough 
        ' a fully patched VS2005 uses the newer MSBuildToolsPath.  So, this should only
        ' be required if you don't have VS2005 SP1 installed. However, I can't detect 
        ' that, so we take the worst case scenario, and use the older version
        For Each xn In xd.SelectNodes("/prj:Project/prj:Import", xnsm)
            xtemp = xn.Attributes("Project")
            If xtemp IsNot Nothing Then
                temp = xn.Attributes("Project").Value
                If ConvertTo >= Versions.Version9 Then
                    ' convert it to the newer MSBuildToolsPath
                    If temp.Contains("MSBuildBinPath") Then
                        temp = temp.Replace("MSBuildBinPath", "MSBuildToolsPath")
                        xtemp.Value = temp
                    End If
                Else
                    ' convert it to the older MSBuildBinPath
                    If temp.Contains("MSBuildToolsPath") Then
                        temp = temp.Replace("MSBuildToolsPath", "MSBuildBinPath")
                        xtemp.Value = temp
                    End If
                End If
            End If
        Next
    
        xd.Save(ProjFile)
        Return True
    End Function
    

    Downloads/Links

    Download the MSI Installer file: ProjectConverterSetup.msi
    Download the VB.Net Source code for this program: ProjectConverter2.zip
    The C# source code version will be available shortly

    Last Modified: 5 May 10

  • 相关阅读:
    获取有关控件的坐标
    Android PopupWindow的使用和分析
    Android RecyclerView 使用完全解析 体验艺术般的控件
    TextView中显示价格并且中间直接有一个横线
    Android Studio
    移动开发】Android中三种超实用的滑屏方式汇总(ViewPager、ViewFlipper、ViewFlow)
    Android中visibility属性VISIBLE、INVISIBLE、GONE的区别
    理解Java的IO流 2015年8月6日 21:30:38
    算法导论学习随笔——第七章 快速排序
    oj 1031 random permutation
  • 原文地址:https://www.cnblogs.com/loongfee/p/2722477.html
Copyright © 2011-2022 走看看