diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9cc3824..de2ef05 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: run: mvn -B versions:set --file ./pom.xml -DnewVersion=${GITHUB_REF##*/} - name: Build and Test id: buildAndTest - run: mvn -B clean test + run: mvn -B clean test -DdevCommandFileDir="${{ vars.MSVC_DEV_FILES_DIR }}" - name: Codesign DLL on release if: startsWith(github.ref, 'refs/tags/') uses: skymatic/code-sign-action@v3 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e786bc1..39525fc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -32,6 +32,6 @@ jobs: with: languages: java - name: Build - run: mvn -B compile + run: mvn -B compile -DdevCommandFileDir="${{ vars.MSVC_DEV_FILES_DIR }}" - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 \ No newline at end of file diff --git a/.github/workflows/publish-central.yml b/.github/workflows/publish-central.yml index f445539..c8026ed 100644 --- a/.github/workflows/publish-central.yml +++ b/.github/workflows/publish-central.yml @@ -29,7 +29,7 @@ jobs: - name: Enforce project version ${{ github.event.inputs.tag }} run: mvn versions:set -B -DnewVersion="${{ github.event.inputs.tag }}" - name: Deploy - run: mvn deploy -B -DskipTests -Psign,deploy-central --no-transfer-progress + run: mvn deploy -B -DskipTests -Psign,deploy-central --no-transfer-progress -DdevCommandFileDir="${{ vars.MSVC_DEV_FILES_DIR }}" env: MAVEN_OPTS: > --add-opens=java.base/java.util=ALL-UNNAMED diff --git a/.github/workflows/publish-github.yml b/.github/workflows/publish-github.yml index 95fe4b8..9b46bd6 100644 --- a/.github/workflows/publish-github.yml +++ b/.github/workflows/publish-github.yml @@ -21,7 +21,7 @@ jobs: - name: Enforce project version ${{ github.event.release.tag_name }} run: mvn versions:set -B -DnewVersion="${{ github.event.release.tag_name }}" - name: Deploy - run: mvn deploy -B -DskipTests -Psign,deploy-github --no-transfer-progress + run: mvn deploy -B -DskipTests -Psign,deploy-github --no-transfer-progress -DdevCommandFileDir="${{ vars.MSVC_DEV_FILES_DIR }}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} diff --git a/.gitignore b/.gitignore index f74150f..359ee37 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,73 @@ pom.xml.versionsBackup .idea/compiler.xml .idea/jarRepositories.xml *.iml + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# exclude compile outputs not used by projects +*.exp +*.lib \ No newline at end of file diff --git a/Makefile b/Makefile index 09525fb..7048ed3 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,10 @@ -HEADERS := -I"src/main/headers" -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" +# Note: make apparently thinks, that options specified with "/" are absolute paths and resolves them. see also https://stackoverflow.com/questions/17012419/d9024-make-unrecognized-source-file-type +WIN_SDK_VERSION ?= 10.0.22621.0 +MSVC_VERSION ?= 14.41.34120 +HEADERS := -I"src\main\headers" \ + -I"${JAVA_HOME}\include" \ + -I"${JAVA_HOME}\include\win32" \ + -I"C:\Program Files (x86)\Windows Kits\10\Include\$(WIN_SDK_VERSION)\cppwinrt" SOURCES := $(wildcard src/main/native/*.cpp) ######## @@ -6,4 +12,10 @@ SOURCES := $(wildcard src/main/native/*.cpp) all: install install: - g++ -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at $(HEADERS) -shared -osrc/main/resources/integrations.dll $(SOURCES) -lcrypt32 -lshell32 -lole32 -luuid \ No newline at end of file + cl -EHsc -std:c++17 -LD -W4 -guard:cf \ + -Fe"src/main/resources/integrations.dll" \ + -Fo"target/" \ + $(HEADERS) $(SOURCES) \ + -link -NXCOMPAT -DYNAMICBASE \ + -implib:target/integrations.lib \ + crypt32.lib shell32.lib ole32.lib uuid.lib user32.lib Advapi32.lib \ No newline at end of file diff --git a/README.md b/README.md index 5bd462d..42ce72b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,17 @@ This project uses the following JVM properties: ## Building -This project uses JNI, hence you'll nedd Java as well as GCC build tools: +### Requirements * JDK 22 * Maven -* MinGW GCC compiler (`choco install mingw --version=10.2.0`) -* Make (`choco install make`) \ No newline at end of file +* MSVC 2022 toolset (e.g. by installing Visual Studio 2022, Workset "Desktop development with C++") +* Make (`choco install make`) + +### Build +Open a terminal and run +``` +mvn clean verify +``` + +If building the dll fails with "cl.exe cannot be found", you have to specify the developer command file directory as a property, e.g. `-DdevCommandFileDir=C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\"`. \ No newline at end of file diff --git a/integrations-win.sln b/integrations-win.sln new file mode 100644 index 0000000..2e4e468 --- /dev/null +++ b/integrations-win.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "integrations-win", "integrations-win.vcxproj", "{CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Debug|x64.ActiveCfg = Debug|x64 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Debug|x64.Build.0 = Debug|x64 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Debug|x86.ActiveCfg = Debug|Win32 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Debug|x86.Build.0 = Debug|Win32 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Release|x64.ActiveCfg = Release|x64 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Release|x64.Build.0 = Release|x64 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Release|x86.ActiveCfg = Release|Win32 + {CF96ACE0-9471-4BD6-AD0E-BE32AF14C358}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCEB853F-9857-4F7D-A508-A7390F37BC50} + EndGlobalSection +EndGlobal diff --git a/integrations-win.vcxproj b/integrations-win.vcxproj new file mode 100644 index 0000000..053bbe7 --- /dev/null +++ b/integrations-win.vcxproj @@ -0,0 +1,130 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {cf96ace0-9471-4bd6-ad0e-be32af14c358} + integrationswin + 10.0.22621.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)src\main\headers;$(JAVA_HOME)include;$(JAVA_HOME)include\win32;$(IncludePath) + $(SolutionDir)target\native\$(Platform)\$(Configuration)\ + integrations + + + + Level3 + true + _DEBUG;INTEGRATIONSWIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + + + stdcpp17 + + + Windows + true + false + %(ForceSymbolReferences) + crypt32.lib;shell32.lib;ole32.lib;uuid.lib;user32.lib;windowsapp.lib + + + + + Level3 + true + true + true + NDEBUG;INTEGRATIONSWIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index e6a216d..e522bba 100644 --- a/pom.xml +++ b/pom.xml @@ -295,6 +295,9 @@ !skipNativeCompile + + C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\ + @@ -308,13 +311,14 @@ compile - make + cmd ${project.basedir} ${java.home} - install + /c + "${devCommandFileDir}\vcvars64.bat" && make install diff --git a/src/main/native/org_cryptomator_windows_uiappearnce_WinAppearance_Native.cpp b/src/main/native/org_cryptomator_windows_uiappearnce_WinAppearance_Native.cpp index 9ae99ba..ffaf353 100644 --- a/src/main/native/org_cryptomator_windows_uiappearnce_WinAppearance_Native.cpp +++ b/src/main/native/org_cryptomator_windows_uiappearnce_WinAppearance_Native.cpp @@ -17,10 +17,10 @@ void throwIllegalStateException(JNIEnv *env, const char* message) { JNIEXPORT jint JNICALL Java_org_cryptomator_windows_uiappearance_WinAppearance_00024Native_getCurrentTheme (JNIEnv *env, jobject thisObject){ DWORD data{}; DWORD dataSize = sizeof(data); - LSTATUS status = RegGetValue(HKEY_CURRENT_USER, R"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)", "AppsUseLightTheme", RRF_RT_DWORD, NULL, &data, &dataSize); + LSTATUS status = RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_DWORD, NULL, &data, &dataSize); if(status != ERROR_SUCCESS){ char msg[50]; - sprintf(msg, "Failed to read registry value (status %d)", (int) status); + sprintf_s(msg, 50, "Failed to read registry value (status %d)", (int) status); throwIllegalStateException(env, msg); } return data ? 1 : 0; @@ -28,16 +28,16 @@ JNIEXPORT jint JNICALL Java_org_cryptomator_windows_uiappearance_WinAppearance_0 JNIEXPORT void JNICALL Java_org_cryptomator_windows_uiappearance_WinAppearance_00024Native_waitForNextThemeChange(JNIEnv *env, jobject thisObj){ HKEY key; - LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, R"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)", 0, KEY_READ, &key); + LSTATUS status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &key); if (status != ERROR_SUCCESS) { char msg[50]; - sprintf(msg, "Failed to open registry key (status %d)", (int) status); + sprintf_s(msg, 50,"Failed to open registry key (status %d)", (int) status); throwIllegalStateException(env, msg); } status = RegNotifyChangeKeyValue(key, TRUE, REG_NOTIFY_CHANGE_LAST_SET, NULL, FALSE); if (status != ERROR_SUCCESS) { char msg[50]; - sprintf(msg, "Failed to observe registry key (status %d)", (int) status); + sprintf_s(msg, 50, "Failed to observe registry key (status %d)", (int) status); throwIllegalStateException(env, msg); } RegCloseKey(key);