Use C++20 and CMake presets (#7322)
* Create tasks.json * Delete gui.pro * Swallow any exceptions from stopDesktop * Upgrade to C++20 * Update ChangeLog * Remove old versions of Ubuntu * Ignore VS Code workspace * Restore original CodeQL job name * Add problem matcher and suppress warnings from within old CMake lib * Bump CMake min version to 3.5 * Remove useless cmake_minimum_required * HACK: temp comment out failing code * Bump Qt to 5.12.6 * Delete tasks.json * Create CMakePresets.json * Fixed Qt link error: The input line is too long. * Fixed invalid call to map erase * Fixed incorrect use of RegCreateKeyEx * Add VS Code tasks.json for cmake build * Store `desktop` in char buf before using it * Generate compile_commands.json * Restore indentation * Revert "Restore indentation" This reverts commit d9f495460f337c37e8a01d8853b317e949ea085a. * Restore original indentation (for now) * Create extensions.json
This commit is contained in:
parent
55f68ed3e9
commit
d4133d1110
16 changed files with 102 additions and 233 deletions
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
|
|
@ -12,7 +12,7 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
codeql-analysis:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
|
|
|||
4
.github/workflows/job-test-linux-ubuntu.yml
vendored
4
.github/workflows/job-test-linux-ubuntu.yml
vendored
|
|
@ -24,12 +24,8 @@ jobs:
|
|||
distro:
|
||||
- "22.04"
|
||||
- "20.04"
|
||||
- "18.04"
|
||||
flag:
|
||||
- "-j"
|
||||
include:
|
||||
- distro: "16.04"
|
||||
flag: "-j1"
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
|
|
|
|||
10
.github/workflows/job-test-windows.yml
vendored
10
.github/workflows/job-test-windows.yml
vendored
|
|
@ -18,9 +18,9 @@ jobs:
|
|||
GIT_COMMIT: ${{ github.sha }}
|
||||
BONJOUR_BASE_DIR: ${{ github.workspace }}\deps\bonjour
|
||||
QT_BASE_DIR: ${{ github.workspace }}\deps\Qt
|
||||
QT_VERSION: 5.12.6
|
||||
QT_VERSION: 5.15.2
|
||||
QT_BASE_URL: http://qt.mirror.constant.com/
|
||||
QT_LIB_DIR: ${{ github.workspace }}\deps\Qt\5.12.6
|
||||
QT_LIB_DIR: ${{ github.workspace }}\deps\Qt\5.15.2
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
|
|
@ -39,8 +39,8 @@ jobs:
|
|||
if: steps.cache-qt.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
pip install aqtinstall
|
||||
python -m aqt install --outputdir $env:QT_BASE_DIR --base $env:QT_BASE_URL $env:QT_VERSION windows desktop win64_msvc2017_64
|
||||
cd $env:QT_LIB_DIR\msvc2017_64
|
||||
python -m aqt install --outputdir $env:QT_BASE_DIR --base $env:QT_BASE_URL $env:QT_VERSION windows desktop win64_msvc2019_64
|
||||
cd $env:QT_LIB_DIR\msvc2019_64
|
||||
dir
|
||||
|
||||
- name: Cache Bonjour
|
||||
|
|
@ -66,7 +66,7 @@ jobs:
|
|||
|
||||
- name: Build
|
||||
env:
|
||||
CMAKE_PREFIX_PATH: "${{ env.QT_LIB_DIR }}\\msvc2017_64\\"
|
||||
CMAKE_PREFIX_PATH: "${{ env.QT_LIB_DIR }}\\msvc2019_64\\"
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -32,3 +32,5 @@ flatpak/build
|
|||
flatpak/export
|
||||
flatpak/synergy.desktop
|
||||
flatpak/*.flatpak
|
||||
*.code-workspace
|
||||
*.idx
|
||||
|
|
|
|||
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"ms-vscode.cmake-tools",
|
||||
"twxs.cmake",
|
||||
"llvm-vs-code-extensions.vscode-clangd"
|
||||
]
|
||||
}
|
||||
13
.vscode/tasks.json
vendored
Normal file
13
.vscode/tasks.json
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "build",
|
||||
"command": "build",
|
||||
"targets": ["all"],
|
||||
"preset": "${command:cmake.activeBuildPresetName}",
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -14,9 +14,18 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cmake_minimum_required (VERSION 3.4)
|
||||
cmake_minimum_required (VERSION 3.5)
|
||||
project (synergy-core C CXX)
|
||||
|
||||
# use response files so that ninja can compile on windows,
|
||||
# otherwise you get an error when linking qt:
|
||||
# "The input line is too long."
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@")
|
||||
set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@")
|
||||
set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
if (DEFINED ENV{SYNERGY_NO_LEGACY})
|
||||
option (SYNERGY_BUILD_LEGACY_GUI "Build the legacy GUI" OFF)
|
||||
option (SYNERGY_BUILD_LEGACY_INSTALLER "Build the legacy installer" OFF)
|
||||
|
|
@ -50,7 +59,7 @@ else()
|
|||
option (SYNERGY_BUSINESS "Build Business" OFF)
|
||||
endif()
|
||||
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
set (CMAKE_CXX_EXTENSIONS OFF)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
|
@ -90,8 +99,6 @@ else()
|
|||
set (SYNERGY_ADD_HEADERS TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
set (libs)
|
||||
include_directories (BEFORE SYSTEM ${PROJECT_SOURCE_DIR}/ext/googletest/googletest/include)
|
||||
|
||||
|
|
@ -325,6 +332,7 @@ if (UNIX)
|
|||
endif()
|
||||
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /D _BIND_TO_CURRENT_VCLIBS_VERSION=1")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2 /Ob2")
|
||||
|
||||
|
|
@ -337,6 +345,7 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
|||
/DSYNERGY_VERSION=\"${SYNERGY_VERSION}\"
|
||||
/D_XKEYCHECK_H
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
#
|
||||
|
|
|
|||
32
CMakePresets.json
Normal file
32
CMakePresets.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"version": 2,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "windows",
|
||||
"displayName": "Windows",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||
},
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"toolset": {
|
||||
"value": "host=x64",
|
||||
"strategy": "external"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "windows",
|
||||
"displayName": "Windows",
|
||||
"configurePreset": "windows"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ Enhancements:
|
|||
- #7282 Improve error handling for thread jobs
|
||||
- #7284 Change session ID info log message to DEBUG2
|
||||
|
||||
CI changes:
|
||||
Build/CI:
|
||||
|
||||
- #7283 Update all workflows and fix broken macOS workflows
|
||||
- #7313 Fix CodeQL workflow: Failed to perl 404 Not Found
|
||||
|
|
@ -21,6 +21,7 @@ CI changes:
|
|||
- #7319 Remove workflows for slow self-hosted RPi runners
|
||||
- #7320 Move build_version.py script to scripts dir
|
||||
- #7321 Switch to GitHub hosted Mac M1 runner
|
||||
- #7322 Use C++20 and add VSCode tasks config
|
||||
|
||||
# 1.14.6
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
cmake_minimum_required (VERSION 3.4)
|
||||
|
||||
#
|
||||
# Synergy Version
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
cmake_minimum_required (VERSION 3.4)
|
||||
|
||||
find_package (Qt5 COMPONENTS Core Widgets Network LinguistTools)
|
||||
set (CMAKE_AUTOMOC ON)
|
||||
set (CMAKE_AUTORCC ON)
|
||||
|
|
|
|||
206
src/gui/gui.pro
206
src/gui/gui.pro
|
|
@ -1,206 +0,0 @@
|
|||
QT += widgets \
|
||||
network
|
||||
TEMPLATE = app
|
||||
TARGET = synergy
|
||||
DEFINES += VERSION_STAGE=\\\"$$QMAKE_VERSION_STAGE\\\"
|
||||
DEFINES += VERSION_REVISION=\\\"$$QMAKE_VERSION_REVISION\\\"
|
||||
DEFINES -= UNICODE
|
||||
DEFINES += _MBCS
|
||||
DEPENDPATH += . \
|
||||
res
|
||||
INCLUDEPATH += . \
|
||||
src \
|
||||
../lib/shared/
|
||||
FORMS += src/MainWindowBase.ui \
|
||||
src/AboutDialogBase.ui \
|
||||
src/ServerConfigDialogBase.ui \
|
||||
src/ScreenSettingsDialogBase.ui \
|
||||
src/ActionDialogBase.ui \
|
||||
src/HotkeyDialogBase.ui \
|
||||
src/SettingsDialogBase.ui \
|
||||
src/SetupWizardBase.ui \
|
||||
src/AddClientDialogBase.ui \
|
||||
src/ActivationDialog.ui \
|
||||
src/CancelActivationDialog.ui \
|
||||
src/FailedLoginDialog.ui
|
||||
SOURCES += src/main.cpp \
|
||||
src/MainWindow.cpp \
|
||||
src/AboutDialog.cpp \
|
||||
src/ServerConfig.cpp \
|
||||
src/ServerConfigDialog.cpp \
|
||||
src/ScreenSetupView.cpp \
|
||||
src/Screen.cpp \
|
||||
src/ScreenSetupModel.cpp \
|
||||
src/NewScreenWidget.cpp \
|
||||
src/TrashScreenWidget.cpp \
|
||||
src/ScreenSettingsDialog.cpp \
|
||||
src/BaseConfig.cpp \
|
||||
src/HotkeyDialog.cpp \
|
||||
src/ActionDialog.cpp \
|
||||
src/Hotkey.cpp \
|
||||
src/Action.cpp \
|
||||
src/KeySequence.cpp \
|
||||
src/KeySequenceWidget.cpp \
|
||||
src/SettingsDialog.cpp \
|
||||
src/AppConfig.cpp \
|
||||
src/QSynergyApplication.cpp \
|
||||
src/VersionChecker.cpp \
|
||||
src/SetupWizard.cpp \
|
||||
src/IpcClient.cpp \
|
||||
src/IpcReader.cpp \
|
||||
src/Ipc.cpp \
|
||||
src/SynergyLocale.cpp \
|
||||
src/QUtility.cpp \
|
||||
src/ZeroconfServer.cpp \
|
||||
src/ZeroconfThread.cpp \
|
||||
src/ZeroconfRegister.cpp \
|
||||
src/ZeroconfBrowser.cpp \
|
||||
src/ZeroconfService.cpp \
|
||||
src/DataDownloader.cpp \
|
||||
src/AddClientDialog.cpp \
|
||||
src/CommandProcess.cpp \
|
||||
src/CoreInterface.cpp \
|
||||
src/Fingerprint.cpp \
|
||||
src/SslCertificate.cpp \
|
||||
src/WebClient.cpp \
|
||||
src/ActivationNotifier.cpp \
|
||||
src/ActivationDialog.cpp \
|
||||
src/CancelActivationDialog.cpp \
|
||||
src/FailedLoginDialog.cpp \
|
||||
../lib/shared/SerialKey.cpp \
|
||||
src/LicenseManager.cpp
|
||||
HEADERS += src/MainWindow.h \
|
||||
src/AboutDialog.h \
|
||||
src/ServerConfig.h \
|
||||
src/ServerConfigDialog.h \
|
||||
src/ScreenSetupView.h \
|
||||
src/Screen.h \
|
||||
src/ScreenSetupModel.h \
|
||||
src/NewScreenWidget.h \
|
||||
src/TrashScreenWidget.h \
|
||||
src/ScreenSettingsDialog.h \
|
||||
src/BaseConfig.h \
|
||||
src/HotkeyDialog.h \
|
||||
src/ActionDialog.h \
|
||||
src/Hotkey.h \
|
||||
src/Action.h \
|
||||
src/KeySequence.h \
|
||||
src/KeySequenceWidget.h \
|
||||
src/SettingsDialog.h \
|
||||
src/AppConfig.h \
|
||||
src/QSynergyApplication.h \
|
||||
src/VersionChecker.h \
|
||||
src/SetupWizard.h \
|
||||
src/IpcClient.h \
|
||||
src/IpcReader.h \
|
||||
src/Ipc.h \
|
||||
src/SynergyLocale.h \
|
||||
src/QUtility.h \
|
||||
src/ZeroconfServer.h \
|
||||
src/ZeroconfThread.h \
|
||||
src/ZeroconfRegister.h \
|
||||
src/ZeroconfRecord.h \
|
||||
src/ZeroconfBrowser.h \
|
||||
src/ZeroconfService.h \
|
||||
src/DataDownloader.h \
|
||||
src/AddClientDialog.h \
|
||||
src/CommandProcess.h \
|
||||
src/ProcessorArch.h \
|
||||
src/CoreInterface.h \
|
||||
src/Fingerprint.h \
|
||||
src/SslCertificate.h \
|
||||
src/WebClient.h \
|
||||
src/ActivationNotifier.h \
|
||||
src/ElevateMode.h \
|
||||
src/ActivationDialog.h \
|
||||
src/CancelActivationDialog.h \
|
||||
src/FailedLoginDialog.h \
|
||||
../lib/shared/EditionType.h \
|
||||
../lib/shared/SerialKey.h \
|
||||
src/LicenseManager.h
|
||||
TRANSLATIONS = res/lang/gui_ar-SA.ts \
|
||||
res/lang/gui_bg-BG.ts \
|
||||
res/lang/gui_ca-ES.ts \
|
||||
res/lang/gui_cs-CZ.ts \
|
||||
res/lang/gui_cy-GB.ts \
|
||||
res/lang/gui_da-DK.ts \
|
||||
res/lang/gui_de-DE.ts \
|
||||
res/lang/gui_el-GR.ts \
|
||||
res/lang/gui_es-ES.ts \
|
||||
res/lang/gui_et-EE.ts \
|
||||
res/lang/gui_fi-FI.ts \
|
||||
res/lang/gui_fr-FR.ts \
|
||||
res/lang/gui_gl-ES.ts \
|
||||
res/lang/gui_he-IL.ts \
|
||||
res/lang/gui_hr-HR.ts \
|
||||
res/lang/gui_hu-HU.ts \
|
||||
res/lang/gui_id-ID.ts \
|
||||
res/lang/gui_it-IT.ts \
|
||||
res/lang/gui_ja-JP.ts \
|
||||
res/lang/gui_ko-KR.ts \
|
||||
res/lang/gui_lt-LT.ts \
|
||||
res/lang/gui_lv-LV.ts \
|
||||
res/lang/gui_mr-IN.ts \
|
||||
res/lang/gui_nl-NL.ts \
|
||||
res/lang/gui_no-NO.ts \
|
||||
res/lang/gui_pl-PL.ts \
|
||||
res/lang/gui_pt-BR.ts \
|
||||
res/lang/gui_pt-PT.ts \
|
||||
res/lang/gui_ro-RO.ts \
|
||||
res/lang/gui_ru-RU.ts \
|
||||
res/lang/gui_sk-SK.ts \
|
||||
res/lang/gui_sl-SI.ts \
|
||||
res/lang/gui_sq-AL.ts \
|
||||
res/lang/gui_sr-SP.ts \
|
||||
res/lang/gui_sv-SE.ts \
|
||||
res/lang/gui_th-TH.ts \
|
||||
res/lang/gui_tr-TR.ts \
|
||||
res/lang/gui_uk-UA.ts \
|
||||
res/lang/gui_ur-IN.ts \
|
||||
res/lang/gui_vi-VN.ts \
|
||||
res/lang/gui_zh-CN.ts \
|
||||
res/lang/gui_zh-TW.ts
|
||||
RESOURCES += res/Synergy.qrc
|
||||
RC_FILE = res/win/Synergy.rc
|
||||
macx {
|
||||
QMAKE_INFO_PLIST = res/mac/Info.plist
|
||||
TARGET = Synergy
|
||||
QSYNERGY_ICON.files = res/mac/Synergy.icns
|
||||
QSYNERGY_ICON.path = Contents/Resources
|
||||
QMAKE_BUNDLE_DATA += QSYNERGY_ICON
|
||||
LIBS += $$MACX_LIBS
|
||||
HEADERS += src/OSXHelpers.h
|
||||
SOURCES += src/OSXHelpers.mm
|
||||
}
|
||||
unix:!macx:LIBS += -ldns_sd
|
||||
debug {
|
||||
OBJECTS_DIR = tmp/debug
|
||||
MOC_DIR = tmp/debug
|
||||
RCC_DIR = tmp/debug
|
||||
}
|
||||
release {
|
||||
OBJECTS_DIR = tmp/release
|
||||
MOC_DIR = tmp/release
|
||||
RCC_DIR = tmp/release
|
||||
}
|
||||
win32-msvc2015 {
|
||||
LIBS += -lAdvapi32
|
||||
QMAKE_LFLAGS += /NODEFAULTLIB:LIBCMT
|
||||
}
|
||||
win32-msvc* {
|
||||
contains(QMAKE_HOST.arch, x86):{
|
||||
QMAKE_LFLAGS *= /MACHINE:X86
|
||||
LIBS += -L"$$(BONJOUR_SDK_HOME)/Lib/Win32" -ldnssd
|
||||
}
|
||||
|
||||
contains(QMAKE_HOST.arch, x86_64):{
|
||||
QMAKE_LFLAGS *= /MACHINE:X64
|
||||
LIBS += -L"$$(BONJOUR_SDK_HOME)/Lib/x64" -ldnssd
|
||||
}
|
||||
}
|
||||
win32 {
|
||||
Debug:DESTDIR = ../../bin/Debug
|
||||
Release:DESTDIR = ../../bin/Release
|
||||
INCLUDEPATH += "$$(BONJOUR_SDK_HOME)/Include"
|
||||
}
|
||||
else:DESTDIR = ../../bin
|
||||
|
|
@ -213,8 +213,14 @@ MainWindow::~MainWindow()
|
|||
{
|
||||
if (appConfig().processMode() == Desktop) {
|
||||
m_ExpectedRunningState = kStopped;
|
||||
try {
|
||||
stopDesktop();
|
||||
}
|
||||
catch (...) {
|
||||
// do not throw, since throwing from a dtor can result in unreliable behaviour.
|
||||
qCritical() << "error stopping desktop in main window destructor";
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SYNERGY_ENTERPRISE) && defined(SYNERGY_AUTOCONFIG)
|
||||
delete m_pZeroconf;
|
||||
|
|
|
|||
|
|
@ -138,11 +138,11 @@ ArchMiscWindows::openKey(HKEY key, const TCHAR* keyName, bool create)
|
|||
|
||||
// open next key
|
||||
HKEY newKey;
|
||||
LONG result = RegOpenKeyEx(key, keyName, 0,
|
||||
LSTATUS result = RegOpenKeyEx(key, keyName, 0,
|
||||
KEY_WRITE | KEY_QUERY_VALUE, &newKey);
|
||||
if (result != ERROR_SUCCESS && create) {
|
||||
DWORD disp;
|
||||
result = RegCreateKeyEx(key, keyName, 0, TEXT(""),
|
||||
result = RegCreateKeyEx(key, keyName, 0, NULL,
|
||||
0, KEY_WRITE | KEY_QUERY_VALUE,
|
||||
NULL, &newKey, &disp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,8 +336,18 @@ ArchTaskBarWindows::processDialogs(MSG* msg)
|
|||
|
||||
ARCH->lockMutex(m_mutex);
|
||||
|
||||
// remove removed dialogs
|
||||
m_dialogs.erase(false);
|
||||
// there was previously some code here, with the comment "remove removed dialogs":
|
||||
// m_dialogs.erase(false);
|
||||
//
|
||||
// it's not entirely clear what this code was doing, but it was probably trying to
|
||||
// erase dialogs that had been removed (i.e. the map value was `false`).
|
||||
for (auto it = m_dialogs.begin(); it != m_dialogs.end(); ) {
|
||||
if (it->second == false) {
|
||||
it = m_dialogs.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// merge added dialogs into the dialog list
|
||||
for (Dialogs::const_iterator index = m_addedDialogs.begin();
|
||||
|
|
|
|||
|
|
@ -398,9 +398,12 @@ MSWindowsWatchdog::startProcess()
|
|||
void
|
||||
MSWindowsWatchdog::setStartupInfo(STARTUPINFO& si)
|
||||
{
|
||||
// TODO: maybe this should be \winlogon if we have logonui.exe?
|
||||
char desktop[] = "winsta0\\Default";
|
||||
|
||||
ZeroMemory(&si, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.lpDesktop = "winsta0\\Default"; // TODO: maybe this should be \winlogon if we have logonui.exe?
|
||||
si.lpDesktop = desktop;
|
||||
si.hStdError = m_stdOutWrite;
|
||||
si.hStdOutput = m_stdOutWrite;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
|
|
|||
Loading…
Reference in a new issue