I'm using a launcher to start a jar in c++ that I took from here: https://github.com/foolo/windows-jre-laucher
My folders and files are like this:
.\launcher.exe
.\lib\MyApp-1.6.0-jar-with-dependencies.jar
.\lib\MyApp-1.6.1-jar-with-dependencies.jar
It works great but I'd like to change so that it checks the "lib" folder, and for every file that matches the regex ".*-.\..\..-.*jar" (or any other way to match my jars) then compares the versions of each and deletes all the older ones (there should only be one old one).
Here is the current launcher.cpp code:
#define JAVAPATH L"jre\\bin\\java.exe"
#define ARGS L"--class-path lib/*;* app.Launcher"
#include <windows.h>
#include <stdio.h>
#include <shlwapi.h>
#define BUFSIZE 512
wchar_t buf[BUFSIZE];
void cdToApplication() {
wchar_t path[MAX_PATH];
int len = GetModuleFileNameW(NULL, path, MAX_PATH);
if (len > 0 && len < MAX_PATH) {
path[len-1] = 0;
if (PathRemoveFileSpecW(path) != 0) {
SetCurrentDirectoryW(path);
}
}
}
int main() {
cdToApplication();
STARTUPINFOW si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPCWSTR cmd = JAVAPATH;
WCHAR args[] = JAVAPATH L" " ARGS;
if (CreateProcessW(cmd, args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) == 0) {
swprintf_s( buf, BUFSIZE, L"Could not run %s\nerror code: %lu\ncommand line: %s", cmd, GetLastError(), args );
MessageBoxExW(NULL, buf, L"Message", MB_OK | MB_ICONERROR, 0);
return 0;
}
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD exitCode = 0;
if (GetExitCodeProcess(pi.hProcess, &exitCode) != 0) {
if (exitCode != 0) {
swprintf_s( buf, BUFSIZE, L"%s\nfailed with exit code %lu\ncommand line: %s", cmd, exitCode, args );
MessageBoxExW(NULL, buf, L"Message", MB_OK | MB_ICONERROR, 0);
}
}
else {
swprintf_s( buf, BUFSIZE, L"%s\nterminated with unknown exit code\ncommand line: %s", cmd, args );
MessageBoxExW(NULL, buf, L"Message", MB_OK | MB_ICONERROR, 0);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
I did try some code with std::filesystem but it didn't compile, I'm using MingW64 with g++ 10.2.0. I tried adding the code from the 2017 solution here : How can I get the list of files in a directory using C or C++?
Here is the code modified to try and use std::filesystem
#define JAVAPATH L"jre\\bin\\java.exe"
#define ARGS L"--class-path lib/*;* app.Launcher"
#include <windows.h>
#include <stdio.h>
#include <shlwapi.h>
#include <string>
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#define BUFSIZE 512
wchar_t buf[BUFSIZE];
void cdToApplication() {
wchar_t path[MAX_PATH];
int len = GetModuleFileNameW(NULL, path, MAX_PATH);
if (len > 0 && len < MAX_PATH) {
path[len-1] = 0;
if (PathRemoveFileSpecW(path) != 0) {
SetCurrentDirectoryW(path);
}
}
}
int main() {
cdToApplication();
std::string path = "/lib";
for (const auto & entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPCWSTR cmd = JAVAPATH;
WCHAR args[] = JAVAPATH L" " ARGS;
if (CreateProcessW(cmd, args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) == 0) {
swprintf_s( buf, BUFSIZE, L"Could not run %s\nerror code: %lu\ncommand line: %s", cmd, GetLastError(), args );
MessageBoxExW(NULL, buf, L"Message", MB_OK | MB_ICONERROR, 0);
return 0;
}
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD exitCode = 0;
if (GetExitCodeProcess(pi.hProcess, &exitCode) != 0) {
if (exitCode != 0) {
swprintf_s( buf, BUFSIZE, L"%s\nfailed with exit code %lu\ncommand line: %s", cmd, exitCode, args );
MessageBoxExW(NULL, buf, L"Message", MB_OK | MB_ICONERROR, 0);
}
}
else {
swprintf_s( buf, BUFSIZE, L"%s\nterminated with unknown exit code\ncommand line: %s", cmd, args );
MessageBoxExW(NULL, buf, L"Message", MB_OK | MB_ICONERROR, 0);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
Here is the error when just using std::filesystem:
$ g++ -o launcher.o -c launcher.cpp
launcher.cpp:11:21: error: 'filesystem' is not a namespace-name
11 | namespace fs = std::filesystem;
| ^~~~~~~~~~
launcher.cpp: In function 'int main()':
launcher.cpp:30:31: error: 'fs' has not been declared
30 | for (const auto & entry : fs::directory_iterator(path))
| ^~
But when using std::experimental::filesystem it does work for the first step: g++ -o launcher.o -c launcher.cpp but it crashes at the second step:
$ g++ -o launcher.exe -static -s -mwindows launcher.o resources.res -lshlwapi
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.text+0x1be): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() const'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.text+0x1fe): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.text$_ZNSt12experimental10filesystem2v17__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code[_ZNSt12experimental10filesystem2v17__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code]+0x93): undefined reference to `std::experimental::filesystem::v1::__cxx11::filesystem_error::_M_gen_what()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.text$_ZNSt12experimental10filesystem2v17__cxx1118directory_iteratorC1ERKNS2_4pathE[_ZNSt12experimental10filesystem2v17__cxx1118directory_iteratorC1ERKNS2_4pathE]+0x28): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path const&, std::experimental::filesystem::v1::directory_options, std::error_code*)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.text$_ZNSt12experimental10filesystem2v17__cxx114pathC1INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT_[_ZNSt12experimental10filesystem2v17__cxx114pathC1INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT_]+0x60): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.rdata$.refptr._ZNSt12experimental10filesystem2v17__cxx1116filesystem_errorD1Ev[.refptr._ZNSt12experimental10filesystem2v17__cxx1116filesystem_errorD1Ev]+0x0): undefined reference to `std::experimental::filesystem::v1::__cxx11::filesystem_error::~filesystem_error()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: launcher.o:launcher.cpp:(.rdata$.refptr._ZTVNSt12experimental10filesystem2v17__cxx1116filesystem_errorE[.refptr._ZTVNSt12experimental10filesystem2v17__cxx1116filesystem_errorE]+0x0): undefined reference to `vtable for std::experimental::filesystem::v1::__cxx11::filesystem_error'
collect2.exe: error: ld returned 1 exit status