Ho scritto inizialmente questo articolo nel mio , per non dover cercare e ricordare di nuovo, ma poiché nessuno legge il blog, ho voluto condividere queste informazioni con tutti, nel caso possano essere utili.
Durante il lavoro sull'idea di un servizio per il ripristino della password nei sistemi SAP R/3, è emersa la domanda: come si può avviare SAP GUI con i parametri necessari dal browser? Poiché in questa idea si prevedeva l'uso di un web service, inizialmente sviluppato per gestire una richiesta SOAP da SAP GUI e inviare un'email con un link a una pagina web contenente lo script per il ripristino della password, e successivamente mostrare all'utente un messaggio di avvenuto ripristino della password e il relativo password iniziale, desideravo che su questa pagina ci fosse anche un link per avviare SAP GUI. Vorrei che questo link aprisse il sistema richiesto e, preferibilmente, già con i campi nome utente e password compilati: all'utente basterebbe inserire due volte la password di produzione.
Avviare SAP Logon — per noi non era interessante, e avviando sapgui.exe non era possibile specificare il mandante e il nome utente; tuttavia, era possibile avviare un sistema non definito in SAP Logon. D'altro canto, avviare SAP GUI con parametri server arbitrari non era particolarmente utile: se stiamo affrontando un problema di ripristino della password di un utente, è probabile che in SAP Logon ci sia già la stringa necessaria, con le impostazioni richieste, senza dover inserire le proprie. Tuttavia, la tecnologia SAP GUI Shortcut e il programma sapshcut.exe soddisfacevano i requisiti, permettendo di avviare SAP GUI utilizzando un determinato "collegamento".
Soluzione diretta: avviare sapshcut.exe direttamente dal browser utilizzando l'oggetto 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');
}
Soluzione pessima: in primo luogo, funziona solo in Internet Explorer, in secondo luogo, richiede le impostazioni di sicurezza appropriate nel browser, che nell'organizzazione potrebbero essere vietate a livello di dominio, e anche se consentite, il browser fornisce all'utente una finestra con un avviso preoccupante:

Soluzione n. 2 trovata su Internet: . Permette di avviare l'applicazione di cui abbiamo bisogno tramite un link specificando il protocollo che registriamo noi stessi in Windows nel registro nella sezione HKEY_CLASSES_ROOT. Poiché il collegamento SAP GUI ha una sua sotto-sezione in questa parte, possiamo aggiungere il parametro stringa URL Protocol con valore vuoto:

Questo protocollo avvia sapgui.exe con il parametro /SHORTCUT, che è esattamente ciò che ci serve:

Oppure, se vogliamo creare un protocollo completamente arbitrario (ad esempio, sapshcut), possiamo registrarlo utilizzando il seguente file reg:
Editor di registro di Windows Versione 5.00
[HKEY_CLASSES_ROOTsapshcut]
@="Gestore sapshcut"
"URL Protocol"=""
[HKEY_CLASSES_ROOTsapshcutDefaultIcon]
@="sapshcut.exe"
[HKEY_CLASSES_ROOTsapshcutshell]
[HKEY_CLASSES_ROOTsapshcutshellopen]
[HKEY_CLASSES_ROOTsapshcutshellopencommand]
@="sapshcut.exe "%1""
Ora, se facciamo un link su una pagina web specificando il protocollo Sapgui.Shortcut.File in questo modo:
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>SID200</a>
dovrebbe apparire una finestra di questo tipo:

E sembrerebbe tutto fantastico, ma cliccando sul pulsante «Consenti» vediamo:

