Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Microsoft.Dotnet.Wpf.sln
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PresentationFramework.Fluen
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Printing.Tests", "src\Microsoft.DotNet.Wpf\tests\UnitTests\System.Printing.Tests\System.Printing.Tests.csproj", "{762F6671-44CA-672D-B9C5-CFB69999F152}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OlderTargetFramework.Tests", "src\Microsoft.DotNet.Wpf\tests\UnitTests\OlderTargetFramework.Tests\OlderTargetFramework.Tests.csproj", "{47D631CE-1934-E2D8-91E1-F61730525AB1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|arm64 = Debug|arm64
Expand Down Expand Up @@ -1667,6 +1669,18 @@ Global
{762F6671-44CA-672D-B9C5-CFB69999F152}.Release|x64.Build.0 = Release|x64
{762F6671-44CA-672D-B9C5-CFB69999F152}.Release|x86.ActiveCfg = Release|x86
{762F6671-44CA-672D-B9C5-CFB69999F152}.Release|x86.Build.0 = Release|x86
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Debug|arm64.ActiveCfg = Debug|arm64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Debug|arm64.Build.0 = Debug|arm64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Debug|x64.ActiveCfg = Debug|x64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Debug|x64.Build.0 = Debug|x64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Debug|x86.ActiveCfg = Debug|x86
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Debug|x86.Build.0 = Debug|x86
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Release|arm64.ActiveCfg = Release|arm64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Release|arm64.Build.0 = Release|arm64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Release|x64.ActiveCfg = Release|x64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Release|x64.Build.0 = Release|x64
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Release|x86.ActiveCfg = Release|x86
{47D631CE-1934-E2D8-91E1-F61730525AB1}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1795,6 +1809,7 @@ Global
{0EFFC7C4-B486-4852-8CED-EDEB46E02C42} = {D0AED517-9972-41CB-8751-983E4EB8F511}
{56833D74-2D0B-5516-C1D6-B93D4FFF7612} = {A48B585E-6AB0-4F8D-8484-77F37CB44437}
{762F6671-44CA-672D-B9C5-CFB69999F152} = {A48B585E-6AB0-4F8D-8484-77F37CB44437}
{47D631CE-1934-E2D8-91E1-F61730525AB1} = {A48B585E-6AB0-4F8D-8484-77F37CB44437}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B4340004-DAC0-497D-B69D-CFA7CD93F567}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

global using Xunit;
#pragma warning disable IDE0005 // Using directive is unnecessary. New project, this will be used.
global using FluentAssertions;
#pragma warning restore IDE0005
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<Platforms>x64;x86;arm64</Platforms>
<RootNamespace />
<TargetFramework Condition="!$(TargetFramework.Contains('windows'))">$(TargetFramework)-windows</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionsVersion)" />
<PackageReference Include="xunit.stafact" Version="$(XUnitStaFactPackageVersion)" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerPackageVersion)" />
<PackageReference Include="$(SystemIOPackagingPackage)" Version="$(SystemIOPackagingVersion)" />
</ItemGroup>

<ItemGroup>
<MicrosoftPrivateWinFormsReference Include="System.Private.Windows.Core" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(WpfSourceDir)PresentationFramework\PresentationFramework.csproj" />
<ProjectReference Include="$(WpfSourceDir)System.Windows.Primitives\System.Windows.Primitives.csproj" />

<ProjectReference Include="$(WpfSourceDir)PresentationCore\PresentationCore.csproj" />
<ProjectReference Include="$(WpfSourceDir)DirectWriteForwarder\DirectWriteForwarder.vcxproj">
<UndefineProperties>TargetFramework;TargetFrameworks</UndefineProperties>
</ProjectReference>
<ProjectReference Include="$(WpfSourceDir)System.Xaml\System.Xaml.csproj" />
<ProjectReference Include="$(WpfSourceDir)WindowsBase\WindowsBase.csproj" />
<ProjectReference Include="$(WpfSourceDir)UIAutomation\UIAutomationTypes\UIAutomationTypes.csproj" />
<ProjectReference Include="$(WpfSourceDir)UIAutomation\UIAutomationProvider\UIAutomationProvider.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.Linq;

