摘要:当Java桌面程序开发完成做产品的时候,面对未知的安装环境,通常是编写一些预安装检测脚本/程序,让程序傻瓜化安装以便减少分发出去的产品带来

的未知工作量(安装答疑,操作系统问题引起安装失败等),当然你也可以把安装过程中出现的问题写入文档手册。本文写作的背景是

1.不想让客户知道产品是用Java编写的

2. 客户懒的帮助文档都不想看

  截至本文编写的时候,JDK官方最新版本为jdk 8u144,本文测试环境在虚拟机Windows XP,使用的版本为jdk-8u144-windows-i586.exe

Java 安装是使用 Microsoft Window Installer (MSI) 2.0 技术构建的。MSI 包含对静默或无人参与安装的内置支持。

  从Google搜索"java silent install"总结出了一些安装参数  

 /lang=<语言代码> 安装特定语言包

  支持的语言包如下

语言   语言代码
英语 (en) 1033
法语 (fr) 1036            
德语 (de) 1031
意大利语 (it) 1040
日语 (ja) 1041
韩语 (ko) 1042
西班牙语 (es) 1034
瑞典语 (sv) 1053
简体中文 (zh) 2052
繁体中文 (zh_TW) 1028

经过笔者实测,设置语言代码为1041,即日语。安装命令:

jdk-8u144-windows-i586.exe /lang=1041

安装包界面如下

做对日外包的同学应该习惯于看到这个界面。这样就以日语语言环境安装JDK了。

WEB_JAVA = 1|0 Java浏览器支持 1启用 0禁用
IEXPLORER = 1|0 IE浏览器支持 1启用 0 禁用(jdk1.8命令行实测无效)
SPONSORS= 1|0 绕过赞助商,如浏览器插件,实测发现完整安装了JDK
WEB_JAVA_SECURITY_LEVEL = VH|H|M|L 浏览器中运行的未签名 Java 应用程序的安全级别 非常高|高|中|低
AUTO_UPDATE= 1|0 JDK自动检测更新 1启用 0禁用
NOSTARTMENU= 1|0 创建开始菜单 1禁用 0 启动

当然你也可以安装后在控制面板找到Java设置安全级别

以上为JDK 7u10 release版本起的安装特性,Java早期的时候有一些应用就是通过Web Applet方式发布的,笔者工作早些年的时候一

家做ERP的单位他就是通过浏览器方式发布项目的,现今已经很少看到这样的企业应用,鲜见一些社区里的Demo程序会有Web Applet的示例程序。

/L install.log 记录安装日志

常规情况下Oracle公司已经帮我考虑到安装过程中遇到的问题,并且他也有自己的解决方法,这些都封装在安装包里,当然有时候如果需要查看java安装过程的操作,

或者在特殊情况下(静默安装)他都做了什么,或者是为了排错,我们需要记录日志。/L参数便应运而生。

/s 静默安装

此参数不需要赋值,直接带入安装命令行即可,启动后将在后台默默的安装直至安装完成结束。

ADDLOCAL = [[ToolsFeature],[SourceFeature],[PublicjreFeature]] 选择附加组件包各个参数可独立使用也可以组合使用
ADDLOCAL = ["ToolsFeature,SourceFeature,PublicjreFeature"] 安装开发工具/源代码/JRE
ADDLOCAL = ["ToolsFeature,SourceFeature"] 安装开发工具和源代码

除了以上命令还有很多配置方式或者参数,笔者没有一一测试,笔者最终的安装命令如下:

jdk-8u144-windows-i586.exe /lang= /s /L c:\jdk-install.log INSTALLDIR=D:\develop\Java\jdk1..0_144 ADDLOCAL="ToolsFeature,SourceFeature,,PublicjreFeature" WEB_JAVA= AUTO_UPDATE= NOSTARTMENU= /INSTALLDIRPUBJRE=D:\develop\Java\jre1..0_144

