// Здесь нельзя использовать общие модули!

&НаКлиенте
Процедура ЗапуститьНовоеПриложение(Знач ОбычноеПриложение = Истина)
	
	#Если ВебКлиент Тогда
		Сообщить("Команда недоступна веб клиенте");
	#Иначе
		Если ТекущийПользователь Тогда
			НастроитьПользователяНаСервере();
		КонецЕсли; 
		ПараметрыЗапуска = "";
		СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
		ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE";
		ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
		Если ОбычноеПриложение Тогда
			ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication";
		Иначе
			ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication";
		КонецЕсли; 
		ПараметрыЗапуска = ПараметрыЗапуска + " /Debug";
		ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """";
		ИспользуемоеИмяФайла = ПолучитьИспользуемоеИмяФайла(ИмяКомпьютера());
		Если ЗначениеЗаполнено(ИспользуемоеИмяФайла) Тогда
			ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ИспользуемоеИмяФайла + """";
		КонецЕсли; 
		Если ТекущийПользователь Тогда
			ПараметрыЗапуска = ПараметрыЗапуска + " /N""" + ИмяПользователя() + """";
			Если ЗначениеЗаполнено(ПарольТекущегоПользователя) Тогда
				ПараметрыЗапуска = ПараметрыЗапуска + " /P""" + ПарольТекущегоПользователя + """";
			КонецЕсли; 
		КонецЕсли; 
		
		Если ПодключитьОтладчик Тогда
			Попытка
				ВК = Новый ("AddIn.ирОбщая.AddIn");
			Исключение
				// https://partners.v8.1c.ru/forum/t/1265923/m/1555146
				//АдресКомпоненты = ПолучитьАдресВнешнейКомпоненты();
				//УстановитьВнешнююКомпоненту(АдресКомпоненты); // Выдает предупреждение пользователю каждый раз
				//
				Это64битныйПроцесс = Это64битныйПроцесс();
				ДвоичныеДанные = ПолучитьДвоичныеДанныеВК(Это64битныйПроцесс);
				АдресКомпоненты = ПолучитьИмяВременногоФайла("dll");
				ДвоичныеДанные.Записать(АдресКомпоненты);
				
				Результат = ПодключитьВнешнююКомпоненту(АдресКомпоненты, "ирОбщая", ТипВнешнейКомпоненты.Native);
				Если Не Результат Тогда
					ВызватьИсключение "Не удалось подключить внешнюю компоненту Общая. Она требуется для флажка ""Подключить отладчик"""; 
				КонецЕсли; 
				ВК = Новый ("AddIn.ирОбщая.AddIn");
			КонецПопытки; 
			ИдентификаторПроцессаОС = ВК.PID();
			ПараметрыЗапускаДляОтладки = ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчику(ИдентификаторПроцессаОС);
			ПараметрыЗапуска = ПараметрыЗапуска + " " + ПараметрыЗапускаДляОтладки;
		КонецЕсли; 
		
		ЗапуститьПриложение(КаталогПрограммы() + "1cv8.exe " + ПараметрыЗапуска);
		Если ЗакрытьФорму Тогда
			Закрыть();
		КонецЕсли; 
		Если ЗавершитьСеанс Тогда
			ЗавершитьРаботуСистемы();
		КонецЕсли; 
	#КонецЕсли

КонецПроцедуры

Процедура НастроитьПользователяНаСервере()
	
	ИмяПользователя = ИмяПользователя();
	Если Элементы.ВключитьКомпактныйВариантФорм.Доступность И ВключитьКомпактныйВариантФорм Тогда
		НастройкиКлиентскогоПриложения = ХранилищеСистемныхНастроек.Загрузить("Общее/НастройкиКлиентскогоПриложения",,, ИмяПользователя);
		Если НастройкиКлиентскогоПриложения = Неопределено Тогда
			НастройкиКлиентскогоПриложения = Новый НастройкиКлиентскогоПриложения;
		КонецЕсли;
		НастройкиКлиентскогоПриложения.ВариантМасштабаФормКлиентскогоПриложения = Вычислить("ВариантМасштабаФормКлиентскогоПриложения.Компактный");
		ХранилищеСистемныхНастроек.Сохранить("Общее/НастройкиКлиентскогоПриложения", "", НастройкиКлиентскогоПриложения, , ИмяПользователя);
	КонецЕсли; 
	Если Элементы.ОтключитьЗащитуОтОпасныхДействий.Доступность И ОтключитьЗащитуОтОпасныхДействий Тогда
		Пользователь = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя);
		Если Пользователь <> Неопределено Тогда
			Пользователь.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь;
			Пользователь.Записать();
		КонецЕсли; 
	КонецЕсли;
	
КонецПроцедуры

Функция ДоступнаЗащитаОтОпасныхДействий() Экспорт 
	
	Перем ТекущийПользователь;
	ЗащитаОтОпасныхДействийЛ = Неопределено;
	Попытка
		ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
		ЗащитаОтОпасныхДействийЛ = ТекущийПользователь.ЗащитаОтОпасныхДействий;
	Исключение
	КонецПопытки;
	Возврат ЗащитаОтОпасныхДействийЛ <> Неопределено;
	
КонецФункции