namespace System.Windows.Controls
{
public class OlderTFMTests
{
private static string s_projectPath = "";
private string _projectName = "";
private static string s_projectFile = "";

[Theory]
[InlineData("net9.0")]
[InlineData("net8.0")]
[InlineData("net47")]
[InlineData("net471")]
[InlineData("net472")]
[InlineData("net48")]
[InlineData("net481")]
public void OlderTFMTestFX(string targetFramework)
{
if (targetFramework != null)
{
Assert.True(true);
Console.WriteLine($"Starting test with target framework: {targetFramework}");
try
{
// Define project name
_projectName = "WPFSampleApp" + targetFramework;

// Create a new project
CreateProject(targetFramework, _projectName);

if (targetFramework.Contains("net48") || targetFramework.Contains("net481") || targetFramework.Contains("net472") || targetFramework.Contains("net471") || targetFramework.Contains("net47"))
{
ChangeTargetFramework(s_projectFile, targetFramework);
}
// Publish the project
string publishPath = Path.Combine(s_projectPath, "publish");
RunDotnetPublish(publishPath);

// Launch the WPF application
bool check = LaunchWPFApp(publishPath, _projectName);
if (check)
{ Assert.True(true); }
else
{ Assert.True(false); }
}
catch (Exception e)
{
Console.WriteLine($"Exception: {e}");
throw;

}
}
else
{
Console.WriteLine($"Missing or Incorrect target framework: {targetFramework}");
Assert.True(false);
}
}

private static void CreateProject(string targetFramework, string projectName)
{
// Define project path
string? defaultDrive = Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System));
if (defaultDrive == null)
{
Console.WriteLine("Failed to get the default drive.");
return;
}

string rootPath = Path.Combine(defaultDrive, "TFMProjects\\" + projectName);

// Clean up the directory if it exists
if (Directory.Exists(rootPath))
{
Directory.Delete(rootPath, true);
}

// Define project path
s_projectPath = Path.Combine(rootPath, projectName);

// Create project directory
Directory.CreateDirectory(s_projectPath);

// Command to create a new project
string createProjectCommand;
if (targetFramework is "net48" or "net481" or "net472" or "net471" or "net47")
{
createProjectCommand = $"dotnet new wpf -n {projectName}";
}
else
{
createProjectCommand = $"dotnet new wpf -n {projectName} --framework {targetFramework}";
}

// Start the process to create the project
ProcessStartInfo startInfo = new("cmd", "/c " + createProjectCommand)
{
WorkingDirectory = rootPath,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using Process? process = Process.Start(startInfo);
if (process == null)
{
Console.WriteLine("Failed to start the process.");
return;
}
process.WaitForExit();

// Read the output and error
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
Console.WriteLine(output);
if (!string.IsNullOrEmpty(error))
{
Console.WriteLine($"Error: {error}");
}

// Define project file path
s_projectFile = Path.Combine(s_projectPath, $"{projectName}.csproj");

// Verify if the projects are created
Assert.True(File.Exists(s_projectFile));
}

private static void RunDotnetPublish(string publishPath)
{
// Create project directory
Directory.CreateDirectory(publishPath);

if (Directory.Exists(publishPath))
{
Assert.True(true);
}
else
{
Assert.True(false);
}
// Set up the process start information to run the 'dotnet publish' command
var startInfo = new ProcessStartInfo
{
FileName = "dotnet",
Arguments = $"dotnet publish \"{s_projectPath}\" -c Release -r win-x64 -o \"{publishPath}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};

// Start the process
using var process = Process.Start(startInfo);
if (process != null)
{
// Read output and error streams
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
Console.WriteLine("The publish has log :--------------------- " + output);
Console.WriteLine("The publish has error :--------------------- " + error);
}

// Verify if the publish is successful
if (Directory.Exists(publishPath))
{
Console.WriteLine("Publish successfully.");
Assert.True(true);
}
else
{
Console.WriteLine("Publish failed.");
Assert.True(false);
}
}

private static bool LaunchWPFApp(string publishPath, string filenames)
{
string exePath = Path.Combine(publishPath, filenames + ".exe");

var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = exePath,
UseShellExecute = true,
}
};

// Start the WPF application
bool processStarted = process.Start();
if (!processStarted)
{
Console.WriteLine($"Failed to start process");
}

// Optionally wait for a moment to ensure the app is up
Thread.Sleep(2000);

// Close the main window of the process
if (!process.CloseMainWindow())
{
// If the main window could not be closed, kill the process
process.Kill();
}
process.WaitForExit();

// Check if the process has exited
Assert.True(process.HasExited);
return process.ExitCode == 0;

}

//Change the TFM to latest version of .Net
private static void ChangeTargetFramework(string WpfProjectPath, string updateTargetFramework)
{
if (!File.Exists(WpfProjectPath))
{
Console.WriteLine("Project file not found.");
return;
}

// Load the project file
XDocument doc = XDocument.Load(WpfProjectPath);
XElement? propertyGroup = doc.Descendants("PropertyGroup").FirstOrDefault();

if (propertyGroup != null)
{
// Add LangVersion for WPF Framework project type
XElement langVersionElement = new XElement("LangVersion", "10.0");
propertyGroup.Add(langVersionElement);

XElement? targetFrameworkElement = propertyGroup.Elements("TargetFramework").FirstOrDefault();
if (targetFrameworkElement != null)
{
targetFrameworkElement.Value = updateTargetFramework;
}
else
{
propertyGroup.Add(new XElement("TargetFramework", updateTargetFramework));
}

// Save the changes
doc.Save(WpfProjectPath);
Console.WriteLine($"TLangVersion added in '{WpfProjectPath}'project .");
}
else
{
Console.WriteLine("No PropertyGroup found in the project file.");
}
}
}
}