命令解释:笔者选择了简体中文静默安装,记录了安装日志到c:\jdk-install.log,JDK安装目录c:\\embededJDK1.8,另外还安装了开发工具和源代码组件包、jre,禁用浏览Java插件,关闭JAVA自动更新,屏蔽了java开始菜单的创建。

安装后效果图如下:

从IE浏览器“工具”--"管理加载项"找不到java浏览器插件

开始菜单也没了Java的踪迹

windows注册表启动项也没有java的影子

当然文字不是到这里就结束了。

本文最终目的是要发送福利,在下面,笔者用C#写了简单的程序来静默安装JDK。

首先从java官方获得JDK的x86和x64版本分别改名为sdk-x86.bin和sdk-x64.bin

下面奉上代码(考虑客户端实际安装环境,为兼容Windows XP SP及更高版本,代码采用C#2.0 .NET Framework 2.0)

using System;
using System.IO;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Threading; namespace Starter
{
class Enterance
{
static string JVM_Pattern = string.Empty;
static bool hasFoundJVM = false;
static string Target_JDK_FIlE = string.Empty;
public static void Main(string[] args)
{ Console.WriteLine("按任意键开始安装xxx综合平台...");
Console.ReadKey(true);
Console.Clear(); if(isFileMissed())
{
Console.WriteLine("安装文件丢失请联系技术人员");
}else{
doPreInstallCheck();
if(hasFoundJVM){
installJVM(Target_JDK_FIlE);
}
} Console.ReadKey(true);
} /// <summary>
/// 判断主安装程序是否丢失
/// </summary>
/// <returns></returns>
static bool isFileMissed()
{
return !File.Exists("setup.exe");
} static String getArch()
{
return System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE",
EnvironmentVariableTarget.Machine);
} /// <summary>
/// 安装预检测
/// </summary>
static void doPreInstallCheck(){
String arch =getArch();
Architecture type= (Architecture)Enum.Parse(typeof(Architecture),arch);
switch(type){
case Architecture.AMD64:
case Architecture.IA64:
case Architecture.x64:
Console.WriteLine("发现{0}",EnumUtil.GetEnumDescription(type));
JVM_Pattern = "sdk.*x64.*";
break;
case Architecture.x86:
Console.WriteLine("发现{0}",EnumUtil.GetEnumDescription(type));
JVM_Pattern = "sdk.*x86.*";
break;
}
string []files = Directory.GetFiles(Environment.CurrentDirectory,"sdk-*.bin");
Action<string> action = new Action<string>(matchJVM);
Array.ForEach(files, action);
} private static void matchJVM(string jdkfile)
{
FileInfo fileInfo = new FileInfo(jdkfile);
bool isMatched = Regex.IsMatch(fileInfo.Name,JVM_Pattern);
if(isMatched) {
hasFoundJVM = true;
Target_JDK_FIlE = jdkfile;
}
if(Debugger.IsAttached)
Console.WriteLine("{0}与当前操作系统匹配的JVM:{1}",fileInfo.Name,isMatched);
} /// <summary>
/// 安装JVM
/// </summary>
/// <param name="fileName">JDK文件名</param>
static void installJVM(String fileName)
{
Console.WriteLine("即将安装程序,等待时间取决你电脑的性能");
//https://stackoverflow.com/questions/3360555/how-to-pass-parameters-to-threadstart-method-in-thread
Thread thread =new Thread(new ParameterizedThreadStart(DoSlientInstall));
thread.Start(fileName);
Thread.Sleep();//等待安装进程启动
FileInfo fileInfo = new FileInfo(fileName);
InstallState state =new InstallState();
state.processName =fileInfo.Name; Timer timer =new Timer(waitForProcessExitCallBack,state,,);
state.tmr = timer; } public static void waitForProcessExitCallBack(object target){
InstallState state = target as InstallState;
Timer timer = state.tmr;
Process []allProcceses = Process.GetProcesses();
bool isJDKProcExit = true;
foreach(Process proc in allProcceses)
{
string procName = String.Format("{0}",proc.ProcessName);
if(Debugger.IsAttached)
Console.WriteLine("{0},{1}, {2}",procName,state.processName,procName.Equals(state.processName));
if(procName.Equals(state.processName)){
isJDKProcExit = false;
}
}
if(isJDKProcExit){
Console.WriteLine("\r\n安装所需软件使用时间:{0}秒",state.counter);
timer.Dispose();
}else{
Console.Write(state.delims);
state.counter++;
//Thread.Sleep(1000);
//
//timer.Change(1000,1000);
//timer.Dispose();
} } //https://stackoverflow.com/questions/24918768/progress-bar-in-console-application //https://stackoverflow.com/questions/12354883/how-do-i-gracefully-stop-a-system-threading-timer
static void DoSlientInstall(object fileName)
{
Console.WriteLine("安装进行中,请勿退出...");
ProcessStartInfo pStartInfo = new ProcessStartInfo();
pStartInfo.FileName = (String)fileName;
pStartInfo.Verb = "runas";
pStartInfo.Arguments = "/lang=2052 /s /L c:\\jdk-install.log INSTALLDIR=c:\\embededJDK1.8 ADDLOCAL=\"ToolsFeature,SourceFeature\" WEB_JAVA=0 AUTO_UPDATE=0 NOSTARTMENU=1";
pStartInfo.UseShellExecute = false;
System.Diagnostics.Process.Start(pStartInfo);
//https://stackoverflow.com/questions/6050478/how-do-i-create-edit-a-manifest-file
//System.Diagnostics.Process.Start((String)fileName,"/s");
}
}
//http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Threading/Timer.html
class InstallState{
/// <summary>
/// 时间计数器
/// </summary>
public int counter = ;
/// <summary>
/// 进程名
/// </summary>
public String processName;
/// <summary>
/// 分隔符
/// </summary>
public string delims="*"; public Timer tmr;
}
}
using System;
using System.ComponentModel;
using System.Reflection;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data; namespace Starter
{
/// <summary>
/// 操作系统架构枚举类
/// </summary>
//https://msdn.microsoft.com/en-us/library/aa384274.aspx
//https://ss64.com/nt/syntax-64bit.html
public enum Architecture{
[Description("64位操作系统")]
x64 =,
[Description("AMD 64位操作系统")]
AMD64=,
[Description("Intel64位操作系统")]
IA64=,
[Description("x86架构操作系统")]
x86=
}
class EnumUtil{
public static string GetEnumDescription(Enum enumValue)
{
string enumValueAsString = enumValue.ToString(); Type type = enumValue.GetType();
FieldInfo fieldInfo = type.GetField(enumValueAsString);
object[] attributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Length > )
{
DescriptionAttribute attribute = (DescriptionAttribute)attributes[];
return attribute.Description;
} return enumValueAsString;
}
}
}

