Ten artykuł napisałem najpierw dla siebie , aby później znów nie szukać i nie przypominać sobie, ale ponieważ nikt nie czyta bloga, postanowiłem podzielić się tą informacją ze wszystkimi, może się komuś przyda.
Podczas pracy nad pomysłem na usługę resetowania hasła w systemach SAP R/3 pojawiło się pytanie — jak uruchomić SAP GUI z odpowiednimi parametrami z przeglądarki? Ponieważ w tym pomyśle przewidywano użycie usługi sieciowej, która najpierw realizowała żądanie SOAP z SAP GUI i wysyłała e-mail z linkiem do strony internetowej ze skryptem resetującym hasło na początek, a następnie wyświetlała użytkownikowi komunikat o pomyślnym zresetowaniu hasła i wyświetlała to samo początkowe hasło, chciałem, aby na tej stronie znajdował się także link do uruchomienia SAP GUI. I żeby ten link otwierał odpowiedni system, a także, najlepiej, od razu z wypełnionymi polami loginu i hasła: użytkownik musiałby tylko dwukrotnie wprowadzić aktualne hasło.
Uruchomienie SAP Logon — nie było dla nas interesujące, a przy uruchomieniu sapgui.exe nie można było wskazać mandanta i nazwy użytkownika, za to można było uruchomić system nieokreślony w SAP Logon. Z drugiej strony uruchomienie SAP GUI z dowolnymi parametrami serwera nie było szczególnie istotne: jeśli rozwiązujemy problem resetowania hasła użytkownika, to prawdopodobnie ma on już potrzebny wpis w SAP Logon ze swoimi ustawieniami i nie musimy wchodzić ze swoimi. Jednak technologii SAP GUI Shortcut i samego programu sapshcut.exe spełniały postawione wymagania, co pozwalało uruchamiać SAP GUI z użyciem określonego „skrót”.
Rozwiązanie problemu na prost: uruchomienie sapshcut.exe bezpośrednio z przeglądarki z wykorzystaniem obiektu 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');
}
Rozwiązanie słabe: po pierwsze, działa tylko w Internet Explorer, po drugie, wymaga odpowiednich ustawień bezpieczeństwa w przeglądarce, które w organizacji mogą być zabronione na poziomie domeny, a nawet jeśli są dozwolone, przeglądarka wyświetla użytkownikowi okno z przerażającym ostrzeżeniem:

Rozwiązanie nr 2 znalazłem w Internecie: . Umożliwia uruchomienie nam potrzebnej aplikacji za pomocą linku z określeniem protokołu, który rejestrujemy w systemie Windows w rejestrze w sekcji HKEY_CLASSES_ROOT. Ponieważ SAP GUI Shortcut ma swoją podsekcję w tej sekcji, można tam dodać parametr ciągu URL Protocol z pustą wartością:

Ten protokół uruchamia sapgui.exe z parametrem /SHORTCUT, co właśnie jest nam potrzebne:

A jeśli chcemy stworzyć całkowicie dowolny protokół (na przykład, sapshcut), to możemy go zarejestrować za pomocą poniższego pliku reg:
Edytor rejestru systemu Windows w wersji 5.00
[HKEY_CLASSES_ROOTsapshcut]
@="sapshcut Handler"
"URL Protocol"=""
[HKEY_CLASSES_ROOTsapshcutDefaultIcon]
@="sapshcut.exe"
[HKEY_CLASSES_ROOTsapshcutshell]
[HKEY_CLASSES_ROOTsapshcutshellopen]
[HKEY_CLASSES_ROOTsapshcutshellopencommand]
@="sapshcut.exe "%1""
Teraz, jeśli na stronie internetowej utworzymy link z określeniem protokołu Sapgui.Shortcut.File w ten sposób:
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>SID200</a>
powinno pojawić się okno tego typu:

I wydaje się, że wszystko jest w porządku, ale po naciśnięciu przycisku „Zezwól” widzimy:

O, przeglądarka zamieniła spację na . Inne symbole również będą kodowane w swoim numerycznym kodzie z symbolem procenta. I co najgorsze, nie da się tego naprawić na poziomie przeglądarki (wszystko zrobione zgodnie z standardem) — przeglądarka nie toleruje takich symboli, a interpreter poleceń Windows nie działa z takimi zakodowanymi wartościami. I jeszcze jedna wada — jako parametr przekazywana jest cała linia, w tym nazwa protokołu i nawet dwukropek (sapgui.shortcut.file:). Choć ten sam sapshcut.exe potrafi odrzucić wszystko, co nie jest dla niego parametrem (zaczyna się od znaku „-”, potem nazwa, „=” i wartość), tj. linia w postaci „sapgui.shortcut.file: -system=SID” jeszcze zadziała, to bez spacji „sapgui.shortcut.file:-system=SID” już nie działa.
Okazuje się, że w zasadzie są dwa sposoby korzystania z protokołu URI:
- Korzystanie bez parametrów: Tworzymy całą masę protokołów dla naszych systemów w postaci SIDMANDT, takie jak AAA200, BBB200 itp. Jeśli trzeba po prostu uruchomić odpowiedni system, to opcja jest jak najbardziej działająca, ale w naszym przypadku nie pasuje, ponieważ chcielibyśmy również przekazać login użytkownika, a to w ten sposób się nie uda.
- Korzystanie z programu pośredniczącego do wywołania sapshcut.exe lub sapgui.exeIstota tego programu jest prosta — ma on przejmować ciąg, który przekaże mu przeglądarka przez protokół WWW i zamieniać go w takie przedstawienie, jakie akceptuje Windows, tj. z powrotem przekształcać wszystkie kody znaków w znaki (może nawet analizować ciąg pod kątem parametrów) i już wywołuje SAP GUI gwarantowaną poprawną komendą. W naszym przypadku również nie do końca to pasuje (dlatego nawet nie chciałem tego pisać), gdyż mało nam już dodać protokół na wszystkich komputerach użytkowników (w ramach domeny to jeszcze jakoś by przeszło, chociaż też lepiej unikać takiej praktyki), ale tu dodatkowo będzie trzeba jeszcze umieścić program na komputerze i nieustannie śledzić, żeby gdzieś nie zniknął przy reinstalacjach oprogramowania na komputerze.
To znaczy, tę opcję również odrzucamy jako niepraktyczną.
Tutaj zacząłem już myśleć, że z pomysłem uruchamiania SAP GUI z potrzebnymi parametrami z przeglądarki będę musiał się pożegnać, ale wtedy wpadło mi do głowy, że w SAP Logon można utworzyć skrót i można go skopiować na pulpit. Korzystałem z tej metody kiedyś, ale wcześniej nie przyglądałem się plikowi skrótu. Okazało się, że ten skrót to zwykły plik tekstowy z rozszerzeniem .sap. I jeśli uruchomić go w Windows — uruchomi się SAP GUI z parametrami, które są określone w tym pliku. „Bingo!”
Format tego pliku wygląda mniej więcej tak (może być jeszcze dodatkowa transakcja uruchamiana przy starcie, ale ją pominąłem):
[System]
Nazwa=SID
Klient=200
[User]
Nazwa=
Język=RU
Hasło=
[Function]
Tytuł=
[Configuration]
GuiSize=Maximized
[Options]
Reuse=0
Wydaje się, że wszystko, co konieczne: identyfikator systemu, mandant, nazwa użytkownika, a nawet hasło. A nawet dodatkowe parametry: Tytuł — tytuł okna, GuiSize — rozmiar uruchomionego okna (na cały ekran lub nie) oraz Reuse — czy otwierać nowe okno, czy użyć już otwartego z tym samym systemem. Ale od razu pojawił się problem — w SAP Logon okazało się, że hasła ustawić nie można, pole było zablokowane. Okazało się, że zrobiono to z powodów bezpieczeństwa: wszystkie skróty utworzone w SAP Logon są przechowywane w pliku sapshortcut.ini (obok) saplogon.ini w profilu użytkownika Windows) i tam są one co prawda zaszyfrowane, ale nie za mocno i przy dużym chęci można je odszyfrować. Można to jednak umożliwić, zmieniając wartość jednego parametru w rejestrze (domyślnie wartość 0):
Edytor rejestru systemu Windows w wersji 5.00
[HKEY_CURRENT_USERSoftwareSAPSAPShortcutSecurity]
"EnablePassword"="1"
To odblokowuje możliwość wprowadzenia „Hasła” w formularzu tworzenia skrótu w SAP Logon:

