
During the creation of the next B2B system at the 1C: Enterprise 8.2 integration stage with the web interface, it became necessary to transfer large files from 1C to the web safely.
To solve this problem, SFTP was chosen as a reliable and unlimited transfer file size.
In the embedded language 1C: Enterprise 8.2, there are no functions for transmitting data via
SFTP , so I had to look for application tools.
On the Internet resources devoted to programming 1C, there are examples of successful use of freeware utilities like
WinSCP . To use this method, you need to run the utility from the embedded language 1C with command line parameters.
An example of running the WinCSP utility from 1C:
= (34)+()+"\"+ "WinSCP.com"+(34)+"/script="+(34)+()+(34)+"\script.txt "+"/parameter "+(34)++(34)+" "+ (34)++(34)+" "+(34) + + (34) + " " + (34) + + (34);
')
The downside of such a solution is the lack of control over startup errors and execution from the embedded language 1C. In this regard, it was decided to write an external DLL component for 1C: Enterprise 8.2.
The 1C: Enterprise platform supports two technologies for creating external components of the Native API and COM. The choice fell on the Native API, since the components created by this technology work both on the client and on the 1C server. Using materials from the ITS disk about the technology of creating external components and the open source library C ++, the file SftpExtension.dll was created (you can download the source
here ).
Creating a DLL Component1. For use in the SFTP component of the protocol, we used two libraries.
- libssh
http://www.libssh2.org/ (Download “git clone git: //git.libssh2.org/libssh2.git”)
- openssl
http://www.openssl.org/ (Download archive openssl-1.0.1c.tar.gz from
here )
We connect libraries to the project.
2. Each component object must be inherited from the abstract class IcomponentBase and IlanguageInterface.
- IcomponentBase - implements the main methods of the component.
- IlanguageInterface - serves to localize the methods and properties of 1C and C ++ through the definition of arrays of correspondences and methods of accessors GetMethodName, GetPropName.
Part of the component code describing the possibility of calling C ++ functions from 1C in Russian:
You can use other languages.
static wchar_t *g_MethodNames[] = { L"SendFile",L"StartSession", L"EndSession", L"IsSessionStart",L"SetSshHost",L"SetSshLogin",L"SetSshPass",L"SetSftpPath",L"SetLocalPath"}; static wchar_t *g_MethodNamesRu[] = { L"",L"",L"",L"", L"",L"",L"", L"",L""}; const WCHAR_T* SftpExtension::GetMethodName(const long lMethodNum, const long lMethodAlias) { if (lMethodNum >= eMethLast) return NULL; wchar_t *wsCurrentName = NULL; WCHAR_T *wsMethodName = NULL; int iActualSize = 0; switch(lMethodAlias) { case 0:
3. To call the required function from the component, use the CallAsFunc method from the IcomponentBase interface. When calling methods from 1C components, this C ++ method is called.
As parameters of the method are used:
- lMethodNum - the number of the method in the array of matches.
- pvarRetValue - pointer to output parameters.
- paParams - parameters from the method in 1C.
- lSizeArray - the size of the array, if the input parameter is an array.
bool SftpExtension::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue,tVariant* paParams, const long lSizeArray){ switch(lMethodNum){ case eMethSendFile: { if (!lSizeArray || !paParams) return false; this->local_path = toChar(paParams); WriteToServer(status, this->local_path);
4. In our example of 1C, you can perform 4 methods that correspond to the C ++ methods in the DLL component.
1C (methods) | C ++ methods |
---|
Start Session () Beforehand, it is necessary to define the authorization parameters (host, login, password - either rsa keys, the path on the remote server). Therefore, the Start Session function acquires the following properties: Host, Login, Password, Remote Path
| StartSSHSession (status, this-> ssh_host, this-> ssh_login, this-> ssh_pass); StartSftpSession (status, this-> sftp_path)
|
Send File (“Path and file name on client machine”)
| WriteToServer (const char * & status, const char * loclfile)
|
IfSessionStart () | isSessionStart () |
FinishSession () | endSession () - ends an SFTP session and an SSH session |
5. In C ++, you need to define access parameters (read / write) to the created properties; two methods, IsPropReadable and IsPropWritable, are responsible for this.
bool SftpExtension::IsPropReadable(const long lPropNum) { switch(lPropNum) { case ePropSshHost: return true; default: return false; } return false;}
Table of ratios of properties 1C and C ++
1C (properties) | C ++ properties |
---|
Host | ssh_host |
Login | ssh_login |
Password | ssh_pass |
Remote Path | Sftp_path |
The finished library can be downloaded
here .
Work with a component in the embedded language 1C1. We perform the connection and create an object of the external component using the standard commands of the embedded language 1C.
("C:\SftpExtension\SftpExtension.dll","",.Native); = ("AddIn..SftpExtension");
2. Fill 4 properties of the object components Host, Login, Password, Remote Path.
. = "192.168.0.1"; . = "root"; . = "123"; . = "/var/www/company/data/www/import/data.xml";
3. We open connection session
.();
4. Send the file
.("C:\data.xml");
5. We send the following file, with a check if the session of the connection is open.
.() .("C:\data2.xml"); .(); .("C:\data2.xml"); ;
6. After sending files, close the session.
.();
As a result of the execution, the file with C: \ data2.xml in /var/www/company/data/www/import/data.xml was successfully transferred.
Materials usedLiterature:
Manual to create componentsSFTP libraries:
Conclusion: this implementation allows to transfer files from 1C: Enterprise 8.2. large secure protocol SFTP. Plus, it is possible to transfer part of the functionality from 1C to the external component, which protects the written code and allows you to implement additional, not available 1C functionality.