Windows launcher: initial

This commit is contained in:
Dmitry Jemerov
2013-02-14 20:55:27 +01:00
parent 8df7b744e5
commit 72b1bfe395
14 changed files with 538 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
*.opensdf
*.suo
*.sdf
Debug
Release
ipch
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinLauncher", "WinLauncher\WinLauncher.vcxproj", "{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Debug|Win32.ActiveCfg = Debug|Win32
{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Debug|Win32.Build.0 = Debug|Win32
{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Release|Win32.ActiveCfg = Release|Win32
{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,3 @@
Debug
*.aps
*.vcxproj.user
@@ -0,0 +1,312 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stdafx.h"
#include "WinLauncher.h"
typedef JNIIMPORT jint (JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args);
HINSTANCE hInst; // current instance
char jvmPath[_MAX_PATH];
JavaVMOption* vmOptions = NULL;
int vmOptionCount = 0;
bool bServerJVM = false;
HMODULE hJVM = NULL;
JNI_createJavaVM pCreateJavaVM = NULL;
JavaVM* jvm = NULL;
JNIEnv* env = NULL;
bool IsValidJRE(char* path)
{
char dllPath[_MAX_PATH];
strcpy_s(dllPath, path);
strcat_s(dllPath, "\\bin\\client\\jvm.dll");
return GetFileAttributesA(dllPath) != INVALID_FILE_ATTRIBUTES;
}
bool FindValidJVM(char* path)
{
if (IsValidJRE(path))
{
strcpy_s(jvmPath, _MAX_PATH-1, path);
return true;
}
char jrePath[_MAX_PATH];
strcpy_s(jrePath, path);
if (jrePath[strlen(jrePath)-1] != '\\')
{
strcat_s(jrePath, "\\");
}
strcat_s(jrePath, _MAX_PATH-1, "jre");
if (IsValidJRE(jrePath))
{
strcpy_s(jvmPath, jrePath);
return true;
}
return false;
}
bool LocateJVM()
{
char envVarName[_MAX_PATH];
if (LoadStringA(hInst, IDS_JDK_ENV_VAR, envVarName, _MAX_PATH-1))
{
char envVarValue[_MAX_PATH];
if (GetEnvironmentVariableA(envVarName, envVarValue, _MAX_PATH-1))
{
if (FindValidJVM(envVarValue))
{
return true;
}
else
{
char buf[_MAX_PATH];
sprintf_s(buf, "The environment variable %s (with the value of %s) does not point to a valid JVM installation",
envVarValue, jvmPath);
MessageBoxA(NULL, buf, "Error Launching IntelliJ Platform", MB_OK);
return false;
}
}
}
return false;
}
void TrimLine(char* line)
{
char *p = line + strlen(line) - 1;
if (p >= line && *p == '\n')
{
*p-- = '\0';
}
while(p >= line && (*p == ' ' || *p == '\t'))
{
*p-- = 0;
}
}
bool LoadVMOptionsFile(const TCHAR* path, std::vector<std::string>& vmOptionLines)
{
FILE *f = _tfopen(path, _T("rt"));
if (!f) return false;
char line[_MAX_PATH];
while(fgets(line, _MAX_PATH-1, f))
{
TrimLine(line);
if (strcmp(line, "-server") == 0)
{
bServerJVM = true;
}
else if (strlen(line) > 0)
{
vmOptionLines.push_back(line);
}
}
fclose(f);
return true;
}
std::string FindToolsJar()
{
std::string toolsJarPath = jvmPath;
size_t lastSlash = toolsJarPath.rfind('\\');
if (lastSlash != std::string::npos)
{
toolsJarPath = toolsJarPath.substr(0, lastSlash+1);
toolsJarPath += "lib\\tools.jar";
if (GetFileAttributesA(toolsJarPath.c_str()) != INVALID_FILE_ATTRIBUTES)
{
return toolsJarPath;
}
}
return "";
}
std::string BuildClassPath()
{
char libDir[_MAX_PATH];
GetCurrentDirectoryA(_MAX_PATH-1, libDir);
char* lastSlash = strrchr(libDir, '\\');
strcpy(lastSlash+1, "lib\\");
if (GetFileAttributesA(libDir) == INVALID_FILE_ATTRIBUTES)
{
return "";
}
char classpathLibs[_MAX_PATH];
std::string result;
LoadStringA(hInst, IDS_CLASSPATH_LIBS, classpathLibs, _MAX_PATH-1);
char *pJarName = classpathLibs;
while(pJarName)
{
char *pNextJarName = strchr(pJarName, ';');
if (pNextJarName)
{
*pNextJarName++ = '\0';
}
if (result.size() > 0)
{
result += ";";
}
result += libDir;
result += pJarName;
pJarName = pNextJarName;
}
std::string toolsJar = FindToolsJar();
if (toolsJar.size() > 0)
{
result += ";";
result += toolsJar;
}
return result;
}
bool LoadVMOptions()
{
TCHAR optionsFileName[_MAX_PATH];
if (LoadString(hInst, IDS_VM_OPTIONS_PATH, optionsFileName, _MAX_PATH-1))
{
TCHAR optionsFileNameExpanded[_MAX_PATH];
ExpandEnvironmentStrings(optionsFileName, optionsFileNameExpanded, _MAX_PATH-1);
std::vector<std::string> vmOptionLines;
if (LoadVMOptionsFile(optionsFileNameExpanded, vmOptionLines))
{
std::string classPath = BuildClassPath();
if (classPath.size() == 0) return false;
std::string classPathArg("-Djava.class.path=");
classPathArg += classPath;
vmOptionLines.push_back(classPathArg);
vmOptionCount = vmOptionLines.size();
vmOptions = (JavaVMOption*) malloc(vmOptionCount * sizeof(JavaVMOption));
for(int i=0; i<vmOptionLines.size(); i++)
{
vmOptions[i].optionString = _strdup(vmOptionLines[i].c_str());
vmOptions[i].extraInfo = 0;
}
return true;
}
}
MessageBox(NULL, _T("Cannot find VM options file"), _T("Error launching IntelliJ Platform"), MB_OK);
return false;
}
bool LoadJVMLibrary()
{
std::string dllName(jvmPath);
if (bServerJVM)
{
dllName += "\\bin\\server\\jvm.dll";
}
else
{
dllName += "\\bin\\client\\jvm.dll";
}
hJVM = LoadLibraryA(dllName.c_str());
if (hJVM)
{
pCreateJavaVM = (JNI_createJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM");
}
if (!pCreateJavaVM)
{
TCHAR buf[_MAX_PATH];
_stprintf_s(buf, _MAX_PATH-1, _T("Failed to load JVM DLL %s"), dllName);
MessageBox(NULL, buf, _T("Error Launching IntelliJ Platform"), MB_OK);
return false;
}
return true;
}
bool CreateJVM()
{
JavaVMInitArgs initArgs;
initArgs.version = JNI_VERSION_1_2;
initArgs.options = vmOptions;
initArgs.nOptions = vmOptionCount;
initArgs.ignoreUnrecognized = JNI_FALSE;
int result = pCreateJavaVM(&jvm, &env, &initArgs);
for(int i=0; i<vmOptionCount; i++)
{
free(vmOptions[i].optionString);
}
free(vmOptions);
vmOptions = NULL;
if (result != JNI_OK)
{
MessageBox(NULL, _T("Failed to create JVM"), _T("Error launching IntelliJ Platform"), MB_OK);
}
return result == JNI_OK;
}
bool RunMainClass()
{
char mainClassName[_MAX_PATH];
if (!LoadStringA(hInst, IDS_MAIN_CLASS, mainClassName, _MAX_PATH-1)) return false;
jclass mainClass = env->FindClass(mainClassName);
if (!mainClass)
{
char buf[_MAX_PATH];
sprintf(buf, "Could not find main class %s", mainClassName);
MessageBoxA(NULL, buf, "Error Launching IntelliJ Platform", MB_OK);
return false;
}
jclass stringClass = env->FindClass("java/lang/String");
jobjectArray args = env->NewObjectArray(0, stringClass, NULL);
jmethodID mainMethod = env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
if (!mainClass)
{
MessageBoxA(NULL, "Could not find main method", "Error Launching IntelliJ Platform", MB_OK);
return false;
}
env->CallStaticVoidMethod(mainClass, mainMethod, args);
return true;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
hInst = hInstance;
if (!LocateJVM()) return 1;
if (!LoadVMOptions()) return 1;
if (!LoadJVMLibrary()) return 1;
if (!CreateJVM()) return 1;
if (!RunMainClass()) return 1;
jvm->DestroyJavaVM();
return 0;
}
@@ -0,0 +1,3 @@
#pragma once
#include "resource.h"
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.
@@ -0,0 +1,100 @@
<?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>{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>WinLauncher</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" />
</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" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>C:\Java\jdk1.6.0_37\include;C:\Java\jdk1.6.0_37\include\win32;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>C:\Java\jdk1.6.0_37\include;C:\Java\jdk1.6.0_37\include\win32;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
<None Include="small.ico" />
<None Include="WinLauncher.ico" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="WinLauncher.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="WinLauncher.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WinLauncher.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,53 @@
<?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>
<None Include="ReadMe.txt" />
<None Include="small.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="WinLauncher.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WinLauncher.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WinLauncher.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WinLauncher.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// WinLauncher.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
+25
View File
@@ -0,0 +1,25 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <jni.h>
#include <vector>
// TODO: reference additional headers your program requires here
@@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>