Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MICROS RES3700 call execute file

Status
Not open for further replies.

jWattana

Programmer
Jan 11, 2019
5
TH
I want to run execute file such as "getCODE.exe". I tried to create script below
============
Event Print_Trailer : getCode
system "c:\getCODE.exe"
EndEvent
============
The error shows in picture.
How to call in SIM script, please kindy advised ?
a_jvfict.jpg
 
What does getCODE.exe do? Are you trying to print to the printer? Because that won't work if you are as the COM port is locked at that point.
 
The get_code.exe was generate random number and put at text file.
My script below. If it wrong, Could you advise ?
===========================
Event Print_Trailer : getCode
Var TrailerCnt : N5 = 0
Var TrailerLn : N5 = 1
Var MyLine1 : A50
Var loops : N5 = 20
Var i : N5

// get Code from text file
call get_Code

var fn : n5
var OpenFileName : a40
var line : A50
var read_code : A50

format OpenFileName as "c:\temp\get_code.txt"
fopen fn, OpenFileName, read
for i = 1 to loops
if fn = 0
break
endif
fopen fn, OpenFileName, read
endfor

freadln fn, line
format read_code as line
format MyLine1 as "CODE: ", read_code
@Trailer[TrailerLn] = MyLine1

EndEvent

sub get_Code
//**** get Code for print in trailer
// call program get_code.exe for generate code and put in text file.

var fname : A100 = "c:\temp\get_code.exe"
system fname

endsub
 
Well, are you seeing the get_code.txt being generated? If it is being called and creating the file, I could easily see this being a file lock issue. I don't think Micros waits for the exe to finish before continuing. Maybe.

Could you just write it as a C++ DLL? If you only plan to run it on win32 machines, you can write the DLL in Visual C++ rather than having to cobble together an IDE which can target CE.
 
Thank you for your advised. I will try to write to DLL.
One more, Do you know how to create script for checking file already in folder ?
such as the "a.txt" is existing in "c:\Temp\" or not.
 
If you are doing it with a DLL you don't even really need to write it to a file.

Something like this (just a mock up, haven't tested if it will compile or work):

Code:
#include <stdlib.h> 

extern "C" _declspec(dllexport) void GetRandomNumber(int& result) {
[indent]result = rand()[/indent]
}

and then in the SIM you could just do:

Code:
event print_trailer: getCode
[indent]var random : N50[/indent]
[indent]var dllhandle : N30[/indent]
[indent]DLLLOAD dllhandle, "GetCode.dll"[/indent]
[indent]DLLCALL_CDECL dllhandle, GetRandomNumber(random)[/indent]
[indent]var line : a50[/indent]
[indent]format line as "CODE: ", random[/indent]
[indent]@Trailer[1] = line[/indent]
endevent
 
I'm terrible with C++ honestly as I've never made an effort to learn it, but here is a sample of a fully functioning DLL that I call from SIM. I imagine anyone proficient in C++ would find it awful, but it works.

WSInfoWin32.h:

Code:
#ifndef _WSINFO_H_
#define _WSINFO_H_

#include <WinSock2.h>
#include <Windows.h>
#include <string>
#include <Winreg.h>
#include <sstream>
#include <IPHlpApi.h>
#include <WS2tcpip.h>


extern "C" __declspec(dllexport) void WriteInfo();
void GetRegString(HKEY regNode, const wchar_t* key, const wchar_t* valName, char* val, const wchar_t* defVal);
bool hasEnding(std::string const &fullString, std::string const &ending);
void Replace(char* input, std::string const& target, std::string const& repl);
SIZE_T GetMemory();
char* GetModel();
char* GetSerialNumber();
std::string GetIPAddresses();
#endif

WSInfoWin32.cpp:

Code:
#include "WSInfo.h"
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <Winreg.h>
#include <sstream>
#include <comdef.h>
#include <WbemIdl.h>
#include <IPHlpApi.h>
#include <WS2tcpip.h>

using namespace std;

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")

#define MAX_STRING_LENGTH 2000

typedef void(__cdecl* sqlInitConnection)(char* db, char* conString, char* dunno);
typedef void(__cdecl* sqlCloseConnection)();
typedef void(__cdecl* sqlGetLastErrorString)(char *error);
typedef void(__cdecl* sqlExecuteQuery)(char* cmd);
typedef void(__cdecl* sqlIsConnectionOpen)(int* conStatus);
typedef void(__cdecl* sqlGetRecordSet)(char* cmd);
typedef void(__cdecl* sqlGetNext)(char* output);

extern "C" __declspec(dllexport) void WriteInfo() {
	HINSTANCE dllHandle = NULL;
	dllHandle = LoadLibrary(L"MDSSysUtilsProxy.dll");
	if (dllHandle != NULL) {

		sqlInitConnection sqlInitConPtr = NULL;
		sqlCloseConnection sqlCloseConPtr = NULL;
		sqlGetLastErrorString sqlGetLastErrorPtr = NULL;
		sqlExecuteQuery sqlExecutePtr = NULL;
		sqlIsConnectionOpen sqlIsConnectionOpenPtr = NULL;
		sqlGetRecordSet sqlGetRecordSetPtr = NULL;
		sqlGetNext sqlGetNextPtr = NULL;

		sqlInitConPtr = (sqlInitConnection)GetProcAddress(dllHandle, "sqlInitConnection");
		sqlCloseConPtr = (sqlCloseConnection)GetProcAddress(dllHandle, "sqlCloseConnection");
		sqlGetLastErrorPtr = (sqlGetLastErrorString)GetProcAddress(dllHandle, "sqlGetLastErrorString");
		sqlExecutePtr = (sqlExecuteQuery)GetProcAddress(dllHandle, "sqlExecuteQuery");
		sqlIsConnectionOpenPtr = (sqlIsConnectionOpen)GetProcAddress(dllHandle, "sqlIsConnectionOpen");
		sqlGetRecordSetPtr = (sqlGetRecordSet)GetProcAddress(dllHandle, "sqlGetRecordSet");
		sqlGetNextPtr = (sqlGetNext)GetProcAddress(dllHandle, "sqlGetNext");

		BOOL foundAllFunctions = !(sqlGetNextPtr == NULL || sqlInitConPtr == NULL || sqlCloseConPtr == NULL || sqlGetLastErrorPtr == NULL || sqlExecutePtr == NULL || sqlIsConnectionOpenPtr == NULL || sqlGetRecordSetPtr == NULL);
		if (foundAllFunctions) {

			char lastError[MAX_STRING_LENGTH];
			int conOpen = 0;
			std::ostringstream sql_cmd;

			sqlInitConPtr("micros", "ODBC;UID=custom;PWD=custom;", "");
			sqlIsConnectionOpenPtr(&conOpen);

			if (conOpen != 0) {
				sqlGetRecordSetPtr("SELECT COUNT(*) FROM CUSTOM.workstation_info");
				sqlGetLastErrorPtr(lastError);

				if (strcmp(lastError, "") != 0)
					sqlExecutePtr("CREATE TABLE CUSTOM.workstation_info (name TEXT, model TEXT, physRAMBytes INT, CALVersion TEXT, SerialNumber TEXT, IPAddresses TEXT)");

				char* workstationName = new char[MAX_STRING_LENGTH];
				DWORD bufferSize = MAX_STRING_LENGTH;
				GetComputerNameA(workstationName, &bufferSize);

				sql_cmd.clear();
				sql_cmd << "DELETE FROM CUSTOM.workstation_info WHERE name = '" << workstationName << "'";
				sqlExecutePtr(&sql_cmd.str()[0]);

				char* CALVersion = new char[MAX_STRING_LENGTH];
				GetRegString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\MICROS\\CAL", L"CALVersion", CALVersion, L"UNKNOWN");

				string model = GetModel();

				sql_cmd.clear();
				sql_cmd.seekp(0);
				sql_cmd << "INSERT INTO CUSTOM.workstation_info (name, model, physRAMBytes, CALVersion, SerialNumber, IPAddresses) VALUES ('" << workstationName << "', '" << model << "', " << GetMemory() << ", '" << CALVersion << "', '" << GetSerialNumber() << "', '" << GetIPAddresses() << "')";

				sqlExecutePtr(&(sql_cmd.str()[0]));
				sqlCloseConPtr();
			}
		}

		FreeLibrary(dllHandle);
	}
}
void GetRegString(HKEY regNode, const wchar_t* key, const wchar_t* valName, char* val, const wchar_t* defVal) {
	HKEY hKey;
	LONG lRes = RegOpenKeyEx(regNode, key, 0, KEY_READ, &hKey);

	bool bExistsAndSuccess(lRes == ERROR_SUCCESS);
	bool bDoesNotExistsSpecifically(lRes == ERROR_FILE_NOT_FOUND);

	TCHAR buffer[MAX_STRING_LENGTH];
	DWORD bufferSize = MAX_STRING_LENGTH;
	ULONG nError = RegQueryValueEx(hKey, valName, 0, NULL, (LPBYTE)buffer, &bufferSize);

	RegCloseKey(hKey);

	size_t i;
	if (nError == ERROR_SUCCESS)
		wcstombs_s(&i, val, (size_t)MAX_STRING_LENGTH, buffer, (size_t)MAX_STRING_LENGTH);
	else
		wcstombs_s(&i, val, (size_t)MAX_STRING_LENGTH, defVal, (size_t)MAX_STRING_LENGTH);
}
void Replace(char* input, std::string const& target, std::string const& repl) {
	if (target.length() == 0)
		return;

	if (strlen(input) == 0)
		return;

	std::string src(input);
	size_t idx = 0;

	for (;;) {
		idx = src.find(target, idx);
		if (idx == std::string::npos)  break;

		src.replace(idx, target.length(), repl);
		idx += repl.length();
	}

	strcpy_s(input, MAX_STRING_LENGTH, src.c_str());
}
bool hasEnding(std::string const &fullString, std::string const &ending) {
	if (fullString.length() >= ending.length())
		return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
	else
		return false;
}
SIZE_T GetMemory() {
	MEMORYSTATUS status;
	status.dwLength = sizeof(MEMORYSTATUS);
	GlobalMemoryStatus(&status);
	return status.dwTotalPhys;
} 
char* GetSerialNumber() {
	IWbemLocator *locator = nullptr;
	IWbemServices *services = nullptr;


	auto hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
	hResult = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&locator);

	auto hasFailed = [&hResult]() {
		if (FAILED(hResult)) {
			auto error = _com_error(hResult);
			return true;
		}
		return false;
	};

	auto getValue = [&hResult, &hasFailed](IWbemClassObject *classObject, LPCWSTR property) {
		std::wstring propertyValueText = L"Not set";
		VARIANT propertyValue;
		hResult = classObject->Get(property, 0, &propertyValue, 0, 0);
		if (!hasFailed()) {
			if ((propertyValue.vt == VT_NULL) || (propertyValue.vt == VT_EMPTY)) {
			}
			else if (propertyValue.vt & VT_ARRAY) {
				propertyValueText = L"Unknown"; //Array types not supported
			}
			else {
				propertyValueText = propertyValue.bstrVal;
			}
		}
		VariantClear(&propertyValue);
		return propertyValueText;
	};
	std::wstring serialNumber = L"Not set";
	if (!hasFailed()) {
		// Connect to the root\cimv2 namespace with the current user and obtain pointer pSvc to make IWbemServices calls.
		hResult = locator->ConnectServer(L"ROOT\\CIMV2", nullptr, nullptr, 0, NULL, 0, 0, &services);

		if (!hasFailed()) {
			// Set the IWbemServices proxy so that impersonation of the user (client) occurs.
			hResult = CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL,
				RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);

			if (!hasFailed()) {
				IEnumWbemClassObject* classObjectEnumerator = nullptr;
				hResult = services->ExecQuery(L"WQL", L"SELECT * FROM Win32_BIOS", WBEM_FLAG_FORWARD_ONLY |
					WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &classObjectEnumerator);
				if (!hasFailed()) {
					IWbemClassObject *classObject;
					ULONG uReturn = 0;
					hResult = classObjectEnumerator->Next(WBEM_INFINITE, 1, &classObject, &uReturn);
					if (uReturn != 0) {
						serialNumber = getValue(classObject, (LPCWSTR)L"SerialNumber");
					}
					classObject->Release();
				}
				classObjectEnumerator->Release();
			}
		}
	}

	if (locator) {
		locator->Release();
	}
	if (services) {
		services->Release();
	}
	CoUninitialize();

	size_t i;
	char* sNum = new char[MAX_STRING_LENGTH];
	wcstombs_s(&i, sNum, (size_t)MAX_STRING_LENGTH, serialNumber.c_str(), serialNumber.length());
	return sNum;
}
char* GetModel() {
	// Obtain the initial locator to Windows Management on a particular host computer.
	IWbemLocator *locator = nullptr;
	IWbemServices *services = nullptr;


	auto hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
	hResult = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&locator);

	auto hasFailed = [&hResult]() {
		if (FAILED(hResult)) {
			auto error = _com_error(hResult);
			//TRACE(error.ErrorMessage());
			//TRACE(error.Description().Detach());
			return true;
		}
		return false;
	};

	auto getValue = [&hResult, &hasFailed](IWbemClassObject *classObject, LPCWSTR property) {
		std::wstring propertyValueText = L"Not set";
		VARIANT propertyValue;
		hResult = classObject->Get(property, 0, &propertyValue, 0, 0);
		if (!hasFailed()) {
			if ((propertyValue.vt == VT_NULL) || (propertyValue.vt == VT_EMPTY)) {
			}
			else if (propertyValue.vt & VT_ARRAY) {
				propertyValueText = L"Unknown"; //Array types not supported
			}
			else {
				propertyValueText = propertyValue.bstrVal;
			}
		}
		VariantClear(&propertyValue);
		return propertyValueText;
	};
	std::wstring manufacturer = L"Not set";
	std::wstring model = L"Not set";
	if (!hasFailed()) {
		// Connect to the root\cimv2 namespace with the current user and obtain pointer pSvc to make IWbemServices calls.
		hResult = locator->ConnectServer(L"ROOT\\CIMV2", nullptr, nullptr, 0, NULL, 0, 0, &services);

		if (!hasFailed()) {
			// Set the IWbemServices proxy so that impersonation of the user (client) occurs.
			hResult = CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL,
				RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);

			if (!hasFailed()) {
				IEnumWbemClassObject* classObjectEnumerator = nullptr;
				hResult = services->ExecQuery(L"WQL", L"SELECT * FROM Win32_ComputerSystem", WBEM_FLAG_FORWARD_ONLY |
					WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &classObjectEnumerator);
				if (!hasFailed()) {
					IWbemClassObject *classObject;
					ULONG uReturn = 0;
					hResult = classObjectEnumerator->Next(WBEM_INFINITE, 1, &classObject, &uReturn);
					if (uReturn != 0) {
						manufacturer = getValue(classObject, (LPCWSTR)L"Manufacturer");
						model = getValue(classObject, (LPCWSTR)L"Model");
					}
					classObject->Release();
				}
				classObjectEnumerator->Release();
			}
		}
	}

	if (locator) {
		locator->Release();
	}
	if (services) {
		services->Release();
	}
	CoUninitialize();
	if (model.compare(L"Montara Family of Chipsets") == 0)
		return "PCWS 2010";
	if (model.compare(L"Calpella Platform") == 0)
		return "PCWS 2015";
	std::string converted_str(model.begin(), model.end());
	size_t i;
	char* returnVal = new char[MAX_STRING_LENGTH];
	wcstombs_s(&i, returnVal, (size_t)MAX_STRING_LENGTH, model.c_str(), model.length());
	return returnVal;
}
string GetIPAddresses() {
	DWORD rv, size;
	PIP_ADAPTER_ADDRESSES adapter_addresses, aa;
	PIP_ADAPTER_UNICAST_ADDRESS ua;

	rv = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &size);
	if (rv != ERROR_BUFFER_OVERFLOW)
		return "N/A";
	adapter_addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);
	rv = GetAdaptersAddresses(AF_INET, 0, NULL, adapter_addresses, &size);
	if (rv != ERROR_SUCCESS)
		return "N/A";
	ostringstream ipAddresses;
	int count = 0;
	for (aa = adapter_addresses; aa != NULL; aa = aa->Next) {
		for (ua = aa->FirstUnicastAddress; ua != NULL; ua = ua->Next) {
			char buf[256];
			memset(buf, 0, 256);
			getnameinfo(ua->Address.lpSockaddr, ua->Address.iSockaddrLength, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
			if (strcmp("127.0.0.1", buf) == 0)
				continue;
			if (count > 0)
				ipAddresses << "|";
			ipAddresses << buf;
			count++;
		}
	}
	return ipAddresses.str();
}
 
Thank you very much for your help. I haven't ever write C++. But I have C#.
I tried to test command below. It shown error "Undefine Function". What is wrong ?

Microsoft Visual Studio Community 2017 C# version 15.9.5
================================
public class TestcallbySIM
{
public string Hello(string name, string surname)
{
string ret = "I am " + name + " " + surname + ".";
return ret;
}
}


RES 3700 v5.1
===============================
event print_trailer: getCode
var iam : N50
var dllhandle : N30
DLLLOAD dllhandle, "c:\test\testSIM.DLL"
DLLCALL_CDECL dllhandle, Hello("J", "Wat", iam)
var line : a50
format line as "I am ", iam
@Trailer[1] = line
endevent

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top