Remove associator project - it's not needed
This commit is contained in:
parent
8559b3cecf
commit
6b2cf01744
731
PC/associator.c
731
PC/associator.c
|
@ -1,731 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2011-2012 Vinay Sajip. All rights reserved.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#include <windows.h>
|
|
||||||
#include <commctrl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "associator.h"
|
|
||||||
|
|
||||||
#define PYTHON_EXECUTABLE L"python.exe"
|
|
||||||
|
|
||||||
#define MSGSIZE 1024
|
|
||||||
#define MAX_VERSION_SIZE 4
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
wchar_t version[MAX_VERSION_SIZE]; /* m.n */
|
|
||||||
int bits; /* 32 or 64 */
|
|
||||||
wchar_t executable[MAX_PATH];
|
|
||||||
} INSTALLED_PYTHON;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* To avoid messing about with heap allocations, just assume we can allocate
|
|
||||||
* statically and never have to deal with more versions than this.
|
|
||||||
*/
|
|
||||||
#define MAX_INSTALLED_PYTHONS 100
|
|
||||||
|
|
||||||
static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS];
|
|
||||||
|
|
||||||
static size_t num_installed_pythons = 0;
|
|
||||||
|
|
||||||
/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */
|
|
||||||
#define IP_BASE_SIZE 40
|
|
||||||
#define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE)
|
|
||||||
#define CORE_PATH L"SOFTWARE\\Python\\PythonCore"
|
|
||||||
|
|
||||||
static wchar_t * location_checks[] = {
|
|
||||||
L"\\",
|
|
||||||
/*
|
|
||||||
L"\\PCBuild\\",
|
|
||||||
L"\\PCBuild\\amd64\\",
|
|
||||||
*/
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static wchar_t *
|
|
||||||
skip_whitespace(wchar_t * p)
|
|
||||||
{
|
|
||||||
while (*p && isspace(*p))
|
|
||||||
++p;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is here to minimise Visual Studio
|
|
||||||
* warnings about security implications of getenv, and to
|
|
||||||
* treat blank values as if they are absent.
|
|
||||||
*/
|
|
||||||
static wchar_t * get_env(wchar_t * key)
|
|
||||||
{
|
|
||||||
wchar_t * result = _wgetenv(key);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
result = skip_whitespace(result);
|
|
||||||
if (*result == L'\0')
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FILE * log_fp = NULL;
|
|
||||||
|
|
||||||
static void
|
|
||||||
debug(wchar_t * format, ...)
|
|
||||||
{
|
|
||||||
va_list va;
|
|
||||||
|
|
||||||
if (log_fp != NULL) {
|
|
||||||
va_start(va, format);
|
|
||||||
vfwprintf_s(log_fp, format, va);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void winerror(int rc, wchar_t * message, int size)
|
|
||||||
{
|
|
||||||
FormatMessageW(
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
message, size, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INSTALLED_PYTHON *
|
|
||||||
find_existing_python(wchar_t * path)
|
|
||||||
{
|
|
||||||
INSTALLED_PYTHON * result = NULL;
|
|
||||||
size_t i;
|
|
||||||
INSTALLED_PYTHON * ip;
|
|
||||||
|
|
||||||
for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++, ip++) {
|
|
||||||
if (_wcsicmp(path, ip->executable) == 0) {
|
|
||||||
result = ip;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
locate_pythons_for_key(HKEY root, REGSAM flags)
|
|
||||||
{
|
|
||||||
HKEY core_root, ip_key;
|
|
||||||
LSTATUS status = RegOpenKeyExW(root, CORE_PATH, 0, flags, &core_root);
|
|
||||||
wchar_t message[MSGSIZE];
|
|
||||||
DWORD i;
|
|
||||||
size_t n;
|
|
||||||
BOOL ok;
|
|
||||||
DWORD type, data_size, attrs;
|
|
||||||
INSTALLED_PYTHON * ip, * pip;
|
|
||||||
wchar_t ip_path[IP_SIZE];
|
|
||||||
wchar_t * check;
|
|
||||||
wchar_t ** checkp;
|
|
||||||
wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU";
|
|
||||||
|
|
||||||
if (status != ERROR_SUCCESS)
|
|
||||||
debug(L"locate_pythons_for_key: unable to open PythonCore key in %s\n",
|
|
||||||
key_name);
|
|
||||||
else {
|
|
||||||
ip = &installed_pythons[num_installed_pythons];
|
|
||||||
for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) {
|
|
||||||
status = RegEnumKeyW(core_root, i, ip->version, MAX_VERSION_SIZE);
|
|
||||||
if (status != ERROR_SUCCESS) {
|
|
||||||
if (status != ERROR_NO_MORE_ITEMS) {
|
|
||||||
/* unexpected error */
|
|
||||||
winerror(status, message, MSGSIZE);
|
|
||||||
debug(L"Can't enumerate registry key for version %s: %s\n",
|
|
||||||
ip->version, message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_snwprintf_s(ip_path, IP_SIZE, _TRUNCATE,
|
|
||||||
L"%s\\%s\\InstallPath", CORE_PATH, ip->version);
|
|
||||||
status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key);
|
|
||||||
if (status != ERROR_SUCCESS) {
|
|
||||||
winerror(status, message, MSGSIZE);
|
|
||||||
// Note: 'message' already has a trailing \n
|
|
||||||
debug(L"%s\\%s: %s", key_name, ip_path, message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
data_size = sizeof(ip->executable) - 1;
|
|
||||||
status = RegQueryValueEx(ip_key, NULL, NULL, &type,
|
|
||||||
(LPBYTE) ip->executable, &data_size);
|
|
||||||
RegCloseKey(ip_key);
|
|
||||||
if (status != ERROR_SUCCESS) {
|
|
||||||
winerror(status, message, MSGSIZE);
|
|
||||||
debug(L"%s\\%s: %s\n", key_name, ip_path, message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (type == REG_SZ) {
|
|
||||||
data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */
|
|
||||||
if (ip->executable[data_size - 1] == L'\\')
|
|
||||||
--data_size; /* reg value ended in a backslash */
|
|
||||||
/* ip->executable is data_size long */
|
|
||||||
for (checkp = location_checks; *checkp; ++checkp) {
|
|
||||||
check = *checkp;
|
|
||||||
_snwprintf_s(&ip->executable[data_size],
|
|
||||||
MAX_PATH - data_size,
|
|
||||||
MAX_PATH - data_size,
|
|
||||||
L"%s%s", check, PYTHON_EXECUTABLE);
|
|
||||||
attrs = GetFileAttributesW(ip->executable);
|
|
||||||
if (attrs == INVALID_FILE_ATTRIBUTES) {
|
|
||||||
winerror(GetLastError(), message, MSGSIZE);
|
|
||||||
debug(L"locate_pythons_for_key: %s: %s",
|
|
||||||
ip->executable, message);
|
|
||||||
}
|
|
||||||
else if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
|
|
||||||
debug(L"locate_pythons_for_key: '%s' is a \
|
|
||||||
directory\n",
|
|
||||||
ip->executable, attrs);
|
|
||||||
}
|
|
||||||
else if (find_existing_python(ip->executable)) {
|
|
||||||
debug(L"locate_pythons_for_key: %s: already \
|
|
||||||
found: %s\n", ip->executable);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* check the executable type. */
|
|
||||||
ok = GetBinaryTypeW(ip->executable, &attrs);
|
|
||||||
if (!ok) {
|
|
||||||
debug(L"Failure getting binary type: %s\n",
|
|
||||||
ip->executable);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (attrs == SCS_64BIT_BINARY)
|
|
||||||
ip->bits = 64;
|
|
||||||
else if (attrs == SCS_32BIT_BINARY)
|
|
||||||
ip->bits = 32;
|
|
||||||
else
|
|
||||||
ip->bits = 0;
|
|
||||||
if (ip->bits == 0) {
|
|
||||||
debug(L"locate_pythons_for_key: %s: \
|
|
||||||
invalid binary type: %X\n",
|
|
||||||
ip->executable, attrs);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (wcschr(ip->executable, L' ') != NULL) {
|
|
||||||
/* has spaces, so quote */
|
|
||||||
n = wcslen(ip->executable);
|
|
||||||
memmove(&ip->executable[1],
|
|
||||||
ip->executable, n * sizeof(wchar_t));
|
|
||||||
ip->executable[0] = L'\"';
|
|
||||||
ip->executable[n + 1] = L'\"';
|
|
||||||
ip->executable[n + 2] = L'\0';
|
|
||||||
}
|
|
||||||
debug(L"locate_pythons_for_key: %s \
|
|
||||||
is a %dbit executable\n",
|
|
||||||
ip->executable, ip->bits);
|
|
||||||
++num_installed_pythons;
|
|
||||||
pip = ip++;
|
|
||||||
if (num_installed_pythons >=
|
|
||||||
MAX_INSTALLED_PYTHONS)
|
|
||||||
break;
|
|
||||||
/* Copy over the attributes for the next */
|
|
||||||
*ip = *pip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegCloseKey(core_root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_pythons(const void * p1, const void * p2)
|
|
||||||
{
|
|
||||||
INSTALLED_PYTHON * ip1 = (INSTALLED_PYTHON *) p1;
|
|
||||||
INSTALLED_PYTHON * ip2 = (INSTALLED_PYTHON *) p2;
|
|
||||||
/* note reverse sorting on version */
|
|
||||||
int result = wcscmp(ip2->version, ip1->version);
|
|
||||||
|
|
||||||
if (result == 0)
|
|
||||||
result = ip2->bits - ip1->bits; /* 64 before 32 */
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
locate_all_pythons()
|
|
||||||
{
|
|
||||||
#if defined(_M_X64)
|
|
||||||
// If we are a 64bit process, first hit the 32bit keys.
|
|
||||||
debug(L"locating Pythons in 32bit registry\n");
|
|
||||||
locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_32KEY);
|
|
||||||
locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_32KEY);
|
|
||||||
#else
|
|
||||||
// If we are a 32bit process on a 64bit Windows, first hit the 64bit keys.
|
|
||||||
BOOL f64 = FALSE;
|
|
||||||
if (IsWow64Process(GetCurrentProcess(), &f64) && f64) {
|
|
||||||
debug(L"locating Pythons in 64bit registry\n");
|
|
||||||
locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_64KEY);
|
|
||||||
locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// now hit the "native" key for this process bittedness.
|
|
||||||
debug(L"locating Pythons in native registry\n");
|
|
||||||
locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ);
|
|
||||||
locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ);
|
|
||||||
qsort(installed_pythons, num_installed_pythons, sizeof(INSTALLED_PYTHON),
|
|
||||||
compare_pythons);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
wchar_t * path;
|
|
||||||
wchar_t * key;
|
|
||||||
wchar_t * value;
|
|
||||||
} REGISTRY_ENTRY;
|
|
||||||
|
|
||||||
static REGISTRY_ENTRY registry_entries[] = {
|
|
||||||
{ L".py", NULL, L"Python.File" },
|
|
||||||
{ L".pyc", NULL, L"Python.CompiledFile" },
|
|
||||||
{ L".pyo", NULL, L"Python.CompiledFile" },
|
|
||||||
{ L".pyw", NULL, L"Python.NoConFile" },
|
|
||||||
|
|
||||||
{ L"Python.CompiledFile", NULL, L"Compiled Python File" },
|
|
||||||
{ L"Python.CompiledFile\\DefaultIcon", NULL, L"pyc.ico" },
|
|
||||||
{ L"Python.CompiledFile\\shell\\open", NULL, L"Open" },
|
|
||||||
{ L"Python.CompiledFile\\shell\\open\\command", NULL, L"python.exe" },
|
|
||||||
|
|
||||||
{ L"Python.File", NULL, L"Python File" },
|
|
||||||
{ L"Python.File\\DefaultIcon", NULL, L"py.ico" },
|
|
||||||
{ L"Python.File\\shell\\open", NULL, L"Open" },
|
|
||||||
{ L"Python.File\\shell\\open\\command", NULL, L"python.exe" },
|
|
||||||
|
|
||||||
{ L"Python.NoConFile", NULL, L"Python File (no console)" },
|
|
||||||
{ L"Python.NoConFile\\DefaultIcon", NULL, L"py.ico" },
|
|
||||||
{ L"Python.NoConFile\\shell\\open", NULL, L"Open" },
|
|
||||||
{ L"Python.NoConFile\\shell\\open\\command", NULL, L"pythonw.exe" },
|
|
||||||
|
|
||||||
{ NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
do_association(INSTALLED_PYTHON * ip)
|
|
||||||
{
|
|
||||||
LONG rc;
|
|
||||||
BOOL result = TRUE;
|
|
||||||
REGISTRY_ENTRY * rp = registry_entries;
|
|
||||||
wchar_t value[MAX_PATH];
|
|
||||||
wchar_t root[MAX_PATH];
|
|
||||||
wchar_t message[MSGSIZE];
|
|
||||||
wchar_t * pvalue;
|
|
||||||
HKEY hKey;
|
|
||||||
DWORD len;
|
|
||||||
|
|
||||||
wcsncpy_s(root, MAX_PATH, ip->executable, _TRUNCATE);
|
|
||||||
pvalue = wcsrchr(root, '\\');
|
|
||||||
if (pvalue)
|
|
||||||
*pvalue = L'\0';
|
|
||||||
|
|
||||||
for (; rp->path; ++rp) {
|
|
||||||
if (wcsstr(rp->path, L"DefaultIcon")) {
|
|
||||||
pvalue = value;
|
|
||||||
_snwprintf_s(value, MAX_PATH, _TRUNCATE,
|
|
||||||
L"%s\\DLLs\\%s", root, rp->value);
|
|
||||||
}
|
|
||||||
else if (wcsstr(rp->path, L"open\\command")) {
|
|
||||||
pvalue = value;
|
|
||||||
_snwprintf_s(value, MAX_PATH, _TRUNCATE,
|
|
||||||
L"%s\\%s \"%%1\" %%*", root, rp->value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pvalue = rp->value;
|
|
||||||
}
|
|
||||||
/* use rp->path, rp->key, pvalue */
|
|
||||||
/* NOTE: size is in bytes */
|
|
||||||
len = (DWORD) ((1 + wcslen(pvalue)) * sizeof(wchar_t));
|
|
||||||
rc = RegOpenKeyEx(HKEY_CLASSES_ROOT, rp->path, 0, KEY_SET_VALUE, &hKey);
|
|
||||||
if (rc == ERROR_SUCCESS) {
|
|
||||||
rc = RegSetValueExW(hKey, rp->key, 0, REG_SZ, (LPBYTE) pvalue, len);
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
}
|
|
||||||
if (rc != ERROR_SUCCESS) {
|
|
||||||
winerror(rc, message, MSGSIZE);
|
|
||||||
MessageBoxW(NULL, message, L"Unable to set file associations", MB_OK | MB_ICONSTOP);
|
|
||||||
result = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
associations_exist()
|
|
||||||
{
|
|
||||||
BOOL result = FALSE;
|
|
||||||
REGISTRY_ENTRY * rp = registry_entries;
|
|
||||||
wchar_t buffer[MSGSIZE];
|
|
||||||
LONG csize = MSGSIZE * sizeof(wchar_t);
|
|
||||||
LONG rc;
|
|
||||||
|
|
||||||
/* Currently, if any is found, we assume they're all there. */
|
|
||||||
|
|
||||||
for (; rp->path; ++rp) {
|
|
||||||
LONG size = csize;
|
|
||||||
rc = RegQueryValueW(HKEY_CLASSES_ROOT, rp->path, buffer, &size);
|
|
||||||
if (rc == ERROR_SUCCESS) {
|
|
||||||
result = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static BOOL CALLBACK
|
|
||||||
find_by_title(HWND hwnd, LPARAM lParam)
|
|
||||||
{
|
|
||||||
wchar_t buffer[MSGSIZE];
|
|
||||||
BOOL not_found = TRUE;
|
|
||||||
|
|
||||||
wchar_t * p = (wchar_t *) GetWindowTextW(hwnd, buffer, MSGSIZE);
|
|
||||||
if (wcsstr(buffer, L"Python Launcher") == buffer) {
|
|
||||||
not_found = FALSE;
|
|
||||||
*((HWND *) lParam) = hwnd;
|
|
||||||
}
|
|
||||||
return not_found;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HWND
|
|
||||||
find_installer_window()
|
|
||||||
{
|
|
||||||
HWND result = NULL;
|
|
||||||
BOOL found = EnumWindows(find_by_title, (LPARAM) &result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
centre_window_in_front(HWND hwnd)
|
|
||||||
{
|
|
||||||
HWND hwndParent;
|
|
||||||
RECT rect, rectP;
|
|
||||||
int width, height;
|
|
||||||
int screenwidth, screenheight;
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
//make the window relative to its parent
|
|
||||||
|
|
||||||
screenwidth = GetSystemMetrics(SM_CXSCREEN);
|
|
||||||
screenheight = GetSystemMetrics(SM_CYSCREEN);
|
|
||||||
|
|
||||||
hwndParent = GetParent(hwnd);
|
|
||||||
|
|
||||||
GetWindowRect(hwnd, &rect);
|
|
||||||
if (hwndParent) {
|
|
||||||
GetWindowRect(hwndParent, &rectP);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rectP.left = rectP.top = 0;
|
|
||||||
rectP.right = screenwidth;
|
|
||||||
rectP.bottom = screenheight;
|
|
||||||
}
|
|
||||||
|
|
||||||
width = rect.right - rect.left;
|
|
||||||
height = rect.bottom - rect.top;
|
|
||||||
|
|
||||||
x = ((rectP.right-rectP.left) - width) / 2 + rectP.left;
|
|
||||||
y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top;
|
|
||||||
|
|
||||||
|
|
||||||
//make sure that the dialog box never moves outside of
|
|
||||||
//the screen
|
|
||||||
|
|
||||||
if (x < 0)
|
|
||||||
x = 0;
|
|
||||||
|
|
||||||
if (y < 0)
|
|
||||||
y = 0;
|
|
||||||
|
|
||||||
if (x + width > screenwidth)
|
|
||||||
x = screenwidth - width;
|
|
||||||
if (y + height > screenheight)
|
|
||||||
y = screenheight - height;
|
|
||||||
|
|
||||||
SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, SWP_SHOWWINDOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_list(HWND hList)
|
|
||||||
{
|
|
||||||
LVCOLUMNW column;
|
|
||||||
LVITEMW item;
|
|
||||||
int colno = 0;
|
|
||||||
int width = 0;
|
|
||||||
int row;
|
|
||||||
size_t i;
|
|
||||||
INSTALLED_PYTHON * ip;
|
|
||||||
RECT r;
|
|
||||||
LPARAM style;
|
|
||||||
|
|
||||||
GetClientRect(hList, &r);
|
|
||||||
|
|
||||||
style = SendMessage(hList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
|
|
||||||
SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE,
|
|
||||||
0, style | LVS_EX_FULLROWSELECT);
|
|
||||||
|
|
||||||
/* First set up the columns */
|
|
||||||
memset(&column, 0, sizeof(column));
|
|
||||||
column.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
|
|
||||||
column.pszText = L"Version";
|
|
||||||
column.cx = 60;
|
|
||||||
width += column.cx;
|
|
||||||
SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column);
|
|
||||||
#if defined(_M_X64)
|
|
||||||
column.pszText = L"Bits";
|
|
||||||
column.cx = 40;
|
|
||||||
column.iSubItem = colno;
|
|
||||||
SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column);
|
|
||||||
width += column.cx;
|
|
||||||
#endif
|
|
||||||
column.pszText = L"Path";
|
|
||||||
column.cx = r.right - r.top - width;
|
|
||||||
column.iSubItem = colno;
|
|
||||||
SendMessage(hList, LVM_INSERTCOLUMN, colno++,(LPARAM) &column);
|
|
||||||
|
|
||||||
/* Then insert the rows */
|
|
||||||
memset(&item, 0, sizeof(item));
|
|
||||||
item.mask = LVIF_TEXT;
|
|
||||||
for (i = 0, ip = installed_pythons; i < num_installed_pythons; i++,ip++) {
|
|
||||||
item.iItem = (int) i;
|
|
||||||
item.iSubItem = 0;
|
|
||||||
item.pszText = ip->version;
|
|
||||||
colno = 0;
|
|
||||||
row = (int) SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM) &item);
|
|
||||||
#if defined(_M_X64)
|
|
||||||
item.iSubItem = ++colno;
|
|
||||||
item.pszText = (ip->bits == 64) ? L"64": L"32";
|
|
||||||
SendMessage(hList, LVM_SETITEM, row, (LPARAM) &item);
|
|
||||||
#endif
|
|
||||||
item.iSubItem = ++colno;
|
|
||||||
item.pszText = ip->executable;
|
|
||||||
SendMessage(hList, LVM_SETITEM, row, (LPARAM) &item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------*/
|
|
||||||
|
|
||||||
typedef int (__stdcall *MSGBOXWAPI)(IN HWND hWnd,
|
|
||||||
IN LPCWSTR lpText, IN LPCWSTR lpCaption,
|
|
||||||
IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
|
|
||||||
|
|
||||||
int MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText,
|
|
||||||
IN LPCWSTR lpCaption, IN UINT uType,
|
|
||||||
IN WORD wLanguageId, IN DWORD dwMilliseconds);
|
|
||||||
|
|
||||||
#define MB_TIMEDOUT 32000
|
|
||||||
|
|
||||||
int MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText,
|
|
||||||
LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds)
|
|
||||||
{
|
|
||||||
static MSGBOXWAPI MsgBoxTOW = NULL;
|
|
||||||
|
|
||||||
if (!MsgBoxTOW) {
|
|
||||||
HMODULE hUser32 = GetModuleHandleW(L"user32.dll");
|
|
||||||
if (hUser32)
|
|
||||||
MsgBoxTOW = (MSGBOXWAPI)GetProcAddress(hUser32,
|
|
||||||
"MessageBoxTimeoutW");
|
|
||||||
else {
|
|
||||||
//stuff happened, add code to handle it here
|
|
||||||
//(possibly just call MessageBox())
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MsgBoxTOW)
|
|
||||||
return MsgBoxTOW(hWnd, lpText, lpCaption, uType, wLanguageId,
|
|
||||||
dwMilliseconds);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static INT_PTR CALLBACK
|
|
||||||
DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
HWND hList;
|
|
||||||
HWND hChild;
|
|
||||||
static int selected_index = -1;
|
|
||||||
WORD low = LOWORD(wParam);
|
|
||||||
wchar_t confirmation[MSGSIZE];
|
|
||||||
BOOL result = FALSE;
|
|
||||||
|
|
||||||
debug(L"DialogProc entry: 0x%02X\n", message);
|
|
||||||
switch (message) {
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
hList = GetDlgItem(hDlg, IDC_LIST1);
|
|
||||||
init_list(hList);
|
|
||||||
SetFocus(hList);
|
|
||||||
result = TRUE;
|
|
||||||
break;
|
|
||||||
case WM_COMMAND:
|
|
||||||
if((low == IDOK) || (low == IDCANCEL)) {
|
|
||||||
HMODULE hUser32 = LoadLibraryW(L"user32.dll");
|
|
||||||
|
|
||||||
if (low == IDCANCEL)
|
|
||||||
wcsncpy_s(confirmation, MSGSIZE, L"No association was \
|
|
||||||
performed.", _TRUNCATE);
|
|
||||||
else {
|
|
||||||
if (selected_index < 0) {
|
|
||||||
/* should never happen */
|
|
||||||
wcsncpy_s(confirmation, MSGSIZE, L"The Python version to \
|
|
||||||
associate with couldn't be determined.", _TRUNCATE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
INSTALLED_PYTHON * ip = &installed_pythons[selected_index];
|
|
||||||
|
|
||||||
/* Do the association and set the message. */
|
|
||||||
do_association(ip);
|
|
||||||
_snwprintf_s(confirmation, MSGSIZE, _TRUNCATE,
|
|
||||||
L"Associated Python files with the Python %s \
|
|
||||||
found at '%s'", ip->version, ip->executable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hUser32) {
|
|
||||||
MessageBoxTimeoutW(hDlg,
|
|
||||||
confirmation,
|
|
||||||
L"Association Status",
|
|
||||||
MB_OK | MB_SETFOREGROUND |
|
|
||||||
MB_ICONINFORMATION,
|
|
||||||
0, 2000);
|
|
||||||
FreeLibrary(hUser32);
|
|
||||||
}
|
|
||||||
PostQuitMessage(0);
|
|
||||||
EndDialog(hDlg, 0);
|
|
||||||
result = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_NOTIFY:
|
|
||||||
if (low == IDC_LIST1) {
|
|
||||||
NMLISTVIEW * p = (NMLISTVIEW *) lParam;
|
|
||||||
|
|
||||||
if ((p->hdr.code == LVN_ITEMCHANGED) &&
|
|
||||||
(p->uNewState & LVIS_SELECTED)) {
|
|
||||||
hChild = GetDlgItem(hDlg, IDOK);
|
|
||||||
selected_index = p->iItem;
|
|
||||||
EnableWindow(hChild, selected_index >= 0);
|
|
||||||
}
|
|
||||||
result = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_DESTROY:
|
|
||||||
PostQuitMessage(0);
|
|
||||||
result = TRUE;
|
|
||||||
break;
|
|
||||||
case WM_CLOSE:
|
|
||||||
DestroyWindow(hDlg);
|
|
||||||
result = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug(L"DialogProc exit: %d\n", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WINAPI wWinMain(HINSTANCE hInstance,
|
|
||||||
HINSTANCE hPrevInstance,
|
|
||||||
LPWSTR lpCmdLine, int nShow)
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
HWND hDialog = 0;
|
|
||||||
HICON hIcon;
|
|
||||||
HWND hParent;
|
|
||||||
int status;
|
|
||||||
DWORD dw;
|
|
||||||
INITCOMMONCONTROLSEX icx;
|
|
||||||
wchar_t * wp;
|
|
||||||
|
|
||||||
wp = get_env(L"PYASSOC_DEBUG");
|
|
||||||
if ((wp != NULL) && (*wp != L'\0')) {
|
|
||||||
fopen_s(&log_fp, "c:\\temp\\associator.log", "w");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lpCmdLine) {
|
|
||||||
debug(L"No command line specified.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!wcsstr(lpCmdLine, L"nocheck") &&
|
|
||||||
associations_exist()) /* Could have been restored by uninstall. */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
locate_all_pythons();
|
|
||||||
|
|
||||||
if (num_installed_pythons == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
debug(L"%d pythons found.\n", num_installed_pythons);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OK, now there's something to do.
|
|
||||||
*
|
|
||||||
* We need to find the installer window to be the parent of
|
|
||||||
* our dialog, otherwise our dialog will be behind it.
|
|
||||||
*
|
|
||||||
* First, initialize common controls. If you don't - on
|
|
||||||
* some machines it works fine, on others the dialog never
|
|
||||||
* appears!
|
|
||||||
*/
|
|
||||||
|
|
||||||
icx.dwSize = sizeof(icx);
|
|
||||||
icx.dwICC = ICC_LISTVIEW_CLASSES;
|
|
||||||
InitCommonControlsEx(&icx);
|
|
||||||
|
|
||||||
hParent = find_installer_window();
|
|
||||||
debug(L"installer window: %X\n", hParent);
|
|
||||||
hDialog = CreateDialogW(hInstance, MAKEINTRESOURCE(DLG_MAIN), hParent,
|
|
||||||
DialogProc);
|
|
||||||
dw = GetLastError();
|
|
||||||
debug(L"dialog created: %X: error: %X\n", hDialog, dw);
|
|
||||||
|
|
||||||
if (!hDialog)
|
|
||||||
{
|
|
||||||
wchar_t buf [100];
|
|
||||||
_snwprintf_s(buf, 100, _TRUNCATE, L"Error 0x%x", GetLastError());
|
|
||||||
MessageBoxW(0, buf, L"CreateDialog", MB_ICONEXCLAMATION | MB_OK);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
centre_window_in_front(hDialog);
|
|
||||||
hIcon = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(DLG_ICON));
|
|
||||||
if( hIcon )
|
|
||||||
{
|
|
||||||
SendMessage(hDialog, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
|
|
||||||
SendMessage(hDialog, WM_SETICON, ICON_SMALL, (LPARAM) hIcon);
|
|
||||||
DestroyIcon(hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((status = GetMessage (& msg, 0, 0, 0)) != 0)
|
|
||||||
{
|
|
||||||
if (status == -1)
|
|
||||||
return -1;
|
|
||||||
if (!IsDialogMessage(hDialog, & msg))
|
|
||||||
{
|
|
||||||
TranslateMessage( & msg );
|
|
||||||
DispatchMessage( & msg );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int) msg.wParam;
|
|
||||||
}
|
|
1480
PC/associator.h
1480
PC/associator.h
File diff suppressed because it is too large
Load Diff
|
@ -1,97 +0,0 @@
|
||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#include "associator.h"
|
|
||||||
#include "winuser.h"
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.K.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
DLG_ICON ICON "launcher.ico"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Dialog
|
|
||||||
//
|
|
||||||
|
|
||||||
DLG_MAIN DIALOGEX 20, 40, 236, 183
|
|
||||||
// Make the dialog visible after positioning at centre
|
|
||||||
STYLE DS_SETFONT | DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
|
|
||||||
EXSTYLE WS_EX_NOPARENTNOTIFY
|
|
||||||
CAPTION "Python File Associations Have Ceased To Be!"
|
|
||||||
FONT 10, "Arial", 400, 0, 0x0
|
|
||||||
BEGIN
|
|
||||||
LTEXT "You've uninstalled the Python Launcher, so now there are no applications associated with Python files.",IDC_STATIC,7,7,225,18
|
|
||||||
LTEXT "You may wish to associate Python files with one of the Python versions installed on your machine, listed below:",IDC_STATIC,7,27,225,18
|
|
||||||
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,6,49,224,105
|
|
||||||
PUSHBUTTON "&Associate with selected Python",IDOK,6,164,117,14,WS_DISABLED
|
|
||||||
PUSHBUTTON "Do&n't associate Python files",IDCANCEL,128,164,102,14
|
|
||||||
END
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// DESIGNINFO
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
GUIDELINES DESIGNINFO
|
|
||||||
BEGIN
|
|
||||||
DLG_MAIN, DIALOG
|
|
||||||
BEGIN
|
|
||||||
RIGHTMARGIN, 238
|
|
||||||
END
|
|
||||||
END
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // English (U.K.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{023B3CDA-59C8-45FD-95DC-F8973322ED34}</ProjectGuid>
|
|
||||||
<RootNamespace>associator</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
<Import Project="pyproject.props" />
|
|
||||||
<Import Project="debug.props" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
<Import Project="pyproject.props" />
|
|
||||||
<Import Project="release.props" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup />
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\PC\associator.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="..\PC\associator.rc" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\PC\associator.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
|
@ -1,32 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\PC\associator.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="..\PC\associator.rc">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\PC\associator.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -72,8 +72,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vc
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "associator", "associator.vcxproj", "{023B3CDA-59C8-45FD-95DC-F8973322ED34}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
|
Loading…
Reference in New Issue