Abrindo o SAP GUI a partir do navegador

Escrevi este artigo inicialmente para mim blog, para não ter que procurar e lembrar de novo, mas como ninguém lê o blog, achei que seria bom compartilhar essa informação com todos, caso possa ser útil para alguém.

Durante o trabalho na ideia de um serviço para redefinir senhas em sistemas SAP R/3, surgiu a pergunta — como iniciar o SAP GUI com os parâmetros necessários a partir do navegador? Como essa ideia envolvia o uso de um serviço web, inicialmente que processaria uma solicitação SOAP do SAP GUI e enviaria um e-mail com um link para a página da web com o script de reinicialização da senha, seguido pela mensagem de sucesso ao usuário, e a exibição dessa senha inicial, eu gostaria que nesta página também tivesse um link para iniciar o SAP GUI. Além disso, esse link deveria abrir o sistema desejado, de preferência já com os campos de login e senha preenchidos: o usuário só precisaria inserir sua senha produtiva duas vezes.

Iniciar o SAP Logon - não era interessante para nosso objetivo, e ao iniciar o sapgui.exe não era possível especificar o mandante e o nome do usuário, mas era possível iniciar um sistema não definido no SAP Logon. Por outro lado, iniciar o SAP GUI com parâmetros de servidor arbitrários não era especialmente relevante: já que estamos resolvendo o problema de redefinição de senha do usuário, provavelmente ele já tem a entrada necessária no SAP Logon, com as configurações de que precisa, e não há necessidade de mexer nas suas. Porém, a tecnologia SAP GUI Shortcut e o programa sapshcut.exe atendiam às exigências, permitindo iniciar o SAP GUI usando um "atalho" definido.

A resolução direta do problema: iniciar o sapshcut.exe diretamente do navegador com um objeto 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');
}

A solução é ruim: primeiro, funciona apenas no Internet Explorer, segundo, requer as configurações de segurança correspondentes no navegador, que podem ser proibidas em nível de domínio na organização, e mesmo que sejam permitidas, o navegador exibe ao usuário uma janela com um aviso alarmante:

Abrindo o SAP GUI a partir do navegador

A solução nº 2 que encontrei na internet: criação de um protocolo web próprio. Permite iniciar o aplicativo desejado usando um link que especifica um protocolo que registramos no Windows no registro em HKEY_CLASSES_ROOT. Como o atalho SAP GUI possui uma sub-chave nessa seção, podemos adicionar um parâmetro de string URL Protocol com um valor vazio:

Abrindo o SAP GUI a partir do navegador

Este protocolo inicia sapgui.exe com o parâmetro /SHORTCUT, que é o que precisamos:

Abrindo o SAP GUI a partir do navegador

Ou, se quisermos criar um protocolo completamente personalizado (por exemplo, sapshcut), podemos registrá-lo com o seguinte arquivo reg:

Editor do Registro do Windows Versão 5.00
[HKEY_CLASSES_ROOTsapshcut]
@="Manipulador sapshcut"
"Protocolo URL"=""
[HKEY_CLASSES_ROOTsapshcutDefaultIcon]
@="sapshcut.exe"
[HKEY_CLASSES_ROOTsapshcutshell]
[HKEY_CLASSES_ROOTsapshcutshellopen]
[HKEY_CLASSES_ROOTsapshcutshellopencommand]
@="sapshcut.exe "%1""

Agora, se fizermos um link em uma página da web especificando o protocolo Sapgui.Shortcut.File da seguinte forma:

<a href='Sapgui.Shortcut.File: -system=SID -client=200'>SID200</a>

deve aparecer uma janela ao tipo:

Abrindo o SAP GUI a partir do navegador

E parece tudo ótimo, mas ao clicar no botão 'Permitir' vemos:

Abrindo o SAP GUI a partir do navegador

Opa, o navegador transformou o espaço em . Outros símbolos também serão codificados em seu código numérico com o símbolo de porcentagem. E o mais desagradável é que não há nada que se possa fazer no nível do navegador (tudo isso é feito de acordo com o padrão) — o navegador não gosta desses símbolos, e o interpretador de comandos do Windows não trabalha com esses valores codificados. E mais uma desvantagem — a string inteira, incluindo o nome do protocolo e até os dois pontos, é passada como parâmetro.sapgui.shortcut.file:). Além disso, embora o mesmo sapshcut.exe consiga ignorar tudo que não é um parâmetro para ele (começando com o símbolo '-', depois o nome, '=', e o valor), ou seja, uma string como 'sapgui.shortcut.file: -system=SID' ainda funcionará, mas sem espaço 'sapgui.shortcut.file:-system=SID' já não funciona.

Portanto, em princípio, existem duas opções para usar o protocolo URI:

  1. Uso sem parâmetros: Criamos uma série de protocolos para todos os nossos sistemas do tipo SIDMANDT, como AAA200, BBB200 etc. Se for necessário apenas iniciar o sistema desejado, essa opção funciona perfeitamente, mas no nosso caso não serve, pois gostaríamos também de passar o login do usuário, o que não pode ser feito dessa forma.
  2. Uso de um programa wrapper para chamada sapshcut.exe ou sapgui.exe. A essência deste programa é simples — ele deve pegar a string que o navegador envia através do protocolo web e convertê-la para a representação que o Windows aceita, ou seja, converter todos os códigos de caracteres de volta para símbolos (pode até desmembrar a string por parâmetros) e então chamar o SAP GUI com um comando garantidamente correto. No nosso caso, isso também não é ideal (por isso nem escrevi sobre isso), porque já é pouco adicionar o protocolo em todos os PCs dos usuários (dentro do domínio isso até vai, embora seja melhor evitar essa prática), mas aqui será necessário ainda colocar um programa adicional no PC e ficar sempre de olho para que ele não desapareça durante reinstalações de software no PC.