Опа, браузер пробел превратил в %20. Ну и другие символы тоже будут закодированы в свой числовой код с символом процента. И самое неприятное, что тут ничего нельзя сделать на уровне браузера (тут всё сделано по стандарту) — браузер не любит подобные символы, а командный интерпретатор Windows не работает с такими закодированными значениями. И еще один минус — в качестве параметра передается вся строка, включая название протокола и даже двоеточие (sapgui.shortcut.file:) . Infatti, anche se sapshcut.exe è in grado di ignorare tutto ciò che non è un parametro valido (inizia con il simbolo «-«, seguito dal nome, «=» e dal valore), ovvero, una stringa del tipo «sapgui.shortcut.file: -system=SID» ancora funziona, ma senza spazio «sapgui.shortcut.file:-system=SID» non funziona più.
Dunque, in linea di massima, ci sono due opzioni per utilizzare il protocollo URI:
- Utilizzo senza parametri: Creiamo una serie di protocolli per tutti i nostri sistemi del tipo SIDMANDT, come AAA200, BBB200 e simili. Se è necessario semplicemente avviare il sistema desiderato, questa opzione funziona bene, ma nel nostro caso non è adatta, poiché vogliamo comunque trasmettere anche il login dell'utente, e questo non può essere fatto in questo modo.
- Utilizzo di un programma wrapper per le chiamate sapshcut.exe o sapgui.exe. Il concetto di questo programma è semplice: deve prendere la stringa che il browser gli trasmette tramite un protocollo web e convertirla nella rappresentazione accettata da Windows, ovvero riconvertire tutti i codici dei caratteri nei caratteri stessi (potrebbe persino analizzare la stringa per parametri) e poi chiamare SAP GUI con il comando corretto. Anche nel nostro caso, non è del tutto appropriato (per questo non l'ho scritto), perché ci serve poco aggiungere il protocollo su tutti i PC degli utenti (all'interno del dominio va anche bene, anche se è meglio evitare tale pratica), ma qui sarà necessario installare ulteriormente un programma sui PC e inoltre monitorare costantemente affinché non venga rimosso durante le reinstallazioni del software sui PC.
Quindi, anche questa opzione la scartiamo come inadeguata.
A questo punto avevo quasi rinunciato all'idea di lanciare il SAP GUI con i parametri necessari dal browser, ma poi mi è venuta in mente l'idea che in SAP Logon si può creare un collegamento e copiarlo sul desktop. In passato ho usato questo metodo, ma non avevo mai esaminato il file del collegamento. E così ho scoperto che questo collegamento è un normale file di testo con estensione .sap. E se lo avvii in Windows, si aprirà SAP GUI con i parametri specificati in questo file. «Bingo!»
Il formato di questo file è all'incirca il seguente (potrebbe contenere anche la transazione da avviare all'inizio, ma l'ho omessa):
[System]
Nome=SID
Cliente=200
[User]
Nome=
Lingua=IT
Password=
[Function]
Titolo=
[Configuration]
DimensioneGui=Massimizzato
[Options]
Riutilizza=0
Sembra che ci sia tutto il necessario: identificativo del sistema, mandante, nome utente e anche la password. E addirittura parametri aggiuntivi: Titolo — titolo della finestra, GuiSize — dimensione della finestra avviata (a schermo intero o meno) e Reuse — è necessario aprire una nuova finestra o utilizzare quella già aperta con lo stesso sistema. Ma è emerso subito un problema: in SAP Logon non era possibile impostare la password, la riga era bloccata. Si è scoperto che ciò è stato fatto per motivi di sicurezza: tutte le scorciatoie create in SAP Logon vengono salvate in un file sapshortcut.ini (accanto a saplogon.ini nel profilo utente di Windows) e là sono anche se crittografati, ma non in modo troppo forte e con un grande desiderio possono essere decifrati. Ma è possibile anche consentirlo modificando il valore di un parametro nel registro (per impostazione predefinita, il valore 0):
Editor di registro di Windows Versione 5.00
[HKEY_CURRENT_USERSoftwareSAPSAPShortcutSecurity]
"EnablePassword"="1"
Questo sblocca il campo "Password" nel modulo di creazione della scorciatoia in SAP Logon:

E inserendo la password in questo campo, verrà inserita nella riga corrispondente
sapshortcut.ini, ma quando si trascina l'icona sul desktop, essa non appare lì — però può essere aggiunta manualmente. La password è crittografata, per 111111 avrà il seguente formato: PW_49B02219D1F6, per 222222 — PW_4AB3211AD2F5. Ciò che ci interessa è che questa password viene crittografata in un modo che non dipende dal PC specifico e, se ripristiniamo la password all'iniziale, possiamo usare un valore già noto in questo campo. Se desideriamo invece utilizzare una password creata arbitrariamente, dovremo capire l'algoritmo di questa crittografia. Tuttavia, a giudicare dagli esempi forniti, questo non sarà difficile. A proposito, in SAP GUI 7.40 questo campo è completamente scomparso dal modulo, ma il file con la password compilata viene correttamente elaborato.
Quindi risulta che nel browser è sufficiente fare clic sul link a un file con estensione .sap e con il formato necessario — e questo offrirà di aprirlo come un file di tipo SAP GUI Shortcut (naturalmente su un PC con SAP GUI installato) e aprirà la finestra di SAP GUI con i parametri indicati (se la coppia SID e mandante è presente nell'elenco SAP Logon su questo PC).
È chiaro che non è possibile creare e archiviare semplicemente dei file sul sito — devono essere generati in base ai parametri necessari. Ad esempio, si può creare uno script in PHP per la generazione di collegamenti (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 = 'IT'; };
$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=Accesso al sistema rn";};
echo "[Configuration]rn";
if($Size=='max') { echo "GuiSize=Massimizzato rn"; };
echo "[Options]rn";
echo "Reuse=0rn";
?>
Se non si specificano nome utente e password, verrà visualizzata la seguente finestra con la richiesta di login e password:

Se viene passato solo il nome utente, il campo del nome utente verrà compilato e il campo della password rimarrà vuoto. Se invece forniamo sia il nome utente che la password, ma nel registro del computer dell'utente la chiave EnablePassword nella sezione [HKEY_CURRENT_USERSoftwareSAPSAPShortcutSecurity] è impostata su 0, otterremo lo stesso risultato. Solo se questa chiave è impostata su 1 e forniamo sia il nome che la password iniziale, il sistema chiederà immediatamente di inserire due volte una nuova password permanente. Questo è ciò che si intendeva ottenere.
Alla fine, abbiamo il seguente insieme di opzioni esaminate come illustrazione di quanto detto sopra:
<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', '');"/>Esempio 1: Eseguire sapshcut.exe (ActiveX)<br>
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>Esempio 2: Aprire sapshcut.exe (URI)</a><br>
<a href='/it/sapshcut.php/?SID=SID&Client=200&User=test'>Esempio 3: Aprire il file .sap (Collegamento SAP GUI)</a><br>
</body>
</html>
L'ultima opzione mi è sembrata la migliore. Tuttavia, è anche possibile utilizzare, ad esempio, la generazione di file CMD invece di creare collegamenti SAP, che apriranno anche la finestra SAP GUI quando aperti dal browser. Di seguito è riportato un esempio (sapguicmd.php) di avvio diretto di SAP GUI specificando la stringa di connessione completa, senza necessità di avere un SAP Logon configurato:
<?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 offrn";
echo "chcp 1251rn";
echo "echo Access to ".$Title."rn";
echo "set SAP_CODEPAGE=1504rn";
echo 'if exist "%ProgramFiles(x86)%SAPFrontEndSapGuisapgui.exe" set gui=%ProgramFiles(x86)%SAPFrontEndSapGuisapgui.exe'."rn";
echo 'if exist "%ProgramFiles%SAPFrontEndSapGuisapgui.exe" set gui=%ProgramFiles%SAPFrontEndSapGuisapgui.exe'."rn";
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 "rn";
echo '"%gui%" %logon%'."rn";
?>
Fonte: habr.com