安装效果图

参考资料

Installing With a Configuration File

Java 8 SE Documentation

How do I arrange a silent (unattended) Java installation?

Language IDs

Installing the JDK Silently

[原创]自定义参数静默方式安装JDK1.8的更多相关文章

  1. 静默方式安装10g数据库软件+升级patch+手工建库

    通常我们安装Oracle数据库软件,都是用OUI图形界面来完成的,但有些Unix/Linux系统中并未安装图形系统,也就无法使用图形界面来安装Oracle的产品了,对于这种场景,就只能采用静默方式来安 ...

  2. Linux上rpm方式安装JDK1.7

    说明: 1.Linux版本 CentOS6.5_x86 2.Java版本 JDK1.7 32位的rpm包,所以是以rpm方式安装的java 3.可以使用yum install java从yum源中安装 ...

  3. Ubuntu16.04 PPA方式安装JDK1.8

    一.删除OpenJDK:   sudo apt-get purge openjdk* 二.添加PPA: root@ubuntu:~# add-apt-repository ppa:webupd8tea ...

  4. 静默方式安装window oracle

    1. setup.exe -silent -responseFile "C:\app\software\WIN64_11204\RSP\db_install_window.rsp" ...

  5. suse下静默方式安装oracle(无图形界面)

    以 http://www.cnblogs.com/0201zcr/p/4728241.html 为主 以 http://www.cnblogs.com/jyzhao/p/5001782.html 为参 ...

  6. Oracle 11g R2创建数据库之DBCA静默方式

    通常创建Oracle数据库都是通过DBCA(Database Configuration Assistant)工具完成的,DBCA工具可以通过两种方式完成建库任务,即图形界面方式和静默命令行方式.既然 ...

  7. 02-01官网静默模式安装WebLogic

    参考连接:https://docs.oracle.com/middleware/11119/wls/WLSIG/silent.htm#CIHCAHGC 以静默模式运行安装程序 本章介绍如何以静默方式运 ...

  8. CentOS6.5x64采用静默模式安装64位oracle11g

    1.下载oracle11g64位版本的源文件,并上传到Linux服务器,下载地址自行百度,若实在找不到请留言. 2.Package安装检查安装: 通过yum工具直接安装: yum -y install ...

  9. CentOS 6 自定义单实例 二进制方式 安装mariadb-5.5.59

    系统平台: CentOS release 6.9 (Final) 内核 2.6.32-696.el6.x86_64 1.去官网下载适合的二进制包 http://mariadb.org/ mariadb ...

