8. Licença e modo de demonstração #
← FAQ e resolução de problemas · Índice
O PBToolboxAI é uma biblioteca comercial. O controlo da licença é totalmente offline: sem ligação, sem ativação, sem chamada a servidor. Uma chave assinada é atribuída no arranque e a DLL verifica-a localmente.
8.1 Os três tipos de chaves #
As chaves são cumuláveis: PBT_SetLicense pode ser chamada as vezes necessárias, uma vez que a biblioteca retém uma chave por tipo.
| Tipo | Titular | Desbloqueia |
|---|---|---|
dev | Nominativa, um programador | Apenas no IDE do PowerBuilder |
runtime | A sua empresa, incorporada na aplicação entregue | Apenas num executável compilado |
demo | Fornecida com a aplicação de demonstração | A aplicação de demonstração, no IDE, até à expiração |
Um projeto necessita, portanto, de ambas: um posto dev por programador e uma chave runtime para a aplicação entregue aos seus clientes.
- Uma chave
devque acabe por ficar num executável não desbloqueia nada. - Uma chave
runtimenão confere qualquer posto de desenvolvimento. - Os clientes finais não têm nada a introduzir nem a ativar: a chave
runtimeestá no seu código.
A deteção «IDE ou executável» é efetuada pela própria DLL (nome do processo, módulos de design-time carregados), e não por código PowerBuilder — não pode ser contornada a partir das suas fontes.
8.2 Atribuir a chave #
Há apenas uma coisa a fazer, antes da abertura da primeira window:
// Declaracao - objeto application, "Local External Functions"
Function long PBT_SetLicense (string as_client, string as_key) Library "pbtoolboxai.dll"
// Event open do objeto application
// Local variables
long ll_rc
string ls_dev_key
// A chave RUNTIME vai no codigo : TEM de ficar dentro do executavel.
ll_rc = PBT_SetLicense(gs_licensee, gs_runtime_key)
// A chave DEV le-se do posto : so desbloqueia o IDE, e no codigo iria em
// cada copia entregue sem ali servir para nada.
ls_dev_key = ProfileString("pbtoolboxai.ini", "license", "dev", "")
if ls_dev_key <> "" then ll_rc = PBT_SetLicense(gs_licensee, ls_dev_key)
Open(w_main)
A chave é definida através da função da DLL, nunca através de um método de componente: aplica-se a todo o processo e tem de ser definida antes de existir qualquer componente. É pela mesma razão que
PBT_LicenseStatusnão pede qualquer handle.
O titular é passado em claro, como primeiro argumento: é o nome (ou endereço de e-mail) em que a licença foi emitida e tem de corresponder ao que a chave assinada contém. Assim, uma chave não pode circular sem o nome de quem a comprou.
| Retorno | Significado |
|---|---|
0 | Chave válida e retida |
-1 | Formato de chave inválido |
-2 | Assinatura inválida (chave alterada ou externa) |
-3 | Manutenção expirada para esta versão da biblioteca (ver 8.5) |
-4 | Chave demo expirada |
-5 | O titular indicado não corresponde ao da chave |
💡 Que chave vai onde. A chave
runtimepertence ao código: tem de ficar dentro do executável que entrega. A chavedevnão — só desbloqueia o IDE, por isso dentro de um executável não serve para nada e mesmo assim circula, com o nome da sua empresa. O seu lugar é um ficheiropbtoolboxai.inijunto ao IDE, ou um valor no registo.
Atribuir a chave depois da criação de um componente também funciona: os componentes já abertos são desbloqueados de imediato. Contudo, o mais simples continua a ser o event open da aplicação.
💡 A chave deve ser conservada numa constante ou num recurso da aplicação. É assinada: não contém qualquer segredo explorável e não pode ser modificada sem invalidar a respetiva assinatura.
8.3 Verificar o estado da licença #
// Declaracao
Function long PBT_LicenseStatus (ref string as_json, long al_len) Library "pbtoolboxai.dll"
// Local variables
string ls_status
// O estado da licenca, em JSON
ls_status = Space(1024)
PBT_LicenseStatus(ls_status, 1024)
// -> {"licensed":true,"ide":false,"keys":{...},"reason":""}
Útil na fase de integração para verificar se uma chave é efetivamente tida em conta, ou para registar um arranque no registo aplicacional.
8.4 O modo de demonstração #
Sem chave válida — ou com uma chave que não se aplica ao contexto (uma chave dev num exe, por exemplo) — a biblioteca funciona em modo de demonstração: tudo é utilizável, tudo é visível, mas com limites — exceto os cinco componentes da edição comunidade, descritos logo abaixo, que nunca são limitados.
Cinco componentes continuam gratuitos #
A edição comunidade não exige nada: sem qualquer chave, cinco componentes funcionam sem emblema e sem limite, por tempo indeterminado.
| Componente | O que traz |
|---|---|
| statictext | Etiqueta com marcação: negrito, cores, ligações, marcas, blocos dobráveis |
| messagebox | Caixa de diálogo modal com tema e botões livres |
| toaster | Notificações ao canto do ecrã, com título, imagem e ações |
| webbrowser | Navegador WebView2 alojado numa janela PowerBuilder |
| json | Ler e escrever JSON em PowerScript puro (caminhos, tipos, construção) |
A escolha é deliberada: os quatro componentes visuais são aqueles com que se depara primeiro, não trazem qualquer modelo de dados próprio e bastam para provar num posto bloqueado que o runtime se instala — o verdadeiro obstáculo antes de qualquer compra. json junta-se a eles porque é escrito em PowerScript puro, sem a DLL: é uma ferramenta de base, não um componente.
A lista vive na DLL. PBT_LicenseStatus devolve-a tal como está, em "free": a sua aplicação pode então anunciar a que tem direito sem chave, em vez de o descobrir componente a componente.
Uma chave válida prevalece sempre: nesses cinco componentes como nos outros, repõe o seu nome e a sua edição.
O emblema #
Cada componente apresenta um emblema «PBToolboxAI — DEMO», que não pode ser ocultado.
Os limites funcionais #
| Componente | Limite em modo de demonstração |
|---|---|
| tab | No máximo 3 separadores visíveis desenhados (o componente mantém todas as suas páginas: a chave mostra-as) |
| ribbon | 2 separadores no máximo |
| toolbar | 6 items apresentados, no conjunto de todas as barras; 6 entradas por nível de menu pendente; 6 escolhas por lista pendente |
| tilesbox | 8 mosaicos apresentados |
| commandpalette | 5 comandos listados |
| speechout | 4 frases e 400 caracteres por leitura (fila incluída), depois é dita a menção demo; passadas as 4 primeiras frases, cada leitura termina com ela |
| crypto | textos de 2048 caracteres, ficheiros e blobs de 2048 bytes no máximo, tanto à entrada como à saída (também uma decifragem ou uma descodificação) |
| restclient | corpos das respostas cortados a 4096 caracteres, sem transferência, nem envio de ficheiros, nem pedido de intervalo (Range) |
| soundplayer | só os 10 primeiros segundos de um som são tocados (seja qual for a velocidade), e duas notas descendentes dizem-no |
| video | um filme pára após 10 segundos; nem salto nem captura de imagem para além disso |
| xml | documentos de 65 536 caracteres no máximo, alterações incluídas; um documento construído mais longo não é validado (of_is_valid falso) nem indentado (of_pretty vazio) |
| listbar | 6 entradas apresentadas, no conjunto de todas as secções — uma pesquisa ou um of_from_datastore só mostra essas seis |
| statusbar | 4 painéis apresentados; 6 entradas por lista pendente de um painel (os separadores não contam), uma última linha desativada diz quantas ficam ocultas |
| contextmenu | 6 entradas por lista, em cada nível de cascata (os separadores e os cabeçalhos não contam); as outras ficam em memória sem serem mostradas, e uma última linha desativada di-lo |
| menubar | 3 menus na barra; 6 entradas por lista e 12 por menu, todas as suas cascatas incluídas (os separadores não contam); uma lista cortada termina com uma linha desativada que o diz |
| radialmenu | No máximo 4 ramos por coroa (menos se ii_max_sectors for menor), sem ramo «Mais», e um só nível de sub-rodas (um ramo mais profundo fica desativado); uma coroa cortada termina com um setor desativado «+N», e «PBToolboxAI — DEMO» está escrito sob o cubo |
| shellexplorer | 8 nós por nível da árvore |
| stepbar | 4 etapas apresentadas |
| buttonbar | 4 botões apresentados; os seguintes não são desenhados nem acionados pelo teclado (a sua letra Alt fica para a janela) |
| crosstab | 500 linhas de origem usadas, exportação e cópia desativadas; of_get_cell_value e of_get_cell_rows funcionam sobre essas 500 linhas e dão os mesmos valores que no ecrã |
| breadcrumb | 4 segmentos apresentados, os últimos do caminho; 6 ramos por menu de ramos (uma nota de demo diz o resto) e 6 sugestões de escrita |
| jsontree | As 200 primeiras linhas do documento apresentadas, 20 000 caracteres no máximo (uma linha mais longa é cortada); a pesquisa e a seleção ficam por elas |
| xmltree | As 200 primeiras linhas do documento apresentadas, 20 000 caracteres no máximo (uma linha mais longa é cortada); a pesquisa e a seleção ficam por elas |
| datagrid | 100 linhas apresentadas, exportações CSV e Excel desativadas, também a cópia (Ctrl+C) |
| markdownview | O início do documento: 40 blocos (um título, um parágrafo, uma entrada de lista, uma linha de tabela contam cada um como um; um bloco de código é cortado a 40 linhas) ou 4 000 caracteres do documento, o primeiro atingido — um bloco mais longo é cortado —, seguidos de uma nota; a pesquisa e o índice ficam por eles |
| form | 6 campos, os primeiros mostrados pela ordem do ecrã — um campo de uma secção recolhida também conta: expandi-la não redesenha nada; os outros ficam em memória e em of_values sem serem mostrados nem julgados |
| propertygrid | 8 linhas de propriedades, contadas pela ordem do ecrã (vista por categoria): um grupo fechado conta como uma linha, as suas subpropriedades só contam depois de o grupo aberto, os cabeçalhos de categoria não contam; o resto fica em memória e em of_values sem ser mostrado, e nem um resumo nem a pesquisa leem o seu valor |
| kanban | as 4 primeiras colunas visíveis, 5 cartões por coluna contados pela ordem da coluna entre os cartões visíveis, cada uma seguida de uma nota; a contagem e a soma de um cabeçalho só dizem os cartões desenhados; os outros ficam em memória e movem-se sem ser mostrados |
| gantt | 12 tarefas desenhadas, as primeiras linhas da grelha pela sua ordem (o conteúdo de um resumo recolhido não conta), seguidas de uma nota; as outras ficam em memória, no caminho crítico e nas datas e no progresso do resumo que as contém, sem serem mostradas nem selecionáveis |
| scheduler | Os 12 primeiros compromissos do intervalo no ecrã, os outros ficam em memória sem serem apresentados |
| angulargauge | Os 3 primeiros intervalos visíveis desenhados (um intervalo escondido não conta); os outros ficam em memória sem serem apresentados, e a chave definida mostra-os sem reenviar nada |
| chartcartesian | As 3 primeiras séries desenhadas, legenda incluída; as outras ficam em memória sem serem apresentadas, e a chave definida mostra-as sem reenviar nada |
| chartpie | As 5 primeiras fatias desenhadas, legenda incluída, e as percentagens calculadas sobre elas; as outras ficam em memória sem serem apresentadas, e a chave definida mostra-as sem reenviar nada |
| gauge | Os 3 primeiros intervalos visíveis desenhados (um intervalo escondido não conta); os outros ficam em memória sem serem apresentados, e a chave definida mostra-os sem reenviar nada |
| carousel | Os 6 primeiros elementos visíveis desenhados, pela ordem do carrossel (um elemento escondido não conta); os outros ficam em memória sem serem apresentados nem selecionáveis, e a chave definida mostra-os sem reenviar nada |
| treeview | Os 8 primeiros nós de cada nível desenhados, sob cada pai, pela ordem do modelo, e 200 nós em toda a árvore, os primeiros acrescentados — antes da ordenação, da pesquisa e da ocultação (um nó escondido conta, uma pesquisa ou uma ordenação nunca mostram o nono, lotes e grupos incluídos; um total nunca conta o que o limite esconde); os outros ficam em memória sem serem apresentados nem selecionáveis, e a chave definida mostra-os sem reenviar nada; of_export_csv e of_export_xlsx são recusados |
| dockcontainer | 3 painéis: o quarto of_add_panel devolve -6, o seu controlo fica no seu lugar, visível |
| codeeditor | As 200 primeiras linhas apresentadas e editáveis, seguidas de uma nota; as outras ficam em memória e em is_text sem serem apresentadas: a pesquisa, os marcadores e il_doc_line ficam pelas linhas apresentadas, e um texto colado que as ultrapasse junta-se às linhas em memória |
| Todos os restantes | Apenas o emblema — nenhum limite funcional |
Estes limites aplicam-se à apresentação: nada falha, a apresentação é truncada. É assim possível avaliar realmente cada componente, com os seus dados, antes da compra.
Atribuir uma chave válida levanta instantaneamente todos estes limites e retira o emblema, sem reiniciar a aplicação.
8.5 Perpétua + manutenção #
A licença é perpétua: as versões abrangidas pelo seu período de manutenção funcionam para sempre, inclusivamente após a expiração deste.
Na prática, a chave contém uma data de fim de manutenção, comparada com a data de compilação da DLL:
- uma versão da biblioteca publicada durante a sua manutenção fica desbloqueada definitivamente;
- uma versão publicada após a expiração devolve
-3: é necessário renovar a manutenção para lhe aceder; - as aplicações já entregues nunca são afetadas: incorporam a versão que sempre utilizaram.
8.6 Perguntas frequentes #
A minha chave é verificada online? Não. Nunca há rede. A verificação é uma assinatura RSA validada localmente pelo Windows.
Os meus clientes precisam de uma chave? Não. A sua chave runtime está na sua aplicação; eles nunca veem nada relativo à licença.
O que acontece se me esquecer de PBT_SetLicense em produção? A aplicação funciona, mas cada componente apresenta o emblema de demonstração e aplicam-se os limites da tabela acima. É o primeiro ponto a verificar se aparecer um emblema num cliente.
Posso atribuir uma chave dev e uma chave runtime no mesmo código? Sim — é aliás o caso habitual: a dev serve para a execução a partir do IDE, a runtime para a execução do exe. Cada uma é ignorada no outro contexto.
O emblema aparece embora a chave esteja atribuída. Três causas, por ordem de frequência: (1) chave dev quando se está a executar um exe compilado, ou o inverso; (2) retorno de PBT_SetLicense não testado — verificar se é igual a 0; (3) manutenção expirada para a versão de DLL instalada (retorno -3). PBT_LicenseStatus esclarece a situação numa linha.
Uma chave é nominativa. Uma chave dev está associada a um programador, uma chave runtime à sua empresa. Não devem ser partilhadas fora da sua equipa.