Ou seja, descartamos essa opção como inaceitável.

Aqui eu já comecei a pensar que teria que abrir mão da ideia de iniciar o SAP GUI com os parâmetros necessários a partir do navegador, mas então me lembrei que no SAP Logon é possível criar um atalho e copiá-lo para a área de trabalho. Eu já usei esse método antes, mas não tinha olhado especificamente o arquivo do atalho. E percebi que esse atalho é, na verdade, um arquivo de texto comum com a extensão .sap. E se ele for iniciado no Windows — o SAP GUI abrirá com os parâmetros que estão especificados nesse arquivo. "Bingo!"

O formato desse arquivo é mais ou menos o seguinte (também pode haver uma transação a ser iniciada, mas eu a omiti):

[System]
Nome=SID
Cliente=200
[User]
Nome=
Língua=RU
Senha=
[Function]
Título=
[Configuration]
GuiSize=Maximizado
[Options]
Reutilizar=0

Parece que é tudo o que é necessário: tanto o identificador do sistema, quanto o mandante, o nome do usuário e até a senha. E até parâmetros adicionais: Título — título da janela, TamanhoGui — tamanho da janela iniciada (se em tela cheia ou não) e Reuso — se deve abrir obrigatoriamente uma nova janela ou usar uma já aberta com o mesmo sistema. Mas logo surgiu um detalhe — não foi possível definir a senha no SAP Logon, a linha estava bloqueada. Aparentemente, isso foi feito por motivos de segurança: todos os atalhos criados no SAP Logon são armazenados em um arquivo sapshortcut.ini (próximo a saplogon.ini no perfil do usuário do Windows) e lá eles, embora criptografados, não estão muito seguros e, com um pouco de vontade, podem ser decodificados. Mas isso pode ser permitido alterando o valor de um parâmetro no registro (o valor padrão é 0):

Editor do Registro do Windows Versão 5.00
[HKEY_CURRENT_USERSoftwareSAPSAPShortcutSecurity]
"EnablePassword"="1"

Isso desbloqueia o campo "Senha" no formulário de criação de atalho no SAP Logon:

Abrindo o SAP GUI a partir do navegador

E ao inserir a senha neste campo, ela será colocada na linha correspondente
sapshortcut.ini, mas ao arrastar o atalho para a área de trabalho ele não aparece lá — mas pode ser adicionado manualmente. A senha é criptografada, para 111111 ela será assim: PW_49B02219D1F6, para 222222 — PW_4AB3211AD2F5. Mas o que nos interessa mais é que essa senha é criptografada de uma maneira que não depende do PC específico e, se fizermos um reset para a senha inicial, poderemos usar um valor previamente conhecido neste campo. E se quisermos usar uma senha criada aleatoriamente — teremos que entender o algoritmo dessa cifra. Mas, a julgar pelos exemplos fornecidos, isso não será difícil. Aliás, no SAP GUI 7.40 esse campo desapareceu completamente do formulário, mas o arquivo com a senha preenchida é corretamente interpretado.

Ou seja, no navegador, basta clicar no link para o arquivo com a extensão .sap e no formato apropriado — e ele vai oferecer para abri-lo como um arquivo do tipo Atalho SAP GUI (naturalmente em um PC com o SAP GUI instalado) e abrirá a janela SAP GUI com os parâmetros especificados (se a combinação SID e cliente estiver na lista de Logon SAP neste PC).

Mas, claro, que ninguém vai criar e armazenar esses arquivos antecipadamente no site — eles precisam ser gerados com base nos parâmetros necessários. Por exemplo, podemos criar um script em PHP para gerar atalhos (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]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=Acesso ao sistemarn";};
echo "[Configuration]rn";
if($Size=='max') { echo "GuiSize=Maximizedrn"; };
echo "[Options]rn";
echo "Reuse=0rn";
?>

Se não forem definidos nome de usuário e senha, teremos a seguinte janela solicitando login e senha:

Abrindo o SAP GUI a partir do navegador

Se apenas transmitir o login, o campo de login será preenchido, enquanto o campo da senha permanecerá vazio. No entanto, se transmitirmos tanto o nome de usuário quanto a senha ao usuário, mas a chave EnablePassword no registro do PC do usuário, no diretório [HKEY_CURRENT_USERSoftwareSAPSAPShortcutSecurity], estiver definida como 0, obteremos o mesmo resultado. E apenas se essa chave estiver definida como 1 e transmitirmos tanto o nome quanto a senha inicial, o sistema solicitará imediatamente que o novo senha permanente seja inserido duas vezes. Isso era exatamente o que se desejava obter.

No final, temos o seguinte conjunto de opções discutidas como ilustração de tudo o que foi dito acima:

<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', '');"/>Exemplo 1: Execute sapshcut.exe (ActiveX)<br>
<a href='Sapgui.Shortcut.File: -system=SID -client=200'>Exemplo 2: Abra sapshcut.exe (URI)</a><br>
<a href='/pt/sapshcut.php/?SID=SID&Client=200&User=test'>Exemplo 3: Abra o arquivo .sap (Atalho SAP GUI)</a><br>
</body>
</html>

A última opção me atendeu. Mas também podemos, em vez de gerar atalhos SAP, por exemplo, gerar arquivos CMD, que ao serem abertos no navegador abrirão a janela do SAP GUI para você. Abaixo está um exemplo (sapguicmd.php) para a execução direta do SAP GUI com a especificação da string de conexão completa, sem a necessidade de ter o SAP Logon configurado:

<?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\rn";
echo "chcp 1251\rn";
echo "echo Acesso a ".$Title."\rn";
echo "set SAP_CODEPAGE=1504\rn";
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

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster