Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71fc2d43b7 | ||
|
|
56c2ba79fc | ||
|
|
f3d1abf153 | ||
|
|
d8c2c9eb69 | ||
|
|
4028b6cae0 | ||
|
|
860c495002 | ||
|
|
b71e7e3674 | ||
|
|
6f75d2b3e9 | ||
|
|
3bb62c7089 | ||
|
|
bc7e470429 | ||
|
|
92cb91db1b | ||
|
|
2716832118 | ||
|
|
b81f4dd5e3 | ||
|
|
e09bbea607 | ||
|
|
430f154584 | ||
|
|
58b5c72ead | ||
|
|
1a1c5866e0 | ||
|
|
a05668dffc | ||
|
|
551bb174b0 | ||
|
|
afa868fd7b | ||
|
|
619f3830af | ||
|
|
174fc35707 | ||
|
|
292186be44 | ||
|
|
2c0e3b8e0c | ||
|
|
ee4a2d0fe9 | ||
|
|
6a011ed295 |
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*.{c,h,rc}]
|
||||
indent_style = tab
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
/mingw32.exe
|
||||
/mingw32.res
|
||||
/mingw64.exe
|
||||
/mingw64.res
|
||||
/msys2.exe
|
||||
/msys2.res
|
||||
/*.exe
|
||||
/*.res
|
||||
/*.ini
|
||||
/*.pkg.tar.xz
|
||||
/*.pkg.tar.xz.sig
|
||||
/pkg/
|
||||
/src/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
Copyright (c) 2015 David Macek
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
30
Makefile
30
Makefile
@@ -1,19 +1,29 @@
|
||||
all: msys2.exe mingw32.exe mingw64.exe
|
||||
PREFIX=
|
||||
|
||||
all: msys2.exe msys2.ini mingw32.exe mingw32.ini mingw64.exe mingw64.ini
|
||||
|
||||
.PHONY: all
|
||||
|
||||
msys2.ini: launcher.ini
|
||||
cp -f $^ $@
|
||||
echo MSYSTEM=MSYS>> $@
|
||||
msys2.res: launcher.rc msys2.ico
|
||||
windres -O COFF -o $@ $< -DMSYSTEM=MSYS -DICONFILE=msys2.ico
|
||||
$(PREFIX)windres -O COFF -o $@ $< -DMSYSTEM=MSYS -DICONFILE=msys2.ico
|
||||
msys2.exe: launcher.c msys2.res
|
||||
gcc -Wall -Wextra -static -mwindows -o $@ $^ -luuid -lshlwapi -lpsapi -DMSYSTEM=MSYS
|
||||
strip $@
|
||||
$(PREFIX)gcc -std=c11 -Wall -Wextra -Werror -static -municode -mwindows -o $@ $^
|
||||
|
||||
mingw32.ini: launcher.ini
|
||||
cp -f $^ $@
|
||||
echo MSYSTEM=MINGW32>> $@
|
||||
mingw32.res: launcher.rc mingw32.ico
|
||||
windres -O COFF -o $@ $< -DMSYSTEM=MINGW32 -DICONFILE=mingw32.ico
|
||||
$(PREFIX)windres -O COFF -o $@ $< -DMSYSTEM=MINGW32 -DICONFILE=mingw32.ico
|
||||
mingw32.exe: launcher.c mingw32.res
|
||||
gcc -Wall -Wextra -static -mwindows -o $@ $^ -luuid -lshlwapi -lpsapi -DMSYSTEM=MINGW32
|
||||
strip $@
|
||||
$(PREFIX)gcc -std=c11 -Wall -Wextra -Werror -static -municode -mwindows -o $@ $^
|
||||
|
||||
mingw64.ini: launcher.ini
|
||||
cp -f $^ $@
|
||||
echo MSYSTEM=MINGW64>> $@
|
||||
mingw64.res: launcher.rc mingw64.ico
|
||||
windres -O COFF -o $@ $< -DMSYSTEM=MINGW64 -DICONFILE=mingw64.ico
|
||||
$(PREFIX)windres -O COFF -o $@ $< -DMSYSTEM=MINGW64 -DICONFILE=mingw64.ico
|
||||
mingw64.exe: launcher.c mingw64.res
|
||||
gcc -Wall -Wextra -static -mwindows -o $@ $^ -luuid -lshlwapi -lpsapi -DMSYSTEM=MINGW64
|
||||
strip $@
|
||||
$(PREFIX)gcc -std=c11 -Wall -Wextra -Werror -static -municode -mwindows -o $@ $^
|
||||
|
||||
36
PKGBUILD
Normal file
36
PKGBUILD
Normal file
@@ -0,0 +1,36 @@
|
||||
_realname="msys2-launcher"
|
||||
pkgname=("${_realname}-git")
|
||||
pkgver=1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Helper for launching MSYS2 shells"
|
||||
arch=('x86_64' 'i686')
|
||||
license=('MIT')
|
||||
backup=({mingw32,mingw64,msys2}.ini)
|
||||
provides=("${_realname}")
|
||||
conflicts=("${_realname}")
|
||||
depends=("mintty>=2.2.1")
|
||||
makedepends=('mingw-w64-cross-gcc')
|
||||
source=(launcher.{c,ini,rc} {macros,version}.h Makefile {mingw32,mingw64,msys2}.ico)
|
||||
sha512sums=('eac22e62609e06a49931f70b12abaf0f1a412a98bcf349a2b6a0738b511d05ed7ce7731d2e30f9510926c3175d3521d0164e25cd70e9b18ba33aeb887deef11e'
|
||||
'5ed8a2e9997d9d2c1e17940292d68542f897e2716b274741d8a3ba7c8f46235c175b7e0a1252a879ba3c79b571504d25de2a8d6b004aedd117d263195bc2b185'
|
||||
'cf257f1f5b7fc69a32c63fe5bf5299db078621850b1e12358654d71da7777a94a0668d657c1834be308db099cad9d48a42fa7877ad58dfdbd576248150913a12'
|
||||
'6019ca0d67375c1261dda0d54d45fc411b02244c51b71d5c57d2613e9edfb4e8f9000754e5c7d632ed0101005c01cd0a98c3961d5b5f51c94d83eceba4296d35'
|
||||
'2e2669db2e8ef54ff6859f4e9a2657f867aef89094f29386da6df6a39931b55927bd16f92a5058fb4aecc5705a2bf3a867172740bc53bca560b98820790ad3c9'
|
||||
'270db9d92b944754cc71523053532473d8a477241725e7aded02dc34d35895a33cf135be7a87692c0f9d2204731e345b8ae82d33f15a1a197e73357552c564e0'
|
||||
'27b9591fa286a15b0eb76a381191f025184d545359285215b9958632a5bce99484de0130296ff4b285e38cec9d88299c09b2ce1fe4b4957b4ef295d31a620817'
|
||||
'b1ecd3def00a023a9e88806ff9bbb1bbd73086fbf7554799eb5fe8adb16bf96ed1a7da375bb2b9f9268fcf08e25dab4414bb4888e1ee6eff4587ee0973374f6f'
|
||||
'7f369b102391eba9ab56e1fb2157f820ecce41434b7232137da32b924b2d53840731e18ef80916703effc6770e862d1fee2986e66c1d03a8c8bb3feef4f08d58')
|
||||
|
||||
pkgver() {
|
||||
local _major=$(cat version.h | grep -F 'VER_MAJOR' | head -1 | sed -e 's/.* //')
|
||||
local _minor=$(cat version.h | grep -F 'VER_MINOR' | head -1 | sed -e 's/.* //')
|
||||
printf "%s.%s.%s.%s" "${_major}" "${_minor}" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
build() {
|
||||
make PREFIX=/opt/bin/${CARCH}-w64-mingw32-
|
||||
}
|
||||
|
||||
package() {
|
||||
cp {mingw32,mingw64,msys2}.{exe,ini} "${pkgdir}"
|
||||
}
|
||||
16
README.md
16
README.md
@@ -6,4 +6,18 @@ A helper for launching MSYS2 shells. Features blink-less launching and correct t
|
||||
Installation
|
||||
------------
|
||||
|
||||
Just `make` and put the executables inside your MSYS2 root.
|
||||
Just `make` and put the .exe and .ini files inside your MSYS2 root. Needs mintty v2.1.6 or newer.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
All three default launchers are the same (except for embedded icons and descriptions) and are configured by corresponding .ini files. The .ini file has to be in the same directory as the .exe file and have the same filename (except for the `.exe` -> `.ini` change).
|
||||
|
||||
By default, only `MSYSTEM` is set, but options for inheriting `PATH` and tweaking `MSYS` are prepared, as well as `CHERE_INVOKING` for the shell to stay in the current working directory (instead of changing to the home directory).
|
||||
|
||||
The .ini file contains environment variables, each on a separate line, in the usual `VAR=val` format. Lines starting with `#` are ignored. The values are expanded using the current environment (use Windows `%var%` syntax).
|
||||
|
||||
Pinning
|
||||
-------
|
||||
|
||||
As with many other applications, the correct way to pin a shortcut to the taskbar is by right-clicking the button of a running MSYS2 shell (started by this launcher) on the taskbar and choosing "Pin this program to taskbar". Pinning the `.exe` file itself won't create the shortcut correctly. There are tools to diagnose and fix such a situation (7+ Taskbar Tweaker and Win7AppId) in case re-pinning is not preferred.
|
||||
|
||||
327
launcher.c
327
launcher.c
@@ -1,41 +1,44 @@
|
||||
#define _UNICODE
|
||||
#define _WIN32_WINNT 0x0601
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define PSAPI_VERSION 1
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include <propvarutil.h>
|
||||
#include <shobjidl.h>
|
||||
#include <shellapi.h>
|
||||
#include <propsys.h>
|
||||
#include <propkey.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <psapi.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
int _CRT_glob = 0;
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
static void ShowError(const char* desc, const char* err, const long code) {
|
||||
char msg[1024];
|
||||
// if any of the properties change, it's best to use a brand new AppID
|
||||
#define APPID_REVISION 9
|
||||
|
||||
sprintf(msg, "%s. Reason: %s (0x%lx)", desc, err, code);
|
||||
MessageBox(NULL, msg, "Launcher error", MB_ICONEXCLAMATION | MB_OK);
|
||||
static void ShowError(const wchar_t* desc, const wchar_t* err, const long code) {
|
||||
wchar_t msg[1024];
|
||||
|
||||
swprintf(msg, 1024, L"%s. Reason: %s (0x%lx)", desc, err, code);
|
||||
MessageBox(NULL, msg, L"Launcher error", MB_ICONEXCLAMATION | MB_OK);
|
||||
}
|
||||
|
||||
static void ShowLastError(const char* desc) {
|
||||
static void ShowLastError(const wchar_t* desc) {
|
||||
DWORD code;
|
||||
char* err;
|
||||
wchar_t* err;
|
||||
|
||||
code = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&err, 0, NULL);
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&err, 0, NULL);
|
||||
ShowError(desc, err, code);
|
||||
LocalFree(err);
|
||||
}
|
||||
|
||||
static void ShowErrno(const wchar_t* desc) {
|
||||
wchar_t* err;
|
||||
|
||||
PROCESS_INFORMATION StartChild(const wchar_t* cmdline) {
|
||||
err = _wcserror(errno);
|
||||
ShowError(desc, err, errno);
|
||||
}
|
||||
|
||||
static PROCESS_INFORMATION StartChild(wchar_t* cmdline) {
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
DWORD code;
|
||||
@@ -44,126 +47,189 @@ PROCESS_INFORMATION StartChild(const wchar_t* cmdline) {
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
SetLastError(0);
|
||||
code = CreateProcessW(NULL, (wchar_t*)cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||
code = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||
if (code == 0) {
|
||||
ShowLastError("Could not start the shell");
|
||||
ShowLastError(L"Could not start the shell");
|
||||
ShowError(L"The command was", cmdline, 0);
|
||||
return pi;
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
static int SetEnv(const char* msystem) {
|
||||
static wchar_t* SetEnv(wchar_t* conffile) {
|
||||
int code;
|
||||
char* env;
|
||||
const char* err;
|
||||
const char prefix[] = "MSYSTEM=";
|
||||
size_t buflen;
|
||||
size_t expandedlen;
|
||||
wchar_t* tmp;
|
||||
wchar_t* buf;
|
||||
wchar_t* expanded;
|
||||
wchar_t* msystem;
|
||||
FILE* handle;
|
||||
|
||||
env = (char*)alloca(strlen(prefix) + strlen(msystem) + 1);
|
||||
strcpy(env, prefix);
|
||||
strcat(env, msystem);
|
||||
code = putenv(env);
|
||||
msystem = NULL;
|
||||
|
||||
handle = _wfopen(conffile, L"rt");
|
||||
if (handle == NULL) {
|
||||
ShowErrno(L"Could not open configuration file");
|
||||
return msystem;
|
||||
}
|
||||
|
||||
buflen = 512;
|
||||
buf = (wchar_t*)malloc(buflen * sizeof(wchar_t));
|
||||
*buf = L'\0';
|
||||
expandedlen = 2 * buflen;
|
||||
expanded = (wchar_t*)malloc(expandedlen * sizeof(wchar_t));
|
||||
while (true) {
|
||||
tmp = fgetws(buf + wcslen(buf), buflen - wcslen(buf), handle);
|
||||
if (tmp == NULL && !feof(handle)) {
|
||||
ShowErrno(L"Could not read from configuration file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp = buf + wcslen(buf) - 1;
|
||||
if (!feof(handle) && *tmp != L'\n') {
|
||||
buflen *= 2;
|
||||
buf = (wchar_t*)realloc(buf, buflen * sizeof(wchar_t));
|
||||
continue;
|
||||
}
|
||||
if (!feof(handle)) {
|
||||
*tmp = L'\0';
|
||||
}
|
||||
|
||||
if (*buf != L'\0' && *buf != L'#') {
|
||||
tmp = wcschr(buf, L'=');
|
||||
if (tmp != NULL) {
|
||||
*tmp++ = L'\0';
|
||||
while (expandedlen < 32768) {
|
||||
code = ExpandEnvironmentStrings(tmp, expanded, expandedlen);
|
||||
if ((size_t)code <= expandedlen) {
|
||||
break;
|
||||
}
|
||||
expandedlen *= 2;
|
||||
expanded = (wchar_t*)realloc(expanded, expandedlen * sizeof(wchar_t));
|
||||
}
|
||||
if ((*tmp != L'\0' && code == 0) || (size_t)code > expandedlen) {
|
||||
ShowLastError(L"Could not expand string");
|
||||
}
|
||||
if (0 == wcscmp(L"MSYSTEM", buf)) {
|
||||
msystem = _wcsdup(expanded);
|
||||
if (msystem == NULL) {
|
||||
ShowError(L"Could not duplicate string", expanded, 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
code = SetEnvironmentVariable(buf, expanded);
|
||||
if (code == 0) {
|
||||
ShowLastError(L"Could not set environment variable");
|
||||
}
|
||||
} else {
|
||||
ShowError(L"Could not parse environment line", buf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
*buf = L'\0';
|
||||
if (feof(handle)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
code = fclose(handle);
|
||||
if (code != 0) {
|
||||
err = strerror(errno);
|
||||
ShowError("Could not set MSYSTEM", err, errno);
|
||||
return 0;
|
||||
ShowErrno(L"Could not close configuration file");
|
||||
}
|
||||
|
||||
return 1;
|
||||
return msystem;
|
||||
}
|
||||
|
||||
struct handle_data {
|
||||
unsigned long process_id;
|
||||
HWND best_handle;
|
||||
};
|
||||
|
||||
|
||||
BOOL is_main_window(HWND handle)
|
||||
{
|
||||
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
|
||||
}
|
||||
|
||||
|
||||
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
|
||||
{
|
||||
struct handle_data* data = (struct handle_data*)lParam;
|
||||
unsigned long process_id = 0;
|
||||
GetWindowThreadProcessId(handle, &process_id);
|
||||
if (data->process_id != process_id || !is_main_window(handle)) {
|
||||
return TRUE;
|
||||
}
|
||||
data->best_handle = handle;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HWND find_main_window(unsigned long process_id)
|
||||
{
|
||||
struct handle_data data;
|
||||
data.process_id = process_id;
|
||||
data.best_handle = 0;
|
||||
EnumWindows(enum_windows_callback, (LPARAM)&data);
|
||||
return data.best_handle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HRESULT SetAppUserModelProperty(IPropertyStore* store, const PROPERTYKEY* key, LPCWSTR value) {
|
||||
PROPVARIANT propVariant;
|
||||
HRESULT hr;
|
||||
|
||||
propVariant.vt = VT_LPWSTR;
|
||||
hr = SHStrDupW(value, &propVariant.pwszVal);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = store->lpVtbl->SetValue(store, key, &propVariant);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int wmain(int argc, wchar_t* argv[]) {
|
||||
PROCESS_INFORMATION child;
|
||||
DWORD code;
|
||||
int res;
|
||||
HWND window;
|
||||
IPropertyStore* store;
|
||||
HRESULT hr;
|
||||
int code;
|
||||
size_t buflen;
|
||||
wchar_t* buf;
|
||||
wchar_t msysdir[PATH_MAX], exepath[PATH_MAX];
|
||||
int delay = 10;
|
||||
wchar_t* tmp;
|
||||
wchar_t* args;
|
||||
wchar_t* msystem;
|
||||
wchar_t msysdir[PATH_MAX];
|
||||
wchar_t exepath[PATH_MAX];
|
||||
wchar_t confpath[PATH_MAX];
|
||||
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
code = GetModuleFileNameW(NULL, exepath, sizeof(exepath) / sizeof(exepath[0]));
|
||||
code = GetModuleFileName(NULL, exepath, sizeof(exepath) / sizeof(exepath[0]));
|
||||
if (code == 0) {
|
||||
ShowLastError("Could not determine executable path");
|
||||
ShowLastError(L"Could not determine executable path");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
while (wcschr(exepath, L'\\') != NULL) {
|
||||
wcschr(exepath, L'\\')[0] = L'/';
|
||||
tmp = exepath;
|
||||
while (true) {
|
||||
tmp = wcschr(tmp, L'/');
|
||||
if (tmp == NULL) {
|
||||
break;
|
||||
}
|
||||
*tmp = L'\\';
|
||||
}
|
||||
|
||||
wcscpy(msysdir, exepath);
|
||||
if (wcsrchr(msysdir, L'/') != NULL) {
|
||||
wcsrchr(msysdir, L'/')[0] = L'\0';
|
||||
tmp = wcsrchr(msysdir, L'\\');
|
||||
if (tmp == NULL) {
|
||||
ShowError(L"Could not find root directory", msysdir, 0);
|
||||
return __LINE__;
|
||||
}
|
||||
buflen = wcslen(msysdir) + 1000;
|
||||
buf = (wchar_t*)alloca(buflen * sizeof(wchar_t));
|
||||
*tmp = L'\0';
|
||||
|
||||
code = SetEnv(STRINGIFY_A(MSYSTEM));
|
||||
if (code == 0) {
|
||||
wcscpy(confpath, exepath);
|
||||
tmp = confpath + wcslen(confpath) - 4;
|
||||
if (0 != wcsicmp(L".exe", tmp)) {
|
||||
ShowError(L"Could not find configuration file", confpath, 0);
|
||||
return __LINE__;
|
||||
}
|
||||
*tmp++ = L'.';
|
||||
*tmp++ = L'i';
|
||||
*tmp++ = L'n';
|
||||
*tmp++ = L'i';
|
||||
|
||||
if (argc > 1) {
|
||||
code = SetEnvironmentVariable(L"CHERE_INVOKING", L"1");
|
||||
if (code == 0) {
|
||||
ShowLastError(L"Could not set environment variable");
|
||||
}
|
||||
}
|
||||
|
||||
msystem = SetEnv(confpath);
|
||||
if (msystem == NULL) {
|
||||
ShowError(L"Did not find the MSYSTEM variable", confpath, 0);
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
res = swprintf(buf, buflen, L"%s/usr/bin/mintty.exe -i '%s' /usr/bin/bash --login -i", msysdir, exepath);
|
||||
if (res < 0) {
|
||||
code = SetEnvironmentVariable(L"MSYSCON", L"mintty.exe");
|
||||
if (code == 0) {
|
||||
ShowLastError(L"Could not set environment variable");
|
||||
}
|
||||
|
||||
// can break, but hopefully won't for most use cases
|
||||
args = GetCommandLine();
|
||||
if (args[0] == L'"') {
|
||||
args++;
|
||||
}
|
||||
args += wcslen(argv[0]);
|
||||
if (args[0] == L'"') {
|
||||
args++;
|
||||
}
|
||||
|
||||
code = -1;
|
||||
buf = NULL;
|
||||
buflen = 1024;
|
||||
while (code < 0 && buflen < 8192) {
|
||||
buf = (wchar_t*)realloc(buf, buflen * sizeof(wchar_t));
|
||||
if (buf == NULL) {
|
||||
ShowError(L"Could not allocate memory", L"", 0);
|
||||
return __LINE__;
|
||||
}
|
||||
code = swprintf(buf, buflen, L"%s\\usr\\bin\\mintty.exe -i '%s' -o 'AppLaunchCmd=%s' -o 'AppID=MSYS2.Shell.%s.%d' -o 'AppName=MSYS2 %s Shell' -t 'MSYS2 %s Shell' --store-taskbar-properties -- %s %s", msysdir, exepath, exepath, msystem, APPID_REVISION, msystem, msystem, argc == 1 ? L"-" : L"/usr/bin/sh -lc '\"$@\"' sh", args);
|
||||
buflen *= 2;
|
||||
}
|
||||
if (code < 0) {
|
||||
ShowErrno(L"Could not write to buffer");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
@@ -172,51 +238,8 @@ int main(int argc, char* argv[]) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
Sleep(delay);
|
||||
window = find_main_window(GetProcessId(child.hProcess));
|
||||
if (!window) {
|
||||
delay *= 2;
|
||||
if (delay > 60000) {
|
||||
return __LINE__;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
hr = SHGetPropertyStoreForWindow(window, &IID_IPropertyStore, (void**)&store);
|
||||
if (FAILED(hr)) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
hr = SetAppUserModelProperty(store, &PKEY_AppUserModel_ID, L"MSYS2.Shell." STRINGIFY_W(MSYSTEM) L".7");
|
||||
if (FAILED(hr)) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
hr = SetAppUserModelProperty(store, &PKEY_AppUserModel_RelaunchDisplayNameResource, L"MSYS2 " STRINGIFY_W(MSYSTEM) L" shell");
|
||||
if (FAILED(hr)) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
hr = SetAppUserModelProperty(store, &PKEY_AppUserModel_RelaunchCommand, exepath);
|
||||
if (FAILED(hr)) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
hr = SetAppUserModelProperty(store, &PKEY_AppUserModel_RelaunchIconResource, exepath);
|
||||
if (FAILED(hr)) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
hr = store->lpVtbl->Commit(store);
|
||||
if (FAILED(hr)) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
store->lpVtbl->Release(store);
|
||||
store = NULL;
|
||||
break;
|
||||
}
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
4
launcher.ini
Normal file
4
launcher.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
#MSYS=winsymlinks:nativestrict
|
||||
#MSYS=error_start:mingw64/bin/qtcreator.exe|-debug|<process-id>
|
||||
#CHERE_INVOKING=1
|
||||
#MSYS2_PATH_TYPE=inherit
|
||||
29
launcher.rc
29
launcher.rc
@@ -1,22 +1,23 @@
|
||||
#include "macros.h"
|
||||
#include "version.h"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,1,0,0
|
||||
FILEVERSION VER_MAJOR,VER_MINOR,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "ProductName", "MSYS2"
|
||||
VALUE "FileDescription", "MSYS2/" STRINGIFY_A(MSYSTEM) " shell launcher"
|
||||
VALUE "FileVersion", "0.1"
|
||||
END
|
||||
END
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "ProductName", "MSYS2"
|
||||
VALUE "FileDescription", "MSYS2 " STRINGIFY_A(MSYSTEM) " shell launcher"
|
||||
VALUE "FileVersion", STRINGIFY_A(VER_MAJOR) "." STRINGIFY_A(VER_MINOR)
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
id ICON STRINGIFY_A(ICONFILE)
|
||||
|
||||
5
macros.h
5
macros.h
@@ -1,3 +1,6 @@
|
||||
#ifndef M2L_MACROS_H
|
||||
#define M2L_MACROS_H
|
||||
|
||||
#define UNUSED(x) ((void)(x))
|
||||
|
||||
#define STRINGIFY_A_(x) #x
|
||||
@@ -5,3 +8,5 @@
|
||||
|
||||
#define STRINGIFY_W_(x) L ## #x
|
||||
#define STRINGIFY_W(x) STRINGIFY_W_(x)
|
||||
|
||||
#endif
|
||||
|
||||
BIN
mingw32.ico
BIN
mingw32.ico
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 25 KiB |
BIN
mingw32.pdn
BIN
mingw32.pdn
Binary file not shown.
BIN
mingw64.ico
BIN
mingw64.ico
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 25 KiB |
BIN
mingw64.pdn
BIN
mingw64.pdn
Binary file not shown.
Reference in New Issue
Block a user