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")