| caseyryan |
26.07.2017 06:26 |
.air файл это просто архив. При установке он распаковывается в систему и все его содержимое будет в папке с установленной программой, но загвоздка в том, что File.applicationDirectory - только для чтения, то есть записать туда что-то средствами самой программы нельзя, и о прикладывании какого-то swf апдейтера можно забыть. Есть хак для обхода этого запрета, но, насколько удалось выяснить, работает это только в винде, и то до 10ки.
Могу предложить такое решение: AIR программа скачивает с сервера нужный для обновления swf файл, кладет его во временную директорию, а чтобы скопировать его оттуда в папку с установкой, вызывает штатный терминал / командную строку системы и с помощью нее копирует файл, после чего перезапускается
Пример того как работать с командной строкой в винде (Это файл из моего рабочего проекта, так что есть кое что лишнее). Там есть методы назначения и чтения переменных среды, вот в них и происходит работа с командной строкой. Для MAC OS реализации нет за ненадобностью
Код AS3:
package ru.ppro.plagiatorpro.model {
import com.hurlant.util.ArrayUtil;
import flash.desktop.NativeApplication;
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
import flash.events.ProgressEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.system.Capabilities;
import flash.utils.ByteArray;
import flash.utils.IDataInput;
import flash.utils.getTimer;
import ru.ppro.plagiatorpro.utils.arrayToVector;
import ru.ppro.plagiatorpro.view.modalwindows.ModalWindowsManager;
public class OSTools {
public static const DOS_CYRILLIC:String = "cp866";
public function OSTools() {
}
/**
* Задает переменную среды в системе
* @param environmentVarName
* @param value
*/
public static function setEnvironmentVariable(environmentVarName:String, value:String):void {
if (isWindows()) {
var envVarExecutable:File = null;
envVarExecutable = File.applicationStorageDirectory.resolvePath("envvarset.cmd");
var batContents:String = "setx " + environmentVarName + " \"" + value.replace("\"", "") + "\"";
var fileStream: FileStream = new FileStream();
fileStream.open(envVarExecutable, FileMode.WRITE);
fileStream.writeMultiByte(batContents, DOS_CYRILLIC);
fileStream.close();
var envVarSetter:NativeProcess = new NativeProcess();
var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
startupInfo.executable = envVarExecutable;
try {
envVarSetter.start(startupInfo);
} catch (err:Error) {
killFile(envVarExecutable);
ModalWindowsManager.instance.createWarningWindow(err.message);
}
}
}
public static function restartApplication():void {
var extenstion: String = "";
if (isWindows()) {
extenstion = ".exe";
} else if (isMacOS()) {
extenstion = ".app"
} else {
return;
}
try {
var appXML: XML = NativeApplication.nativeApplication.applicationDescriptor;
var ns: Namespace = appXML.namespace();
var fileName: String = appXML.ns::filename + extenstion;
// экзешник для запуска приложения
var appFile:File = File.applicationDirectory.resolvePath(fileName);
var appNSPI:NativeProcessStartupInfo = new NativeProcessStartupInfo();
appNSPI.executable = appFile;
var appNP:NativeProcess = new NativeProcess();
appNP.start(appNSPI);
NativeApplication.nativeApplication.exit();
} catch (error:Error) {
SettingsManager.log("----- ОШИБКА ПЕРЕЗАПУСКА -----");
SettingsManager.log(error.getStackTrace());
SettingsManager.log(appFile.nativePath);
SettingsManager.log("Native Process Support: " + NativeProcess.isSupported);
SettingsManager.log("\n OS: " + Capabilities.manufacturer);
ModalWindowsManager.instance.createWarningWindow(
"Что-то пошло не так во время перезапуска программы! "
+ "Лог сохранен на рабочем столе"
);
}
}
private static function isWindows():Boolean {
return Capabilities.manufacturer.toLowerCase().indexOf("windows") > -1;
}
private static function isMacOS():Boolean {
return Capabilities.manufacturer.toLowerCase().indexOf("mac") > -1;
}
/**
* Запрашивает у операционной системы значение переменной среды
* @param environmentVarName имя переменной, которую нужно получить
* @param onValueCallback метод с одним параметром типа String, в который будет передано
* значение переенной, либо null
*/
public static function getEnvirotnmentVariableValue(environmentVarName:String, onValueCallback:Function):void {
var envVarExecutable:File = null;
if (isWindows()) {
//trace("это винда");
envVarExecutable = File.applicationStorageDirectory.resolvePath("envvar.cmd");
var batContents:String = "echo %" + environmentVarName + "%";
var fileStream: FileStream = new FileStream();
fileStream.open(envVarExecutable, FileMode.WRITE);
fileStream.writeMultiByte(batContents, DOS_CYRILLIC);
fileStream.close();
var envVarGetter:NativeProcess = new NativeProcess();
envVarGetter.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, function(e:ProgressEvent):void {
// ошибка
var standartOutput:IDataInput = (e.target as NativeProcess).standardError;
var error:String = standartOutput.readMultiByte(standartOutput.bytesAvailable, DOS_CYRILLIC);
ModalWindowsManager.instance.createWarningWindow("Произошла ошибка\nДанные записаны в log файл");
SettingsManager.log(error);
onValueCallback(null);
killFile(envVarExecutable);
});
envVarGetter.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, function(e:ProgressEvent):void {
var standartOutput: IDataInput = (e.target as NativeProcess).standardOutput;
var output:String = standartOutput.readMultiByte(standartOutput.bytesAvailable, DOS_CYRILLIC);
var presplit:Array = output.split("\n");
if (presplit.length > 2) {
var varValue:String = presplit[2];
onValueCallback(varValue.replace(/[\r\n]+/g, ""));
killFile(envVarExecutable);
} else {
onValueCallback(null);
killFile(envVarExecutable);
}
});
var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
startupInfo.executable = envVarExecutable;
try {
envVarGetter.start(startupInfo);
} catch (err:Error) {
onValueCallback(null);
killFile(envVarExecutable);
ModalWindowsManager.instance.createWarningWindow(err.message);
}
} else {
ModalWindowsManager.instance.createWarningWindow("Эта фича пока работает только в винде");
onValueCallback(null);
killFile(envVarExecutable);
}
}
/**
* Запускает внешнее приложение с указанными аргументами
* @param applicationExecutablePath
* @param ...args
*/
static public function startExternalApplication(applicationExecutablePath:String, ...args):void {
try {
var executable:File = new File(applicationExecutablePath);
var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
startupInfo.executable = executable;
startupInfo.arguments = new Vector.<String>();
for (var i:int = 0; i < args.length; i++) {
startupInfo.arguments.push(args[i]);
}
var nativeProcess:NativeProcess = new NativeProcess();
nativeProcess.start(startupInfo);
} catch (err:Error) {
ModalWindowsManager.instance.createWarningWindow("Не удалось запустить внешнее приложение, смотрите лог файл");
SettingsManager.log(">>> Ошибка запуска внешнего приложения >>>")
SettingsManager.log(err.message);
SettingsManager.log("<<< Ошибка запуска внешнего приложения <<<")
}
}
private static function killFile(file:File):void {
if (file && file.exists) {
file.deleteFile();
}
}
}
}
п.с. Все это будет работать только если в xml дескрипторе казать профиль extendedDesktop и собрать приложение в EXE
Цитата:
<supportedProfiles>extendedDesktop</supportedProfiles>
|
|