Posts


Use nssm or powershell to register a windows service application.

Registering a Windows Service with PowerShell and SC.exe

Example using powershell and sc to register a new windows service.

$serviceName = "PLACEHOLDER"
$exePath = "C:\Path\To\[PLACEHOLDER].exe"
$displayName = "PLACEHOLDER"
$description = "A service for PLACEHOLDER"

New-Service -Name $serviceName -BinaryPathName $exePath -DisplayName $displayName -Description $description -StartupType Automatic

# Set the service to restart on failure
sc.exe failure $serviceName reset= 0 actions= restart/60000/restart/60000/restart/60000

# Verify service configuration
Get-Service -Name $serviceName
sc.exe qc $serviceName
sc.exe qfailure $serviceName

Example C# Console Application for Windows Service

Below is a minimal C# console application that can be registered as a Windows Service. Make sure to add a reference to System.ServiceProcess.

using System;
using System.ServiceProcess;
using System.Threading;

public class SampleService : ServiceBase
{
    private Thread workerThread;

    public SampleService()
    {
        this.ServiceName = "SampleService";
    }

    protected override void OnStart(string[] args)
    {
        workerThread = new Thread(DoWork);
        workerThread.Start();
    }

    protected override void OnStop()
    {
        workerThread?.Abort();
    }

    private void DoWork()
    {
        while (true)
        {
            // Service logic here
            Thread.Sleep(10000);
        }
    }

    public static void Main()
    {
        ServiceBase.Run(new SampleService());
    }
}

Note: To debug or run as a console app, you can add a conditional block in Main to run as a console when not installed as a service.


CrystalCMD is a C#/dotnet program that loads JSON files into Crystal Reports to produce PDFs. Initially an experimental proof of concept, it demonstrates generating Crystal Reports on Linux using the .NET framework (wine).

Key Features:

  • PDF Generation: Converts JSON (and embedded csv) data into PDF reports with Crystal Reports templates.
  • Command Line & Server Modes: Supports both modes; server mode is recommended for better performance.
  • Cross-Platform: Works on Linux and can run .NET implementations using Wine.

Client

Nuget package

dotnet add package Majorsilence.CrystalCmd.Client

Curl example

curl -u "username:password" -F "reportdata=@test.json" -F "reporttemplate=@the_dataset_report.rpt" http://127.0.0.1:4321/export --output testout.pdf

C# code example

DataTable dt = new DataTable();

// init reprt data
var reportData = new Majorsilence.CrystalCmd.Common.Data()
{
    DataTables = new Dictionary<string, string>(),
    MoveObjectPosition = new List<Majorsilence.CrystalCmd.Common.MoveObjects>(),
    Parameters = new Dictionary<string, object>(),
    SubReportDataTables = new List<Majorsilence.CrystalCmd.Common.SubReports>()
};

// add as many data tables as needed.  The client library will do the necessary conversions to json/csv.
reportData.AddData("report name goes here", "table name goes here", dt);

// export to pdf
var crystalReport = System.IO.File.ReadAllBytes("The rpt template file path goes here");
using (var instream = new MemoryStream(crystalReport))
using (var outstream = new MemoryStream())
{
    var rpt = new Majorsilence.CrystalCmd.Client.Report(serverUrl, username: "The server username goes here", password: "The server password goes here");
    using (var stream = await rpt.GenerateAsync(reportData, instream, _httpClient))
    {
        stream.CopyTo(outstream);
        return outstream.ToArray();
    }
}

Postman Collection

Majorsilence.CrystalCMD.postman_collection.json

Server requirements

See Crystal Reports, Developer for Visual Studio Downloads

  • Download the Crystal Reports .net runtime from: https://origin.softwaredownloads.sap.com/public/site/index.html
    • CR for Visual Studio SP35 CR Runtime 64-bit
    • CR for Visual Studio SP35 CR Runtime 32-bit
  • Majorsilence.CrystalCmd.NetFrameworkServer
    • net4.8 webapi project
  • Majorsilence.CrystalCmd.NetframeworkConsoleServer
    • an embedio based console app/webserver
    • can be run on Linux using wine