随机推荐

  1. (整理) .NET IIS性能优化

    本文收集了部分性能优化的方式,缓存.压缩.线程池调整等等,仅供参考. 1 .NET 程序中的调整 程序Sqlhelper中使用缓存 使用JSON序列化器(Jil)取代Json.NET 2 .NET 程 ...

  2. Specify 的含义 ------ 转载

    specify block用来描述从源点(source:input/inout port)到终点(destination:output/inout port)的路径延时(path delay),由sp ...

  3. js小技巧总结

    js小技巧总结 1.Array.includes条件判断 function test(fruit) { const redFruits = ["apple", "stra ...

  4. HTTP 请求头中的 Remote_Addr,X-Forwarded-For,X-Real-IP

    REMOTE_ADDR 表示发出请求的远程主机的 IP 地址,remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间 ...

  5. Git的操作理解

    1.本地和远程的关系相当于两个分支,是相互独立的. 2.本地分支属于本地仓库,一个仓库可以包含多个分支. 3.commit是为了告诉Git这次提交我改了哪些东西:       pull是将远程comm ...

  6. Linux gzip命令

    语法: gzip [-acdfhlLnNqrtvV][-S <压缩字尾字符串>][-<压缩效率>][--best/fast][文件...] 或 gzip [-acdfhlLnN ...

  7. 微信自带浏览器不支持form表单post提交方案解决

      微信自带浏览器form表单post提交,Java控制后台获取不到值得解决方案: 第一种:把post改成get请求,但是改后另一个问题来了就是,数据不安全了,连接上都能看到,导致数据会流失,Java ...

  8. 视频修复工具recover_mp4,视频录制一半掉电,如何查看已保存数据?

    在生产环境中,视频通常是一种重要的文件证据,但是,如果因为各种原因,导致视频在录制到一半过程中失败, 比如:监控到一半,录制设备掉电.虽然,掉电后的视频肯定找不到,但是,有时,长时间工作生产的视频通常 ...

  9. docker搭建gitlab服务器(Centos7)

    系统环境:CentOS Linux release 7.6.1810 (Core) git版本:gitlab/gitlab-ce 一.安装和启动docker 见HTTPRUNNERMANAGER安装部 ...

  10. Go语言编程读书笔记:Go channel(1)

    Channel是Go语言在语言级别提供的goroutine间的通信方式.我们可以用channel在两个或多个goroutine之间传递消息.channel是进程内的通信方式,因此通过channel传递 ...