#Если Не ВебКлиент Тогда
&НаКлиенте
// р5яф67оыйи
Функция ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчику(Знач ИдентификаторПроцессаОС) Экспорт 
	
	ПараметрыЗапускаДляОтладки = "";
	ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'");
	КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine;
	ВычислительРегулярныхВыражений = Новый COMОбъект("VBScript.RegExp");
	ВычислительРегулярныхВыражений.IgnoreCase = Истина;
	ВычислительРегулярныхВыражений.Global = Истина;
	ВычислительРегулярныхВыражений.Pattern = "(/DebuggerUrl\s*.+?)( /|$)";
	Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
	Если Вхождения.Count > 0 Тогда
		ПараметрыЗапускаДляОтладки = Вхождения.Item(Вхождения.Count - 1).SubMatches(0);
	КонецЕсли; 
	ВычислительРегулярныхВыражений.Pattern = "(/Debug\s+.+?)( /|$)";
	Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
	Если Вхождения.Count > 0 Тогда
		СтрокаОтладчика = Вхождения.Item(Вхождения.Count - 1).SubMatches(0);
	Иначе
		СтрокаОтладчика = "/Debug";
	КонецЕсли;
	ПараметрыЗапускаДляОтладки = ПараметрыЗапускаДляОтладки + " " + СтрокаОтладчика;
	Возврат ПараметрыЗапускаДляОтладки;


КонецФункции
#КонецЕсли 

Функция ОбработкаОбъект()
	
	Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
		ОбработкаОбъект = ЭтаФорма.РеквизитФормыВЗначение("Объект");
	Иначе
		ОбработкаОбъект = Вычислить("ЭтотОбъект");
	КонецЕсли; 
	Возврат ОбработкаОбъект;

КонецФункции

Функция ПолучитьДвоичныеДанныеВК(x64 = Ложь)
	ОбработкаОбъект = ОбработкаОбъект();
	ИмяМакета = "ВК";
	Если x64 Тогда
		ИмяМакета = ИмяМакета + "64";
	Иначе
		ИмяМакета = ИмяМакета + "32";
	КонецЕсли; 
	Возврат ОбработкаОбъект.ПолучитьМакет(ИмяМакета);
КонецФункции

Функция ПолучитьАдресВнешнейКомпоненты()
	ОбработкаОбъект = ОбработкаОбъект();
	#Если Сервер И Не Сервер Тогда
	    ОбработкаОбъект = Обработки.ирПортативный.Создать();
	#КонецЕсли
	ОбъектМД = ОбработкаОбъект.Метаданные();
	// Антибаг платформы 8.2.19, исправлен в 8.3, ПолноеИмя() для дочерних метаданных внешней обработки возвращало обрезанное имя
	Адрес = ОбъектМД.ПолноеИмя() + ".Макет." + ОбъектМД.Макеты.ВК.Имя;
	Возврат Адрес;
КонецФункции

Функция ПолучитьИспользуемоеИмяФайла(ИмяКомпьютера)
	
	ОбработкаОбъект = ОбработкаОбъект();
	Попытка
		ИспользуемоеИмяФайла = ОбработкаОбъект.ИспользуемоеИмяФайла;
	Исключение
	КонецПопытки; 
	Возврат ИспользуемоеИмяФайла;
	
КонецФункции

&НаКлиенте
Функция Это64битныйПроцесс() Экспорт
	
	СисИнфо = Новый СистемнаяИнформация;
	Результат = СисИнфо.ТипПлатформы = ТипПлатформы.Windows_x86_64;
	Возврат Результат;
	
КонецФункции

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	//ЭтаФорма.ПодключитьОтладчик = Истина;
	ЭтаФорма.ЗакрытьФорму = Истина;
	ЭтаФорма.ТекущийПользователь = Истина;
	ЭтаФорма.ОтключитьЗащитуОтОпасныхДействий = Истина;
	//ЭтаФорма.ВключитьКомпактныйВариантФорм = Истина;
	Если Метаданные.Обработки.Найти("ирПлатформа") = Неопределено Тогда
		Элементы.Текст.Заголовок = "Работа портативных инструментов разработчика в режиме управляемого приложения не поддерживается";
		Элементы.ЗапуститьТолстыйКлиент.Доступность = Ложь;
	Иначе
		Элементы.Текст.Заголовок = "Работа инструмента в режиме тонкого клиента не поддерживается";
	КонецЕсли;
	СисИнфо = Новый СистемнаяИнформация;
	Элементы.ВключитьКомпактныйВариантФорм.Доступность = Найти(СисИнфо.ВерсияПриложения, "8.2") <> 1;
	Элементы.ОтключитьЗащитуОтОпасныхДействий.Доступность = ДоступнаЗащитаОтОпасныхДействий();
	ОбновитьДоступность(ЭтаФорма);
	
КонецПроцедуры

&НаКлиенте
Процедура ЗапуститьОбычноеПриложение(Команда)
	
	ЗапуститьНовоеПриложение(Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ЗапуститьТолстыйКлиент(Команда)
	
	ЗапуститьНовоеПриложение(Ложь);
		
КонецПроцедуры

&НаКлиенте
Процедура ТекущийПользовательПриИзменении(Элемент)
	
	ОбновитьДоступность(ЭтаФорма);
	
КонецПроцедуры

// Реальная директива здесь - &НаКлиентеНаСервереБезКонтекста, остальные директивы нужны для контекстной подсказки по параметру ЭтаФорма
#Если Сервер И Не Сервер Тогда
	&НаСервере
#Иначе
	&НаКлиентеНаСервереБезКонтекста
#КонецЕсли
Процедура ОбновитьДоступность(ЭтаФорма)
	
	ЭтаФорма.Элементы.ГруппаПараметрыПользователя.Доступность = ЭтаФорма.ТекущийПользователь;
	
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
	
	ОбновитьДоступность(ЭтаФорма);
	
КонецПроцедуры

