diff --git a/.github/maven-settings.xml b/.github/maven-settings.xml
new file mode 100644
index 0000000..4daffea
--- /dev/null
+++ b/.github/maven-settings.xml
@@ -0,0 +1,11 @@
+
+
+
+ nexus
+ ${env.NEXUS_USERNAME}
+ ${env.NEXUS_PASSWORD}
+
+
+
\ No newline at end of file
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
new file mode 100644
index 0000000..4443ec6
--- /dev/null
+++ b/.github/workflows/pull_request.yml
@@ -0,0 +1,25 @@
+name: Java CI
+
+on:
+ pull_request:
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up JDK 19
+ id: setup-java
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '19'
+
+ - name: Export JAVA19_HOME for build
+ run: |
+ echo "JAVA19_HOME=${{ steps.setup-java.outputs.java-home }}" >> $GITHUB_ENV
+
+ - name: Build and test
+ run: mvn -B verify
diff --git a/.github/workflows/release-on-version-change.yml b/.github/workflows/release-on-version-change.yml
new file mode 100644
index 0000000..f42ca82
--- /dev/null
+++ b/.github/workflows/release-on-version-change.yml
@@ -0,0 +1,96 @@
+name: Detect version change and create tag
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ detect-version:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+
+ outputs:
+ release: ${{ steps.decide.outputs.release }}
+
+
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # needed so we can create tags
+
+
+ - name: Install libxml2-utils
+ run: sudo apt-get update && sudo apt-get install -y libxml2-utils
+
+ - name: Extract version from pom.xml
+ id: version
+ run: |
+ VERSION=$(xmllint --xpath "string(/*[local-name()='project']/*[local-name()='version'])" pom.xml)
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+
+ - name: Set up JDK 19
+ id: setup-java
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '19'
+
+ - name: Export JAVA19_HOME for maven-antrun
+ run: |
+ echo "JAVA19_HOME=${{ steps.setup-java.outputs.java-home }}" >> $GITHUB_ENV
+
+ - name: Build package
+ run: |
+ mvn -B -DskipTests package
+
+ - name: Get previous version from last tag (if any)
+ id: prev
+ run: |
+ LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
+ echo "lasttag=$LAST_TAG" >> $GITHUB_OUTPUT
+
+ - name: Determine whether to release
+ id: decide
+ run: |
+ CUR="${{ steps.version.outputs.version }}"
+ LAST="${{ steps.prev.outputs.lasttag }}"
+ LAST="${LAST#v}" # strip leading v if present
+
+ if [ "$CUR" = "$LAST" ]; then
+ echo "release=false" >> $GITHUB_OUTPUT
+ else
+ echo "release=true" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Create tag and GitHub Release (only if version changed)
+ id: create_release
+ if: steps.decide.outputs.release == 'true'
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: v${{ steps.version.outputs.version }}
+ name: Release v${{ steps.version.outputs.version }}
+ generate_release_notes: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Upload fat JAR to Release
+ if: steps.decide.outputs.release == 'true'
+ uses: actions/upload-release-asset@v1
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: target/win-command-executor/bin/win-command-executor.jar
+ asset_name: win-command-executor-${{ steps.version.outputs.version }}.jar
+ asset_content_type: application/java-archive
+
+ - name: Upload root JAR to Release
+ if: steps.decide.outputs.release == 'true'
+ uses: actions/upload-release-asset@v1
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: target/win-command-executor-${{ steps.version.outputs.version }}.jar
+ asset_name: win-command-executor-${{ steps.version.outputs.version }}-raw.jar
+ asset_content_type: application/java-archive
diff --git a/.gitignore b/.gitignore
index c06f585..3b8b671 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,10 @@ target\
.springBeans
.sts4-cache
+
+### VS CODE ###
+.vscode/
+
### IntelliJ IDEA ###
.idea
*.iws
diff --git a/README.md b/README.md
index ad515e4..393afb6 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This application will serve as a tool to help you execute sequential commmands i
## 1) What is this repository for?
### 1.1) Quick summary
-Version: `0.1-SNAPSHOT`
+Version: `1.0.1`
#### 1.1.1) How to use
You can call the jar and send arguments with the following format:
diff --git a/pom.xml b/pom.xml
index fb593f7..4b53265 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
org.white_sdev.utils
win-command-executor
- 1.0.0
+ 1.0.1
${project.groupId}:${project.artifactId}
Command executor for windows
diff --git a/src/main/java/org/white_sdev/utils/WinCommandExecutor.java b/src/main/java/org/white_sdev/utils/WinCommandExecutor.java
index 8c1f331..02f4208 100644
--- a/src/main/java/org/white_sdev/utils/WinCommandExecutor.java
+++ b/src/main/java/org/white_sdev/utils/WinCommandExecutor.java
@@ -90,11 +90,42 @@ static boolean sendTextToSpeechMessage(String textToSpeechMessage) {
String logID = "::sendTextToSpeechMessage([textToSpeechMessage]): ";
logID = "";
log.trace("{}Start - textToSpeechMessage:{}", logID, textToSpeechMessage);
- String textToSpeechCommand = String.format("mshta vbscript:Execute(" +
- "\"CreateObject(\"\"SAPI.SpVoice\"\").Speak(\"\"%s\"\")(window.close)\")", textToSpeechMessage);
- var result = executeCommandInConsole(textToSpeechCommand);
- log.trace("{}Finish - result:{}", logID, result);
- return result;
+
+ if (textToSpeechMessage == null || textToSpeechMessage.isBlank()) {
+ log.warn("Empty TTS message");
+ return false;
+ }
+
+ // Prefer PowerShell System.Speech (more robust on many Windows setups)
+ try {
+ // Escape single quotes for PowerShell single-quoted string by doubling them
+ String safeForPs = textToSpeechMessage.replace("'", "''");
+ String psCommand = String.format("powershell.exe -NoProfile -Command \"Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak('%s')\"", safeForPs);
+ boolean psResult = executeCommandInConsole(psCommand);
+ log.trace("PowerShell TTS result: {}", psResult);
+ if (psResult) return true;
+ log.warn("PowerShell TTS returned false, attempting mshta fallback");
+ } catch (Exception e) {
+ log.warn("PowerShell TTS attempt threw an exception", e);
+ }
+
+ // Fallback: create a temporary .vbs file and run it with cscript (more robust than mshta)
+ try {
+ String safeForVbs = textToSpeechMessage.replace("\"", "\"\"");
+ String vbsContent = "CreateObject(\"SAPI.SpVoice\").Speak \"" + safeForVbs + "\"";
+ java.nio.file.Path temp = java.nio.file.Files.createTempFile("tts", ".vbs");
+ java.nio.file.Files.writeString(temp, vbsContent);
+ String cscriptCmd = String.format("cscript //NoLogo %s", temp.toAbsolutePath().toString());
+ boolean vbsResult = executeCommandInConsole(cscriptCmd);
+ try {
+ java.nio.file.Files.deleteIfExists(temp);
+ } catch (Exception ignore) {}
+ log.trace("vbs TTS result: {}", vbsResult);
+ return vbsResult;
+ } catch (Exception e) {
+ log.error("VBS TTS attempt failed", e);
+ return false;
+ }
}
@SuppressWarnings("all")