Turwaith
Turwaith
CC#
Created by Turwaith on 6/20/2024 in #help
Launching WPF Windows via code when wpf is not startup project
My solution consists of two project. One is a console application and is the startup project, the other one is a wpf project. The two projects communicate with each other using an interface. Now one method that is called via the interface launches the MainWindow of the wpf project. I know that wpf gui applications need to run on the [STAThread] and I know how to declare that, but it does not seem possible in my case. I have added the flag to literally every single method in the call stack that opens the MainWindow and it still threw me an exception saying it was not run on the STAThread. So that doesn't seem to work out. I then have tried calling it in a specifically declared thread, as you can see in the code block below. But then, as soon as I close the window and reopen it, it says Cannot create more than one System.Windows.Application instance in the same AppDomain . Don't I dispose the Application object correctly?
public class GradeAssigner : IGradeAssigner
{
private static Application? _app;
private static readonly object _lock = new object();
public bool GetGradeAssignments(List<string> customerGrades)
{
var thread = new Thread(() =>
{
lock (_lock)
{
if (_app == null)
{
_app = new Application();
_app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
}
var viewModel = new MainViewModel(customerGrades);
var mainWindow = new MainWindow(viewModel);
mainWindow.Closed += (s, e) =>
{
mainWindow.Dispatcher.InvokeShutdown();
_app = null;
};
_app.Run(mainWindow);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return true;
}
}
public class GradeAssigner : IGradeAssigner
{
private static Application? _app;
private static readonly object _lock = new object();
public bool GetGradeAssignments(List<string> customerGrades)
{
var thread = new Thread(() =>
{
lock (_lock)
{
if (_app == null)
{
_app = new Application();
_app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
}
var viewModel = new MainViewModel(customerGrades);
var mainWindow = new MainWindow(viewModel);
mainWindow.Closed += (s, e) =>
{
mainWindow.Dispatcher.InvokeShutdown();
_app = null;
};
_app.Run(mainWindow);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return true;
}
}
2 replies
CC#
Created by Turwaith on 5/24/2024 in #help
Preventing SQL Injections with string based queries
I'm working with an SDK to execute queries in a mssql database. This SDK offers a method that is required to execute those queries, but this method only takes a string. And string based queries are damn prone to sql injection attacks. So I want to write a middle piece method that takes in a SqlCommand object in which I can set parameters and returns the assembled query as string. Please give me feedback on it:
public static string GetParsedSqlCommand(SqlCommand cmd)
{
string sql = cmd.CommandText;
foreach (SqlParameter param in cmd.Parameters)
{
string placeholder = param.ParameterName;
string value = FormatSqlValue(param);
sql = sql.Replace("@" + placeholder, value);
}
return sql;
}

public static string FormatSqlValue(SqlParameter param)
{
if (param.Value == DBNull.Value || param.Value == null)
{
return "NULL";
}

switch (param.SqlDbType)
{
case System.Data.SqlDbType.NVarChar:
case System.Data.SqlDbType.VarChar:
case System.Data.SqlDbType.Char:
case System.Data.SqlDbType.NChar:
case System.Data.SqlDbType.Text:
case System.Data.SqlDbType.NText:
case System.Data.SqlDbType.UniqueIdentifier:
case System.Data.SqlDbType.Xml:
return $"'{param.Value.ToString().Replace("'", "''")}'";
case System.Data.SqlDbType.Date:
case System.Data.SqlDbType.DateTime:
case System.Data.SqlDbType.DateTime2:
case System.Data.SqlDbType.SmallDateTime:
case System.Data.SqlDbType.Time:
return $"'{((DateTime)param.Value).ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)}'";
case System.Data.SqlDbType.Bit:
return ((bool)param.Value) ? "1" : "0";
default:
return param.Value.ToString();
}
}
public static string GetParsedSqlCommand(SqlCommand cmd)
{
string sql = cmd.CommandText;
foreach (SqlParameter param in cmd.Parameters)
{
string placeholder = param.ParameterName;
string value = FormatSqlValue(param);
sql = sql.Replace("@" + placeholder, value);
}
return sql;
}

public static string FormatSqlValue(SqlParameter param)
{
if (param.Value == DBNull.Value || param.Value == null)
{
return "NULL";
}

switch (param.SqlDbType)
{
case System.Data.SqlDbType.NVarChar:
case System.Data.SqlDbType.VarChar:
case System.Data.SqlDbType.Char:
case System.Data.SqlDbType.NChar:
case System.Data.SqlDbType.Text:
case System.Data.SqlDbType.NText:
case System.Data.SqlDbType.UniqueIdentifier:
case System.Data.SqlDbType.Xml:
return $"'{param.Value.ToString().Replace("'", "''")}'";
case System.Data.SqlDbType.Date:
case System.Data.SqlDbType.DateTime:
case System.Data.SqlDbType.DateTime2:
case System.Data.SqlDbType.SmallDateTime:
case System.Data.SqlDbType.Time:
return $"'{((DateTime)param.Value).ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)}'";
case System.Data.SqlDbType.Bit:
return ((bool)param.Value) ? "1" : "0";
default:
return param.Value.ToString();
}
}
30 replies
CC#
Created by Turwaith on 4/18/2024 in #help
Nuget restore (via gitlab runner) fails at a specific package
I am trying to set up a windows gitlab runner to build and publish my WPF .NET Framework 4.8 project. My gitlab-ci.yml file looks as follows:
stages:
- build_and_publish

build_and_publish:
stage: build_and_publish
script:
- 'nuget locals all -clear'
- 'nuget restore $env:SOLUTION_NAME -SolutionDirectory .'
- 'dotnet add "$env:PROJECT_PATH" package Microsoft.Toolkit.Uwp.Notifications --version 7.1.3'
- '& "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" $env:SOLUTION_NAME /p:Configuration=Release /p:Platform="Any CPU" /p:OutputPath="$env:CI_PROJECT_DIR\bin\Release\"'
- 'mkdir Publish'
- 'xcopy /I /E /Y "$env:CI_PROJECT_DIR\bin\Release\*" Publish/'
- 'Compress-Archive -Path Publish\* -DestinationPath Publish\Product.zip -Force'
artifacts:
name: "Product-${CI_COMMIT_REF_NAME}"
paths:
- Publish/Product.zip
expire_in: never
tags:
- windows

variables:
SOLUTION_NAME: './Source/Product.sln'
PROJECT_PATH: './Source/Product.GUI/Product.GUI.csproj'

cache:
paths:
- .nuget/
stages:
- build_and_publish

build_and_publish:
stage: build_and_publish
script:
- 'nuget locals all -clear'
- 'nuget restore $env:SOLUTION_NAME -SolutionDirectory .'
- 'dotnet add "$env:PROJECT_PATH" package Microsoft.Toolkit.Uwp.Notifications --version 7.1.3'
- '& "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" $env:SOLUTION_NAME /p:Configuration=Release /p:Platform="Any CPU" /p:OutputPath="$env:CI_PROJECT_DIR\bin\Release\"'
- 'mkdir Publish'
- 'xcopy /I /E /Y "$env:CI_PROJECT_DIR\bin\Release\*" Publish/'
- 'Compress-Archive -Path Publish\* -DestinationPath Publish\Product.zip -Force'
artifacts:
name: "Product-${CI_COMMIT_REF_NAME}"
paths:
- Publish/Product.zip
expire_in: never
tags:
- windows

variables:
SOLUTION_NAME: './Source/Product.sln'
PROJECT_PATH: './Source/Product.GUI/Product.GUI.csproj'

cache:
paths:
- .nuget/
Now my project contains the following external packages: - Microsoft.Toolkit.Uwp.Notifications/7.1.3 - PDFtoPrinter/1.5.0 - Serilog.Sinks.File - Serilog Now the runner can successfully restore all the package EXCEPT the first one (Notifications). I have even, as you can see, specifically added the package through the script. It definitely is available on the nuget source. On my local machine (Windows 11, Rider) there is not a single problem with restore and build. Does anyone have any idea why my windows runner fails at restoring this specific package?
8 replies
CC#
Created by Turwaith on 1/9/2024 in #help
HttpClient does not return anything
I am currently writing a method that makes a GET request to a server. The code I'm using for that is
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromSeconds(5);

httpClient.DefaultRequestHeaders.Add("licenseKey", licenseKey);
httpClient.DefaultRequestHeaders.Add("customerKey", customerKey);
string url = "http://localhost:3001/api/myTool/license/register";
HttpResponseMessage response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string responseBody = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(responseBody);

return json["expiresOn"]?.ToString();
}
else
{
return null;
}
}
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromSeconds(5);

httpClient.DefaultRequestHeaders.Add("licenseKey", licenseKey);
httpClient.DefaultRequestHeaders.Add("customerKey", customerKey);
string url = "http://localhost:3001/api/myTool/license/register";
HttpResponseMessage response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string responseBody = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(responseBody);

return json["expiresOn"]?.ToString();
}
else
{
return null;
}
}
For the endpoint, I'm currently using Mockoon until the actual server is ready. Now my call does not return. It neither comes back with an actual response nor does it throw the TaskCanceledException which it should after timing out. I've let it run for over 2 minutes now and it never reaches the exception nor the if statement right below the call. How can that happen? Mockoon logs the call and also seems to send something back, but this never arrives apparently. I can use call the endpoint successfully using postman, so that can't be it...
28 replies
CC#
Created by Turwaith on 8/22/2023 in #help
❔ AWS DDB and Lambda integration doesn't work
As mentioned in the title, I have created a DDB - Lambda - API gateway construct according to this tutorial: https://hevodata.com/learn/lambda-dynamodb/ Now I have done everything according to the tutorial, except the name of the DB table and the fields inside this table. The API does not seem to work though when I test it from Insomnia. Could somebody take a few minutes and look over the tutorial if something looks strange to you? Or build it yourself according to the tutorial to check if it works for you? I am just getting a 500 Internal Server Error back which could be literally anything. I wouldn't even have a clue what to google for... It would really help me if someone who knows their shit around AWS could help me real quick here :)
2 replies
CC#
Created by Turwaith on 4/13/2023 in #help
❔ Akka.net Actors are not responding in time
I have a system that consists of two Actor classes and a class that calls these actors.
public class ActorsystemManager
{
readonly ActorSystem simulationActorSystem;
readonly IActorRef updateActorRef;
private List<ActorState> currentActorStates = new();

private readonly object locker = new();

public int ActorChangeInterval { get; set; }

// This property is accessed by both this class to write and by the interface to read. Always use "lock" when accessing it!
public List<ActorState> CurrentActorStates
{
get
{
lock (locker)
{
return currentActorStates;
}
}
set
{
lock (locker)
{
currentActorStates = value;
}
}
}

public ActorsystemManager(int actorChangeInterval, List<int[]> coordinates)
{
ActorChangeInterval = actorChangeInterval;

simulationActorSystem = ActorSystem.Create("SimulationActorSystem");
updateActorRef = simulationActorSystem.ActorOf(Props.Create<UpdateActor>(actorChangeInterval, coordinates), "UpdateActor");

UpdateTimer timer = new UpdateTimer();
timer.Elapsed += OnTimerTick;
}

private void OnTimerTick(object sender, EventArgs e)
{
updateActorRef.Ask<List<ActorState>>("update")
.ContinueWith(task =>
{
if (task.IsCompletedSuccessfully)
{
UpdateCurrentActorStates(task.Result);
}
// Handle other cases, like task.IsFaulted or task.IsCanceled, if needed
}, TaskScheduler.Default);
}

private void UpdateCurrentActorStates(List<ActorState> result)
{
CurrentActorStates = new List<ActorState>(result);
}

public void Trigger(int[] coordinates)
{
updateActorRef.Tell(coordinates);
}

public bool Dispose()
{
try
{
simulationActorSystem.Dispose();
return true;
}
catch (Exception)
{

return false;
}
}
}
public class ActorsystemManager
{
readonly ActorSystem simulationActorSystem;
readonly IActorRef updateActorRef;
private List<ActorState> currentActorStates = new();

private readonly object locker = new();

public int ActorChangeInterval { get; set; }

// This property is accessed by both this class to write and by the interface to read. Always use "lock" when accessing it!
public List<ActorState> CurrentActorStates
{
get
{
lock (locker)
{
return currentActorStates;
}
}
set
{
lock (locker)
{
currentActorStates = value;
}
}
}

public ActorsystemManager(int actorChangeInterval, List<int[]> coordinates)
{
ActorChangeInterval = actorChangeInterval;

simulationActorSystem = ActorSystem.Create("SimulationActorSystem");
updateActorRef = simulationActorSystem.ActorOf(Props.Create<UpdateActor>(actorChangeInterval, coordinates), "UpdateActor");

UpdateTimer timer = new UpdateTimer();
timer.Elapsed += OnTimerTick;
}

private void OnTimerTick(object sender, EventArgs e)
{
updateActorRef.Ask<List<ActorState>>("update")
.ContinueWith(task =>
{
if (task.IsCompletedSuccessfully)
{
UpdateCurrentActorStates(task.Result);
}
// Handle other cases, like task.IsFaulted or task.IsCanceled, if needed
}, TaskScheduler.Default);
}

private void UpdateCurrentActorStates(List<ActorState> result)
{
CurrentActorStates = new List<ActorState>(result);
}

public void Trigger(int[] coordinates)
{
updateActorRef.Tell(coordinates);
}

public bool Dispose()
{
try
{
simulationActorSystem.Dispose();
return true;
}
catch (Exception)
{

return false;
}
}
}
Actors:
internal class UpdateActor : ReceiveActor
{
public List<IActorRef> HexagonActors { get; set; }

public UpdateActor()
{
HexagonActors = new List<IActorRef>();

ReceiveAsync<string>(data => data.ToLower().Equals("update"), async data => await Update());

Receive<int[]>(data => Trigger(data));
}

public UpdateActor(int actorChangeInterval, List<int[]> coordinates) : this()
{
foreach (var item in coordinates)
{
string coordinatesText = $"{item[0]}_{item[1]}";
var child = Context.ActorOf(Props.Create<HexagonActor>(actorChangeInterval, item), coordinatesText);
HexagonActors.Add(child);
}
}

private async Task Update()
{
var actorStates = new List<ActorState>();

foreach (var actor in HexagonActors)
{
try
{
var actorState = await actor.Ask<ActorState>("update", TimeSpan.FromMilliseconds(200));
actorStates.Add(actorState);
}
catch (AskTimeoutException ex)
{
throw new AskTimeoutException("");
}
}

Sender.Tell(actorStates);
}

private void Trigger(int[] coordinates)
{
var coordinateAddress = $"{coordinates[0]}_{coordinates[1]}";
Context.ActorSelection("akka://SimulationActorSystem/user/UpdateActor/" + coordinateAddress).Tell("trigger");
}
}
internal class UpdateActor : ReceiveActor
{
public List<IActorRef> HexagonActors { get; set; }

public UpdateActor()
{
HexagonActors = new List<IActorRef>();

ReceiveAsync<string>(data => data.ToLower().Equals("update"), async data => await Update());

Receive<int[]>(data => Trigger(data));
}

public UpdateActor(int actorChangeInterval, List<int[]> coordinates) : this()
{
foreach (var item in coordinates)
{
string coordinatesText = $"{item[0]}_{item[1]}";
var child = Context.ActorOf(Props.Create<HexagonActor>(actorChangeInterval, item), coordinatesText);
HexagonActors.Add(child);
}
}

private async Task Update()
{
var actorStates = new List<ActorState>();

foreach (var actor in HexagonActors)
{
try
{
var actorState = await actor.Ask<ActorState>("update", TimeSpan.FromMilliseconds(200));
actorStates.Add(actorState);
}
catch (AskTimeoutException ex)
{
throw new AskTimeoutException("");
}
}

Sender.Tell(actorStates);
}

private void Trigger(int[] coordinates)
{
var coordinateAddress = $"{coordinates[0]}_{coordinates[1]}";
Context.ActorSelection("akka://SimulationActorSystem/user/UpdateActor/" + coordinateAddress).Tell("trigger");
}
}
2nd actor and problem follows in a second message, hang on
4 replies
CC#
Created by Turwaith on 3/31/2023 in #help
❔ Porting a mvvm based WPF application to WinUI 3
I am trying to rewrite a WPF application that is based on the mvvm pattern into WinUI 3. Now I already fail at the MainWindow. In WPF, I usually don't have any content in the MainWindow, I only use it to fill in the views I then fill with content. I use Window.DataContext and Window.Resources for that, as follows:
<Window x:Class="MyProject.Client.ClientUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="clr-namespace:MyProject.Client.ClientUI.ViewModels"
xmlns:views="clr-namespace:MyProject.Client.ClientUI.Views"
xmlns:local="clr-namespace:MyProject.Client.ClientUI"
mc:Ignorable="d"
Title="{Binding Name}">

<Window.DataContext>
<viewmodels:MainViewModel />
</Window.DataContext>

<Window.Resources>
<DataTemplate DataType="{x:Type viewmodels:DisplayViewModel}">
<views:DisplayView />
</DataTemplate>
</Window.Resources>

<Grid>

<ContentControl Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
<Window x:Class="MyProject.Client.ClientUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="clr-namespace:MyProject.Client.ClientUI.ViewModels"
xmlns:views="clr-namespace:MyProject.Client.ClientUI.Views"
xmlns:local="clr-namespace:MyProject.Client.ClientUI"
mc:Ignorable="d"
Title="{Binding Name}">

<Window.DataContext>
<viewmodels:MainViewModel />
</Window.DataContext>

<Window.Resources>
<DataTemplate DataType="{x:Type viewmodels:DisplayViewModel}">
<views:DisplayView />
</DataTemplate>
</Window.Resources>

<Grid>

<ContentControl Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
Now this seems not to work anymore in WinUI 3, as VS keeps telling me that Window doesn't have these properties. How would I do that same thing in WinUI 3?
7 replies
CC#
Created by Turwaith on 3/2/2023 in #help
✅ WPF Window is too big when Height and Width are bound to a property
I have a simple WPF MVVM application where I want the code to be able to response to window size changes, so I bound Height and Width of the window to respective C# properties. Now the designer shows the window in the correct size, but when I run the app, the window becomes a lot wider. The properties are never set except at their declaration. When I replace the height and width bindings with fixed values in the xaml, it works. How do I get this working using those bindings?
43 replies
CC#
Created by Turwaith on 1/25/2023 in #help
❔ Deploying a Blazor WebAssambly app.... but how??
I'm about to finish a front end that I have written in Blazor Wasm. Now I want to deploy it, so that I have a neat little folder with index.html in it as well as css, js, and pages folder. Just like if I'd built in in HTML and JS from scratch. Like your standard folder and file structure to host it on any simple webserver. Now I have tried using the Publish tab and published it to a folder. I've also tried using the console. But I only get some css and an index.html in that resulting folder that does nothing. None of my created pages are there. What am I doing wrong? I have not changed any project structure since creating the project from a wasm template
99 replies
CC#
Created by Turwaith on 10/26/2022 in #help
FizzBuzz as short as possible
With a little help from StackOverflow I came up with this:
List<string> testList = new List<string>();
testList.Add(Enumerable.Range(1, 200)
.Select(n => n % 15 == 0 ? "FizzBuzz"
: n % 3 == 0 ? "Fizz"
: n % 5 == 0 ? "Buzz"
: n.ToString()).ToString());
List<string> testList = new List<string>();
testList.Add(Enumerable.Range(1, 200)
.Select(n => n % 15 == 0 ? "FizzBuzz"
: n % 3 == 0 ? "Fizz"
: n % 5 == 0 ? "Buzz"
: n.ToString()).ToString());
Now it adds only one element though, which is "System.Linq.Enumerable+SelectRangeIterator'1[System.String]". How do I get this expression to have one list object for each number?
4 replies
CC#
Created by Turwaith on 9/8/2022 in #help
WPF - Canvas does not respond to key press anymore
I have an application where I can click on a canvas and when I hit the Enter key, a polygon is drawn with my clicked locations as corners. I do work with MVVM, so everything is using {Binding ...}. I catch both the mouse click and the key press via Interaction.Triggers. Now, next to my canvas are a few buttons. They do not have any functionality yet, there is no command binding so far on those buttons. Now everything works fine, until I click one of those buttons. Let's say I draw a few polygons on my canvas, then I start drawing a new one (by clicking on the canvas). When I now click on one of those yet-functionless buttons and then want to hit enter to draw the polygon on the canvas, the key pressed is no longer recognized. I can keep clicking on the canvas and it does recognize the mouse clicks, but the enter key just won't work anymore. It doesn't call the command that was bound to the key press. Why is that and how do I solve that? I'm losing my mind.
3 replies