Эту статью я сначала написал в свой блог, чтобы потом опять не искать и не вспоминать, но поскольку блог никто не читает, то этой информацией захотелось поделиться со всеми, вдруг кому пригодиться.
Во время работы над идеей сервиса по сбросу пароля в системах SAP R/3 возник вопрос — а как запустить SAP GUI с нужными параметрами из браузера? Поскольку в этой идее подразумевалось использование веб-сервиса, сначала отрабатывающего по запросу SOAP из SAP GUI и отправляющего письмо со ссылкой на веб-страницу со скриптом сброса пароля на начальный, а потом уже отображение пользователю сообщения об успешном сбросе пароля и отображение этого самого начального пароля, то хотелось, чтобы на этой странице была еще и ссылка на запуск SAP GUI. Причем, чтобы эта ссылка открывала нужную систему, да еще, желательно, сразу с заполненными полями логина и пароля: пользователю оставалось бы только дважды заполнить продуктивный пароль.
Запуск SAP Logon — для нашей цели был не интересен, а при запуске sapgui.exe невозможно было указать мандант и имя пользователя, зато можно было запустить систему не определенную в SAP Logon. С другой стороны, запуск SAP GUI с произвольными параметрами сервера был не особенно актуален: уж если мы решаем задачу сброса пароля пользователя, то скорее всего у него в SAP Logon уже есть нужная строка, с нужными ему настройками и не надо лезть со своими. Зато заданным требованиям удовлетворяла технология SAP GUI Shortcut и собственно программа sapshcut.exe, которая давала возможность запускать SAP GUI с использованием определенного «ярлыка».
Решение задачи в лоб: запуск sapshcut.exe непосредственно из браузера с помощью объекта ActiveX:
Решение плохое: во-первых, работает только в Internet Explorer, во-вторых, требует соответствующих настроек безопасности в браузере, которые в организации могут быть запрещены на доменном уровне, и даже если разрешены, то браузер выдает пользователю окно с пугающим предупреждением:
Решение №2 откопал в интернете: создание собственного веб-протокола. Позволяет запустить нужное нам приложение с помощью ссылки с указанием протокола, который мы сами регистрируем в Windows в реестре в разделе HKEY_CLASSES_ROOT. Поскольку у SAP GUI Shortcut в этом разделе есть свой подраздел, то можно туда добавить строковой параметр URL Protocol с пустым значением:
Данный протокол запускает sapgui.exe с параметром /SHORTCUT, что нам как бы и надо:
Ну или если мы хотим сделать вообще произвольный протокол (например, sapshcut), то зарегистрировать его можно с помощью следующего reg-файла:
Теперь, если мы на веб-странице сделаем ссылку с указанием протокола Sapgui.Shortcut.File подобным образом:
у нас должно отобразиться окно вида:
И вроде всё замечательно, но при нажатии на кнопку «Разрешить» видим:
Опа, браузер пробел превратил в %20. Ну и другие символы тоже будут закодированы в свой числовой код с символом процента. И самое неприятное, что тут ничего нельзя сделать на уровне браузера (тут всё сделано по стандарту) — браузер не любит подобные символы, а командный интерпретатор Windows не работает с такими закодированными значениями. И еще один минус — в качестве параметра передается вся строка, включая название протокола и даже двоеточие (sapgui.shortcut.file:). Причем, хотя тот же sapshcut.exe умеет отбрасывает всё что не является для него параметром (начинается с символа «-«, потом название, «=» и значение), т.е. строка вида «sapgui.shortcut.file: -system=SID» еще прокатит, то без пробела «sapgui.shortcut.file:-system=SID» уже не работает.
Получается, что, в принципе, есть два варианта использования URI-протокола:
Т.е. данный вариант тоже отбрасываем как негодный нам.
Тут я уже начал думать, что с идеей запускать SAP GUI с нужными параметрами из браузера придется распрощаться, но тут мне в голову пришла мысль о том, что в SAP Logon можно сделать ярлык и его можно скопировать на рабочий стол. Я пользовался таким способом когда-то, но до этого файл ярлыка специально не смотрел. И оказалось, что данный ярлык представляет из себя обычный текстовый файл с расширением .sap. И если его запустить в Windows — запустится SAP GUI с параметрами, которые и указаны в этом файле. «Бинго!»
Формат данного файла примерно следующий (еще может быть запускаемая транзакция при старте, но я её опустил):
Вроде бы всё, что необходимо: и идентификатор системы, и мандант, и имя пользователя и даже пароль. И даже дополнительные параметры: Title — заголовок окна, GuiSize — размер запущенного окна (во весь экран или нет) и Reuse — открывать ли обязательно новое окно или использовать уже открытое с этой же системой. Но сразу вылез нюанс — пароль в SAP Logon оказалось задать нельзя, строка была заблокирована. Оказалось, что это сделано из соображений безопасности: все ярлыки созданные в SAP Logon он хранит в файле sapshortcut.ini (рядом с saplogon.ini в профиле пользователя Windows) и там они хотя и зашифрованы, но не слишком сильно и при большом желании их можно раскодировать. Но можно и разрешить это с помощью изменения значения одного параметра в реестре (по умолчанию значение 0):
Это разблокирует для ввода поле «Пароль» на форме создания ярлыка в SAP Logon:
И при внесении в это поле пароля, он будет размещен в соответствующей строке
sapshortcut.ini, но вот при перетаскивании ярлыка на рабочий стол он там не появляется — зато можно его туда добавить вручную. Пароль зашифрован, для 111111 он будет следующего вида: PW_49B02219D1F6, для 222222 — PW_4AB3211AD2F5. Но нас больше интересует то, что этот пароль шифруется одним способом, не зависящим от конкретного ПК и, если мы будем сбрасывать пароль на начальный, то можно в этом поле использовать одно заранее известное значение. Ну а если мы захотим использовать произвольно созданный пароль — то придется понять алгоритм этого шифра. Но, судя по приведенным примерам, сделать это будет несложно. Кстати, в SAP GUI 7.40 это поле вообще пропало с формы, но файл с заполненным паролем он корректно воспринимает.
То есть получается, что в браузере достаточно щелкнуть по ссылке на файл с расширением .sap и с нужным форматом — и он предложит его открыть как файл типа SAP GUI Shortcut (естественно на ПК с установленным SAP GUI) и откроет нам окно SAP GUI с указанными параметрами (если пара SID и мандант есть в списке SAP Logon на этом ПК).
Но, понятно, что просто файлы никто заранее создавать и складировать на сайт не будет — их надо генерировать исходя из нужных параметров. Например, можно создать скрипт на PHP для генерации ярлыков (sapshcut.php):
Если не задавать имя пользователя и пароль, то получим следующее окно с запросов логина и пароля:
Если передать только логин — то поле логин будет заполнено, а поле пароль пустое. Если же мы передаем пользователю и логин и пароль, но у пользователя на ПК в реестре ключ EnablePassword в разделе [HKEY_CURRENT_USER\Software\SAP\SAPShortcut\Security] установлен в 0, то получим то же самое. И только если этот ключ установлен в 1 и мы передаем и имя и начальный пароль, то система сразу запросит дважды ввести новый постоянный пароль. Что и требовалось получить.
В итоге, имеем следующий набор рассмотренных вариантов как иллюстрация всего вышесказанного:
Мне подошел последний вариант. Но также можно вместо генерации ярлыков SAP использовать, например, генерацию CMD-файлов, которые также при открытии из браузера откроют вам окно SAP GUI. Ниже приведен пример (sapguicmd.php) прямого запуска SAP GUI с указанием полной строки подключения, без необходимости иметь настроенный SAP Logon:
Во время работы над идеей сервиса по сбросу пароля в системах SAP R/3 возник вопрос — а как запустить SAP GUI с нужными параметрами из браузера? Поскольку в этой идее подразумевалось использование веб-сервиса, сначала отрабатывающего по запросу SOAP из SAP GUI и отправляющего письмо со ссылкой на веб-страницу со скриптом сброса пароля на начальный, а потом уже отображение пользователю сообщения об успешном сбросе пароля и отображение этого самого начального пароля, то хотелось, чтобы на этой странице была еще и ссылка на запуск SAP GUI. Причем, чтобы эта ссылка открывала нужную систему, да еще, желательно, сразу с заполненными полями логина и пароля: пользователю оставалось бы только дважды заполнить продуктивный пароль.
Запуск SAP Logon — для нашей цели был не интересен, а при запуске sapgui.exe невозможно было указать мандант и имя пользователя, зато можно было запустить систему не определенную в SAP Logon. С другой стороны, запуск SAP GUI с произвольными параметрами сервера был не особенно актуален: уж если мы решаем задачу сброса пароля пользователя, то скорее всего у него в SAP Logon уже есть нужная строка, с нужными ему настройками и не надо лезть со своими. Зато заданным требованиям удовлетворяла технология SAP GUI Shortcut и собственно программа sapshcut.exe, которая давала возможность запускать SAP GUI с использованием определенного «ярлыка».
Решение задачи в лоб: запуск sapshcut.exe непосредственно из браузера с помощью объекта ActiveX:
function openSAPGui(sid, client, user, password) {
var shell = new ActiveXObject("WScript.Shell");
shell.run('sapshcut.exe -system="'+sid+'" -client='+client+' -user="'+user+'" -pw="'+password+'" -language=RU');
}
Решение плохое: во-первых, работает только в Internet Explorer, во-вторых, требует соответствующих настроек безопасности в браузере, которые в организации могут быть запрещены на доменном уровне, и даже если разрешены, то браузер выдает пользователю окно с пугающим предупреждением:
Решение №2 откопал в интернете: создание собственного веб-протокола. Позволяет запустить нужное нам приложение с помощью ссылки с указанием протокола, который мы сами регистрируем в Windows в реестре в разделе HKEY_CLASSES_ROOT. Поскольку у SAP GUI Shortcut в этом разделе есть свой подраздел, то можно туда добавить строковой параметр URL Protocol с пустым значением:
Данный протокол запускает sapgui.exe с параметром /SHORTCUT, что нам как бы и надо:
Ну или если мы хотим сделать вообще произвольный протокол (например, sapshcut), то зарегистрировать его можно с помощью следующего reg-файла:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\sapshcut]
@="sapshcut Handler"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\sapshcut\DefaultIcon]
@="sapshcut.exe"
[HKEY_CLASSES_ROOT\sapshcut\shell]
[HKEY_CLASSES_ROOT\sapshcut\shell\open]
[HKEY_CLASSES_ROOT\sapshcut\shell\open\command]
@="sapshcut.exe \"%1\""
Теперь, если мы на веб-странице сделаем ссылку с указанием протокола Sapgui.Shortcut.File подобным образом:
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>SID200</a>
у нас должно отобразиться окно вида:
И вроде всё замечательно, но при нажатии на кнопку «Разрешить» видим:
Опа, браузер пробел превратил в %20. Ну и другие символы тоже будут закодированы в свой числовой код с символом процента. И самое неприятное, что тут ничего нельзя сделать на уровне браузера (тут всё сделано по стандарту) — браузер не любит подобные символы, а командный интерпретатор Windows не работает с такими закодированными значениями. И еще один минус — в качестве параметра передается вся строка, включая название протокола и даже двоеточие (sapgui.shortcut.file:). Причем, хотя тот же sapshcut.exe умеет отбрасывает всё что не является для него параметром (начинается с символа «-«, потом название, «=» и значение), т.е. строка вида «sapgui.shortcut.file: -system=SID» еще прокатит, то без пробела «sapgui.shortcut.file:-system=SID» уже не работает.
Получается, что, в принципе, есть два варианта использования URI-протокола:
- Использование без параметров: Создаем целую кучу протоколов под все наши системы вида SIDMANDT, типа AAA200, BBB200 и т.п. Если нужно просто запустить нужную систему, то вариант вполне рабочий, но в нашем случае не подходит, поскольку уж хотя бы логин пользователя хочется тоже передать, а это таким образом не сделать.
- Использование программы-обертки для вызова sapshcut.exe или sapgui.exe. Суть данной программы проста — она должна брать ту строку, что ей передаст браузер через веб-протокол и её превращать в то представление, что принимает Windows, т.е. обратно превращает все коды символов в символы (может быть даже разбирает строку по параметрам) и уже вызывает SAP GUI гарантировано верной командой. В нашем случае тоже не совсем подходит (поэтому даже не стал её писать), потому что нам уже мало добавить протокол на всех пользовательских ПК (в рамках домена это еще куда ни шло, хотя тоже лучше избегать такой практики), но тут потребуется ещё дополнительно программу разместить на ПК, да еще и постоянно следить, чтобы она никуда не делась при переустановках ПО на ПК.
Т.е. данный вариант тоже отбрасываем как негодный нам.
Тут я уже начал думать, что с идеей запускать SAP GUI с нужными параметрами из браузера придется распрощаться, но тут мне в голову пришла мысль о том, что в SAP Logon можно сделать ярлык и его можно скопировать на рабочий стол. Я пользовался таким способом когда-то, но до этого файл ярлыка специально не смотрел. И оказалось, что данный ярлык представляет из себя обычный текстовый файл с расширением .sap. И если его запустить в Windows — запустится SAP GUI с параметрами, которые и указаны в этом файле. «Бинго!»
Формат данного файла примерно следующий (еще может быть запускаемая транзакция при старте, но я её опустил):
[System]
Name=SID
Client=200
[User]
Name=
Language=RU
Password=
[Function]
Title=
[Configuration]
GuiSize=Maximized
[Options]
Reuse=0
Вроде бы всё, что необходимо: и идентификатор системы, и мандант, и имя пользователя и даже пароль. И даже дополнительные параметры: Title — заголовок окна, GuiSize — размер запущенного окна (во весь экран или нет) и Reuse — открывать ли обязательно новое окно или использовать уже открытое с этой же системой. Но сразу вылез нюанс — пароль в SAP Logon оказалось задать нельзя, строка была заблокирована. Оказалось, что это сделано из соображений безопасности: все ярлыки созданные в SAP Logon он хранит в файле sapshortcut.ini (рядом с saplogon.ini в профиле пользователя Windows) и там они хотя и зашифрованы, но не слишком сильно и при большом желании их можно раскодировать. Но можно и разрешить это с помощью изменения значения одного параметра в реестре (по умолчанию значение 0):
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\SAP\SAPShortcut\Security]
"EnablePassword"="1"
Это разблокирует для ввода поле «Пароль» на форме создания ярлыка в SAP Logon:
И при внесении в это поле пароля, он будет размещен в соответствующей строке
sapshortcut.ini, но вот при перетаскивании ярлыка на рабочий стол он там не появляется — зато можно его туда добавить вручную. Пароль зашифрован, для 111111 он будет следующего вида: PW_49B02219D1F6, для 222222 — PW_4AB3211AD2F5. Но нас больше интересует то, что этот пароль шифруется одним способом, не зависящим от конкретного ПК и, если мы будем сбрасывать пароль на начальный, то можно в этом поле использовать одно заранее известное значение. Ну а если мы захотим использовать произвольно созданный пароль — то придется понять алгоритм этого шифра. Но, судя по приведенным примерам, сделать это будет несложно. Кстати, в SAP GUI 7.40 это поле вообще пропало с формы, но файл с заполненным паролем он корректно воспринимает.
То есть получается, что в браузере достаточно щелкнуть по ссылке на файл с расширением .sap и с нужным форматом — и он предложит его открыть как файл типа SAP GUI Shortcut (естественно на ПК с установленным SAP GUI) и откроет нам окно SAP GUI с указанными параметрами (если пара SID и мандант есть в списке SAP Logon на этом ПК).
Но, понятно, что просто файлы никто заранее создавать и складировать на сайт не будет — их надо генерировать исходя из нужных параметров. Например, можно создать скрипт на PHP для генерации ярлыков (sapshcut.php):
<?php
$queries = array();
parse_str($_SERVER['QUERY_STRING'], $queries);
$Title = $queries['Title'];
$Size = $queries['Size'];
$SID = $queries['SID'];
$Client = $queries['Client'];
if($Client == '') { $Client=200; };
$Lang = $queries['Language'];
if($Lang=='') { $Lang = 'RU'; };
$User = $queries['Username'];
if($User<>'') { $Password = $queries['Password']; };
$filename = $SID.$Client.'.sap';
header('Content-disposition: attachment; filename='.$filename);
header('Content-type: application/sap');
echo "[System]\r\n";
echo "Name=".$SID."\r\n";
echo "Client=".$Client."\r\n";
echo "[User]\r\n";
echo "Name=".$Username."\r\n";
echo "Language=".$Lang."\r\n";
if($Password<>'') echo "Password=".$Password."\r\n";
echo "[Function]\r\n";
if($Title<>'') {echo "Title=".$Title."\r\n";} else {echo "Title=Вход в систему\r\n";};
echo "[Configuration]\r\n";
if($Size=='max') { echo "GuiSize=Maximized\r\n"; };
echo "[Options]\r\n";
echo "Reuse=0\r\n";
?>
Если не задавать имя пользователя и пароль, то получим следующее окно с запросов логина и пароля:
Если передать только логин — то поле логин будет заполнено, а поле пароль пустое. Если же мы передаем пользователю и логин и пароль, но у пользователя на ПК в реестре ключ EnablePassword в разделе [HKEY_CURRENT_USER\Software\SAP\SAPShortcut\Security] установлен в 0, то получим то же самое. И только если этот ключ установлен в 1 и мы передаем и имя и начальный пароль, то система сразу запросит дважды ввести новый постоянный пароль. Что и требовалось получить.
В итоге, имеем следующий набор рассмотренных вариантов как иллюстрация всего вышесказанного:
<html>
<head>
<script>
function openSAPGui(sid, client, user, password) {
var shell = new ActiveXObject("WScript.Shell");
shell.run('sapshcut.exe -system="'+sid+'" -client='+client+' -user="'+user+'" -pw="'+password+'" -language=RU');
}
</script>
</head>
<body>
<a href='' onclick="javascript:openSAPGui('SID', '200', 'test', '');"/>Example 1: Execute sapshcut.exe (ActiveX)<br>
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>Example 2: Open sapshcut.exe (URI)</a><br>
<a href='sapshcut.php?SID=SID&Client=200&User=test'>Example 3: Open file .sap (SAP GUI Shortcut)</a><br>
</body>
</html>
Мне подошел последний вариант. Но также можно вместо генерации ярлыков SAP использовать, например, генерацию CMD-файлов, которые также при открытии из браузера откроют вам окно SAP GUI. Ниже приведен пример (sapguicmd.php) прямого запуска SAP GUI с указанием полной строки подключения, без необходимости иметь настроенный SAP Logon:
<?php
$queries = array();
parse_str($_SERVER['QUERY_STRING'], $queries);
$Title = $queries['Title'];
$ROUTER = $queries['ROUTER'];
$ROUTERPORT = $queries['ROUTERPORT'];
$HOST = $queries['HOST'];
$PORT = $queries['PORT'];
$MESS = $queries['MESS'];
$LG = $queries['LG'];
$filename = 'SAPGUI_';
if($MESS<>'') $filename = $filename.$MESS;
if($HOST<>'') $filename = $filename.$HOST;
if($PORT<>'') $filename = $filename.'_'.$PORT;
$filename = $filename.'.cmd';
header('Content-disposition: attachment; filename='.$filename);
header('Content-type: application/cmd');
echo "@echo off\r\n";
echo "chcp 1251\r\n";
echo "echo Вход в ".$Title."\r\n";
echo "set SAP_CODEPAGE=1504\r\n";
echo 'if exist "%ProgramFiles(x86)%\SAP\FrontEnd\SapGui\sapgui.exe" set gui=%ProgramFiles(x86)%\SAP\FrontEnd\SapGui\sapgui.exe'."\r\n";
echo 'if exist "%ProgramFiles%\SAP\FrontEnd\SapGui\sapgui.exe" set gui=%ProgramFiles%\SAP\FrontEnd\SapGui\sapgui.exe'."\r\n";
echo "set logon=";
if($ROUTER<>'') echo "/H/".$ROUTER;
if($ROUTERPORT<>'') echo "/S/".$ROUTERPORT;
if($MESS<>'') echo "/M/".$MESS;
if($HOST<>'') echo "/H/".$HOST;
if($PORT<>'') echo "/S/".$PORT;
if($LG<>'') echo "/G/".$LG;
echo "\r\n";
echo '"%gui%" %logon%'."\r\n";
?>