A przy wprowadzaniu hasła w to pole, zostanie ono umieszczone w odpowiednim wierszu.
sapshortcut.ini, ale podczas przeciągania skrótu na pulpit nie pojawia się tam — ale można go tam dodać ręcznie. Hasło jest szyfrowane, dla 111111 będzie miało następujący format: PW_49B02219D1F6, dla 222222 — PW_4AB3211AD2F5. Interesuje nas bardziej to, że hasło jest szyfrowane w jeden sposób, niezależnie od konkretnego komputera, a jeśli zresetujemy hasło do wartości początkowej, to w tym polu możemy użyć jednej dobrze znanej wartości. Jeśli jednak zechcemy użyć dowolnie utworzonego hasła — trzeba będzie zrozumieć algorytm tego szyfru. Ale, sądząc po podanych przykładach, będzie to proste. Nawiasem mówiąc, w SAP GUI 7.40 to pole w ogóle zniknęło z formularza, ale plik z wypełnionym hasłem jest prawidłowo rozpoznawany.
Innymi słowy, w przeglądarce wystarczy kliknąć link do pliku z rozszerzeniem .sap i w odpowiednim formacie — a zaproponuje jego otwarcie jako plik typu SAP GUI Shortcut (oczywiście na komputerze z zainstalowanym SAP GUI) i otworzy nam okno SAP GUI z określonymi parametrami (jeśli para SID i mandomant znajduje się na liście SAP Logon na tym komputerze).
Jednakże, jasne jest, że nikt z góry nie będzie tworzył i przechowywał plików na stronie — muszą być generowane na podstawie potrzebnych parametrów. Na przykład można stworzyć skrypt w PHP do generowania skrótów (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 = 'PL'; };
$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]rn";
echo "Name=".$SID."rn";
echo "Client=".$Client."rn";
echo "[User]rn";
echo "Name=".$Username."rn";
echo "Language=".$Lang."rn";
if($Password'') echo "Password=".$Password."rn";
echo "[Function]rn";
if($Title'') {echo "Title=".$Title."rn";} else {echo "Title=Logowanie do systemu rn";};
echo "[Configuration]rn";
if($Size=='max') { echo "GuiSize=Maximizedrn"; };
echo "[Options]rn";
echo "Reuse=0rn";
?>
Jeśli nie podamy nazwy użytkownika i hasła, otrzymamy następujące okno z prośbą o logowanie i hasło:

Jeśli przekażemy tylko login, pole login zostanie wypełnione, a pole hasło pozostanie puste. Jeśli natomiast przekazujemy użytkownikowi zarówno login, jak i hasło, ale w rejestrze na komputerze użytkownika klucz EnablePassword w sekcji [HKEY_CURRENT_USERSoftwareSAPSAPShortcutSecurity] jest ustawiony na 0, to otrzymujemy to samo. Tylko jeśli ten klucz jest ustawiony na 1 i przekazujemy zarówno nazwę, jak i początkowe hasło, system natychmiast poprosi o dwukrotne wprowadzenie nowego, stałego hasła. Co właśnie było celem.
W rezultacie mamy następujący zestaw rozważonych opcji jako ilustrację powyższego:
<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', '');"/>Przykład 1: Uruchom sapshcut.exe (ActiveX)<br>
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>Przykład 2: Otwórz sapshcut.exe (URI)</a><br>
<a href='/pl/sapshcut.php/?SID=SID&Client=200&User=test'>Przykład 3: Otwórz plik .sap (Skrót SAP GUI)</a><br>
</body>
</html>
Ostatnia opcja wydawała mi się odpowiednia. Można także zamiast generacji skrótów SAP użyć na przykład generacji plików CMD, które również po otwarciu w przeglądarce otworzą okno SAP GUI. Poniżej znajduje się przykład (sapguicmd.php) bezpośredniego uruchomienia SAP GUI z podaniem pełnego łącza, bez konieczności posiadania skonfigurowanego 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 Logowanie do ".$Title."\r\n";
echo "set SAP_CODEPAGE=1504\r\n";
echo 'if exist "%ProgramFiles(x86)%SAPFrontEndSapGuisapgui.exe" set gui=%ProgramFiles(x86)%SAPFrontEndSapGuisapgui.exe'."\r\n";
echo 'if exist "%ProgramFiles%SAPFrontEndSapGuisapgui.exe" set gui=%ProgramFiles%SAPFrontEndSapGuisapgui.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";
?>
Źródło: habr.com
