From 44d977fd79ad569261cbb19dcfc84bb9f37af0e7 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Thu, 23 Oct 2014 03:00:51 +0100 Subject: [PATCH] WIP Signed-off-by: Daira Hopwood --- .../windows/installer/installer/installer.cpp | 138 +++++++++++++++++- 1 file changed, 134 insertions(+), 4 deletions(-) diff --git a/misc/build_helpers/windows/installer/installer/installer.cpp b/misc/build_helpers/windows/installer/installer/installer.cpp index 232793b6..e8986fdf 100644 --- a/misc/build_helpers/windows/installer/installer/installer.cpp +++ b/misc/build_helpers/windows/installer/installer/installer.cpp @@ -3,12 +3,142 @@ #include "stdafx.h" #include +#include +#include -int main(int argc, char *argv[]); +// Turn off the warnings nagging you to use the more complicated *_s +// "secure" functions that are actually more difficult to use securely. +#pragma warning(disable:4996) -int main(int argc, char *argv[]) -{ - printf("hello"); +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +int wmain(int argc, wchar_t *argv[]); +void self_extract(wchar_t *destination_dir); +bool have_acceptable_python(); +void install_python(); +wchar_t * get_default_destination_dir(); +bool unzip(wchar_t *zip_path, wchar_t *destination_dir); + +#define MINIMUM_PYTHON_VERSION L"2.7.0" +#define INSTALL_PYTHON_VERSION L"2.7.8" +#define PYTHON_INSTALLER_32BIT (L"python-" INSTALL_PYTHON_VERSION L".msi") +#define PYTHON_INSTALLER_64BIT (L"python-" INSTALL_PYTHON_VERSION L".amd64.msi") + +int wmain(int argc, wchar_t *argv[]) { + if (argc >= 2 && wcscmp(argv[1], L"--help") == 0) { + printf("installer \n"); + } + wchar_t *destination_dir = (argc >= 2) ? argv[1] : get_default_destination_dir(); + + self_extract(destination_dir); + if (!have_acceptable_python()) { + install_python(); + } + //unlink(python_installer); return 0; } +void self_extract(wchar_t *destination_dir) { + HMODULE hModule = GetModuleHandle(NULL); + assert(hModule != NULL); + WCHAR executable_path[MAX_PATH]; + GetModuleFileNameW(hModule, executable_path, MAX_PATH); + assert(GetLastError() == ERROR_SUCCESS); + + wchar_t executable_dir[_MAX_DRIVE-1 + _MAX_DIR], dir_on_drive[_MAX_DIR]; + errno = 0; + _wsplitpath(executable_path, executable_dir, dir_on_drive, NULL, NULL); // can't overflow + assert(errno == 0); + wcscat(executable_dir, dir_on_drive); // can't overflow + assert(errno == 0); + assert(SetCurrentDirectoryW(executable_dir) != 0); +} + +bool have_acceptable_python() { + printf("Checking for Python 2.7..."); + //key = OpenKey(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE) + //key = OpenKey(HKEY_CURRENT_USER, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE) + //... + return false; +} + +void install_python() { + // The current directory should be the root of ... + //CreateProcessW(".msi"); +} + +wchar_t * get_default_destination_dir() { + return L""; +} + +bool unzip(LPWSTR zipFile, LPWSTR folder) { + // Essentially something like: + // Shell.NameSpace(folder).CopyHere(Shell.NameSpace(zipFile)) + + BSTR bstrZipFile = SysAllocString(zipFile); + assert(bstrZipFile); + BSTR bstrFolder = SysAllocString(folder); + assert(bstrFolder); + + HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + assert(res == S_OK || res == S_FALSE); + __try { + IShellDispatch *pISD; + assert(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **) &pISD) == S_OK); + + VARIANT InZipFile; + InZipFile.vt = VT_BSTR; + InZipFile.bstrVal = bstrZipFile; + Folder *pZippedFile = NULL; + pISD->NameSpace(InZipFile, &pZippedFile); + assert(pZippedFile); + + VARIANT OutFolder; + OutFolder.vt = VT_BSTR; + OutFolder.bstrVal = SysAllocString(folder); + assert(OutFolder.bstrVal); + Folder *pDestination = NULL; + pISD->NameSpace(OutFolder, &pDestination); + assert(pDestination); + + FolderItems *pFilesInside = NULL; + pZippedFile->Items(&pFilesInside); + assert(pFilesInside); + + IDispatch *pItem = NULL; + pFilesInside->QueryInterface(IID_IDispatch, (void **) &pItem); + assert(pItem); + + VARIANT Item; + Item.vt = VT_DISPATCH; + Item.pdispVal = pItem; + + VARIANT Options; + Options.vt = VT_I4; + // http://msdn.microsoft.com/en-us/library/bb787866(VS.85).aspx + // (4) Do not display a progress dialog box. + // (16) Respond with "Yes to All" for any dialog box that is displayed. + // (256) Display a progress dialog box but do not show the file names. + // (512) Do not confirm the creation of a new directory if the operation requires one to be created. + // (1024) Do not display a user interface if an error occurs. + + Options.lVal = 512 | 256 | 16; + + bool retval = pDestination->CopyHere(Item, Options) == S_OK; + return retval; + + } __finally { + //if (bstrInZipFile) SysFreeString(bstrInZipFile); + //if (bstrOutFolder) SysFreeString(bstrOutFolder); + //if (pItem) pItem->Release(); + //if (pFilesInside) pFilesInside->Release(); + //if (pDestination) pDestination->Release(); + //if (pZippedFile) pZippedFile->Release(); + //if (pISD) pISD->Release(); + CoUninitialize(); + } +} \ No newline at end of file -- 2.45.2