This repository provides a Docker image sctg/github-runner-vs2010:2.322.0 for running a self-hosted GitHub runner with Visual Studio 2010 and Windows SDK 7.1a. The main purpose is to enable building Windows XP-compatible applications, as GitHub's standard runners no longer support Visual Studio 2010 and Microsoft has ended Windows XP support.
- Docker installed on your host machine
- A GitHub account with appropriate permissions
- A Personal Access Token (PAT) from GitHub
- Windows Server 2019 (for running Windows containers)
Before running the Docker container, you need to configure your GitHub repository to accept self-hosted runners:
- Go to your GitHub repository settings
- Navigate to "Settings" → "Actions" → "Runners"
- Click on "New self-hosted runner"
- Note down the repository URL and token (you'll need these later)
Important security considerations:
- Self-hosted runners should only be used in private repositories by default
- If using in public repositories, enable the "Require approval for all outside collaborators" setting
- Set up runner groups to control access to runners
- Configure allowed actions and workflows in repository settings
Runner labels:
- Add relevant labels to your runner (e.g., 'windows-2019', 'vs2010')
- These labels are used in workflow files to target specific runners
- Install Windows Server 2019 with Desktop Experience
- Enable Containers and Hyper-V features:
Install-WindowsFeature Containers
Install-WindowsFeature Hyper-V
Restart-Computer-Force- Install Docker:
# Install DockerInvoke-WebRequest-UseBasicParsing "https://raw.githubusercontent.com/microsoft/Windows-Containers/master/helpful_tools/Install-DockerCE/install-docker-ce.ps1"-OutFile install-docker-ce.ps1
.\install-docker-ce.ps1
# Start Docker serviceStart-Service docker
# Switch to Windows containers&$Env:ProgramFiles\Docker\Docker\DockerCli.exe-SwitchWindowsEngine
# Test Docker installation
docker version- Configure Docker for Windows containers:
# Set Docker to use Windows containers by default
[Environment]::SetEnvironmentVariable("DOCKER_DEFAULT_PLATFORM","windows","Machine")When running Windows containers, ensure you use the correct isolation mode:
&$Env:ProgramFiles\Docker\Docker\DockerCli.exe-SwitchWindowsEngine
docker run --isolation=hyperv -it -e GH_TOKEN='your_github_token'-e GH_OWNER='your_github_owner'-e GH_REPOSITORY='your_github_repo' sctg/github-runner-vs2010:2.322.0# or for organizations, you may need to specify the `GH_ORG` as `your_github_org`.
docker run --isolation=hyperv -it -e GH_TOKEN='your_github_token'-e GH_ORG='your_github_org' sctg/github-runner-vs2010:2.322.0To build the Docker image, run the following command:
&$Env:ProgramFiles\Docker\Docker\DockerCli.exe -SwitchWindowsEngine
docker build . --tag sctg/github-runner-vs2010:2.322.0 --tag sctg/github-runner-vs2010:latest --pushTo run the Docker container, you need to provide the following environment variables:
GH_TOKEN: Your GitHub Personal Access Token with the minimum required scopes:repo,read:org.GH_OWNER: The owner of the repository (user or organization).- or
GH_ORG: The organization of the repository. GH_REPOSITORY: The name of the repository.
Run the container with the following command:
docker run --isolation=hyperv -it -e GH_TOKEN='your_github_token' -e GH_OWNER='your_github_owner' -e GH_REPOSITORY='your_github_repo' sctg/github-runner-vs2010:2.322.0To use this runner in your GitHub workflows, you need to specify the runs-on field with your self-hosted runner label.
Without modification the labels self-hosted, windows, vs2010 and self-hosted-vs2010 are defined.
Here's a sample real workflow that builds a Windows XP-compatible application using the sample build.ps1 script:
name: Build Windows XP Appon:
workflow_dispatch:
release:
types: [published]permissions:
contents: writepages: writeid-token: writepackages: writeattestations: writejobs:
build:
runs-on: self-hosted-vs2010 # Use https://github.com/sctg-development/github-runner-vs2010steps:
- uses: actions/checkout@v4with:
fetch-depth: 1# this is a real example of a restore script for a Qt project
- name: Restore Qt487shell: bashrun: | _PWD=$(pwd) echo "Running in $_PWD" ./big-restore.sh cd /c/ 7z x -y "$_PWD/Qt487static.zip" - name: Build Releasecontinue-on-error: trueshell: powershellrun: | ./build.ps1 -Configurations "Release" -workspace $PWD -dism 0# - name: Setup MSBuild# shell: cmd# run: |# call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
- name: Build Solutionshell: cmd# This is or real build# build.ps1 is provided as an example in the repo
- name: Build Release Verbosecontinue-on-error: trueshell: powershellrun: | ./build.ps1 -Configurations "Release Verbose" -workspace $PWD -dism 0 - name: Upload Release Artifactsuses: actions/upload-artifact@v4with:
name: windows-xp-build Releasepath: "./Release/Application/**"
- name: Upload Realease Verbose Artifactsuses: actions/upload-artifact@v4with:
name: windows-xp-build Release Verbosepath: "./Release Verbose//Application/**"
- name: Upload full builduses: actions/upload-artifact@v4with:
name: windows-xp-buildpath: "./"
- name: Create zip file with built filesshell: bashrun: | 7z a -tzip myapp-Release.zip "./Release/Application/**" 7z a -tzip myapp-Release-Verbose.zip "./Release Verbose/Application/**" - name: Create Release with gh and extract version from built fileenv:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}shell: powershellrun: | $version = Get-Item -Path "./Release/Application/myapp.exe" | Select-Object -ExpandProperty VersionInfo $revision = $version.FileVersionRaw.Revision $major = $version.FileVersionRaw.Major $minor = $version.FileVersionRaw.Minor $build = $version.FileVersionRaw.Build $TAG_NAME = "v$major.$minor.$build.$revision" Write-Output $TAG_NAMEtry {gh release create $TAG_NAME -t "$TAG_NAME" -n "$TAG_NAME"} catch {Write-Output "Release may already exist, continuing..."}gh release upload $TAG_NAME novasulf-ii-Release.zip --clobbergh release upload $TAG_NAME novasulf-ii-Release-Verbose.zip --clobberNote: Replace YourSolution.sln and paths with your actual project files and build output locations.
The Dockerfile sets up the environment with:
- Visual Studio 2010
- .NET Framework 4.8
- Windows SDK 7.0
- Windows SDK 7.1a
- GitHub runner (version 2.322.0 by default)
The start.ps1 script handles the container initialization by:
- Authenticating with GitHub using the provided
GH_TOKEN - Obtaining a registration token for the GitHub runner
- Registering the runner with the specified repository
- Starting the runner process
Common issues and solutions:
Runner Registration Fails:
- Verify your PAT has the correct permissions
- Ensure the repository exists and you have access to it
Build Failures:
- Check that your solution targets Visual Studio 2010 toolset
- Verify Windows SDK 7.1a paths are correct
Docker Container Issues:
- Ensure you're using process isolation mode on Windows Server 2019
- Verify Docker is configured for Windows containers
- Check container logs for startup errors
When the Docker container is stopped, the runner registration is automatically removed from GitHub. However, if you encounter stale runners, you can use the provided Cleanup-Runners.ps1 script:
.\Cleanup-Runners.ps1 -Owner your_github_owner -Repository your_github_repo -Token your_github_tokenContributions are welcome! Please feel free to submit a Pull Request.
- Ronan L
- Email: ronan@sctg-development.eu.org
- GitHub: sctg-development/github-runner-vs2010
This project is licensed under the GNU Affero General Public License version 3.