Server

Docker run

docker run -p 44355:44355 -e OVERRIDE_WINEARCH_AS_X64='yes' majorsilence/dotnet_framework_wine_crystalcmd:1.0.25-alpine

Windows Service Run

Use nssm or powershell to register the Majorsilence.CrystalCmd.NetframeworkConsoleServer.exe.

$serviceName = "CrystalCmdService"
$exePath = "C:\Path\To\Majorsilence.CrystalCmd.NetframeworkConsoleServer.exe"
$displayName = "Crystal Command Service"
$description = "A service for Majorsilence Crystal Command"

New-Service -Name $serviceName -BinaryPathName $exePath -DisplayName $displayName -Description $description -StartupType Automatic

# Set the service to restart on failure
sc.exe failure $serviceName reset= 0 actions= restart/60000/restart/60000/restart/60000

# Verify service configuration
Get-Service -Name $serviceName
sc.exe qc $serviceName
sc.exe qfailure $serviceName

tldr; install PostgreSQL on Ubuntu 22.04/24.04 or Fedora Linux.

Ubuntu

Install

Install PostgreSQL and start the command line tool psql.

sudo apt update
sudo apt install postgresql
sudo -u postgres psql

Firewall

If you have a firewall enabled you will need to permit traffic.

sudo ufw allow postgresql

Fedora

Install

sudo dnf install postgresql-server postgresql-contrib
sudo systemctl enable postgresql
sudo postgresql-setup --initdb --unit postgresql
sudo systemctl start postgresql
sudo -u postgres psql

configuration

By default, only connections from the local system are allowed. To enable all other computers to connect to your PostgreSQL server, edit the file /etc/postgresql/*/main/postgresql.conf. Locate the line: #listen_addresses = ‘localhost’ and change it to *:

listen_addresses = '*'

After configuring the password, edit the file /etc/postgresql/*/main/pg_hba.conf to use scram-sha-256 authentication with the postgres user, allowed for all databases, from any network connection

# TYPE  DATABASE USER CIDR-ADDRESS  METHOD
host    all      all  0.0.0.0/0     scram-sha-256

Enable sql account for postgres user.

ALTER USER postgres WITH PASSWORD 'your_new_password';

References


Install

Install microk8s and nginx ingress.

sudo snap install microk8s --classic
sudo microk8s status --wait
sudo microk8s enable ingress

Note that the nginx ingressClassName provided by microk8s is public.

Configure

Increase proxy buffer size, enable header underscores, enable use-forwarded-headers.

microk8s kubectl -n ingress edit configmaps nginx-load-balancer-microk8s-conf

add the following

data:
  use-forwarded-headers: "true"
  enable-underscores-in-headers: "true"
  proxy-buffer-size: "16k"

Rollout the changes

microk8s kubectl -n ingress rollout restart daemonset nginx-ingress-microk8s-controller

Create oci images/containers

Use podman or docker.

examplescript.sh

#!/bin/bash
while true
do
	echo "Press [CTRL+C] to stop.."
	sleep 1
done

Make the script executable.

chmod +x ./examplescript.sh

Dockerfile. The filename must be “Dockerfile” or when calling docker build -f must be used to pass in the filename.

FROM ubuntu:22.04
ADD examplescript.sh /
RUN apt update && apt install bash -y
CMD [ "./examplescript.sh" ]

build the image

sudo docker build -t exampleapp .

Verify the image was built.

sudo docker build -t exampleapp .
sudo docker images
sudo docker run localhost/exampleapp

create pods and deployments

create a pod yaml

Create the yaml for a pod running a nginx container.

kubectl run nginx --image=nginx --dry-run=client -o yaml > example-pod.yaml

create a deployment yaml

Create the yaml for a deployment with a pod running an nginx container.

kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > example-deployment.yaml

create a nodeport service yaml

Use a nodeport service to expose an applications via port. Note: –tcp=:

kubectl create service nodeport ns-service --tcp=80:80 --dry-run=client -o yaml > example-nodeport-service.yaml