
I think you all know such software as 1C: Enterprise 8.2. And, probably, many of you know the fact that you can connect to 1C: Enterprise using an OLE / COM connection. And how many of you know that using OLE / COM connections, you can not only execute 1C program code, but also “manage” a 1C: Enterprise server? For example, you can connect to the 1C: Enterprise Server Cluster Agent, get a list of open client sessions, read information about licenses issued to them ... In addition, having a connection option through an OLE / COM connection expands the programmer’s ability to select a different programming language in the arsenal from the built-in language 1C: Enterprises. You can choose any language that can work with OLE / COM components: be it VB.Net, C # .Net, or Java, or even ... Perl. Yes, you heard right. It is Perl.
So…
Task.
It is necessary to implement the automatic restart of the 1C: Enterprise Server Agent Service 8.2 using the Windows Task Scheduler. But before restarting, you need to check whether someone is working in the Base, located on the 1C: Enterprise server. If someone works, then restarting the service is not allowed.
Decision.
You may sneak a question, they say, why do you need to restart the Server Agent service periodically? The fact is that in version 1C: Enterprise 8.2 x64 there is one “small” error. It occurs when the information database is dynamically updated and results in the database being unable to update and work in it. The developers officially (in personal correspondence with them) stated that this error is not planned to be fixed in version 8.2. We'll have to wait and “survive” before the official release of 8.3. I know a way to correct this error (if necessary - I will tell in the comments or update the article). But, as the developers assure, this workaround can destroy the database altogether. In my year of using this method of circumventing, the base has not collapsed. But not about this article.
')
So. Task set. The main problem for me was the condition of checking existing connections to a specific database. To accomplish the task, I decided not to use the built-in 1C: Enterprise language, none of the .Net languages, and also Java (only console, only true linux-way).
In the 1C: Enterprise helper syntax, a method was found to check for connections to the database, but it assumed the use of an OLE / COM connection to the 1C: Enterprise Server Agent. Well ... let's get down to it.
Extract from syntax helperConnection with server agent (IServerAgentConnection)
GetInfoBaseConnections (GetInfoBaseConnections)
Syntax:
GetInfoBaseConnections (<Cluster>, <InformationBase>)
Options:
<Cluster> (required)
Type: Server Cluster. The server cluster for which the array of connection descriptions should be obtained.
<InformationBase> (required)
Type: Description of the information base. Information base for which an array of connection descriptions should be obtained.
Return value:
Type: COMSafeArray. An array of cluster connection descriptions. Each connection description is represented by an object with an interface Connection Description.
Description:
Gets an array of descriptions of the information database connections.
Availability:
Integration.
To work with OLE / COM objects using Perl, we need to use the Win32 :: OLE module. In the StrawberryPerl assembly I used, this module was already preinstalled. But even if it is not, you can install it via CPAN:
C:\Perl\perl\bin\cpan Win32::OLE
To get the list of 1C database connections, we need:- Create a COM connection to the V82.COMConnector object;
- Connect to the 1C: Enterprise server cluster agent;
- Get the object cluster 1C;
- Log in to the cluster;
- Get a list of 1C databases on this cluster;
- Find the base we need;
- Get a list of active connections to this database.
Here is a code with comments that gets a list of active client connections to the 1C: Enterprise database located on the 1C: Enterprise server.
use strict; use warnings; use Win32::OLE; use Data::Dumper; sub getConnectionsCount {
You can restart the Agent service using the “net start” and “net stop” commands:
net stop <> net start <>
I located the full code that accomplished the task on
Bitbucket .