INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Device Info - Micros CE 6.0 Terminals

Device Info - Micros CE 6.0 Terminals

(OP)
More of a Windows CE question, but has anyone found a way to query the model of Micros terminals remotely? I have a mix of WS4, WS5, and WS5a at multiple locations. Would like to do obtain an inventory list.

Is there a super-secret Micros utility that can be run from the RES BOH server or are the any bread crumbs in any log files?

Thanks.

RE: Device Info - Micros CE 6.0 Terminals

There is actually a utility that is supposed to do this but I lost track of it a while ago. Our solution was to create a CAL package that has the workstation write to a custom database table what kind of client it is. Tossed it out into the field, waited a few days, tossed out a script to scrub the cal package and query the custom table, and we had our results. Worked well given we have 800+ stores. If we need it again we just bump the CAL version and send it out again. This won’t differentiate things like a 2010 and 2015, but if I needed to do that including a win32 DLL could handle that easily enough to pull the model.

RE: Device Info - Micros CE 6.0 Terminals

(OP)
Wow!! Awesome idea. Any way you could share the package syntax?

RE: Device Info - Micros CE 6.0 Terminals

Sure. It isn’t anything my work would care about me posting so I’ll post it tomorrow when I get in.

RE: Device Info - Micros CE 6.0 Terminals

(OP)
Very cool. Look forward to it!!

RE: Device Info - Micros CE 6.0 Terminals

Actually, I found the one that Micros put out - it was in my dropbox instead of my google drive!

https://www.dropbox.com/sh/ih1kvn37220meq4/AAAnlo4...


That should work. These are all CAL packages. It retrieves more than just the model information - it is supposed to also grab things like RAM and compact flash size.

RE: Device Info - Micros CE 6.0 Terminals

(OP)
Thanks. Could I pick your brain a little more on this?

This will write the device info back to the Micros DB? What does the installer actually install? Something on the server?

RE: Device Info - Micros CE 6.0 Terminals

This actually is supposed to write it back to a text file on the C:\. The installer is supposed to just extract the cal packages from the first link. Word of warning, I can’t remember the last time I used this. If it isn’t working let me know and I can post the script you need that will get the model information using the SIM. The utility above isn’t the one I mentioned that writes to a custom table, it’s the one Micros put out.

RE: Device Info - Micros CE 6.0 Terminals

(OP)
Awesome. I reviewed WSInfo with a colleague. He said he has used it before and its pretty shaky in his experience. Would you mind sharing the script?

Also, I could have sworn I had a CAL scripting guide, but can't find it. There is such a doc, correct?

Thanks!!

RE: Device Info - Micros CE 6.0 Terminals

(OP)
The CAL package failed to install on a WS5a. Oh well, was worth a shot. Thanks again.

RE: Device Info - Micros CE 6.0 Terminals

In the C:\micros\documentation there is a .hlp file for SIM. Let me track down the CAL package we used and send that to you - are you able to remotely deploy .exe files to your stores?

I'll post the .exe we used plus the source code.

RE: Device Info - Micros CE 6.0 Terminals

Ok, so I couldn't find what we used so I just whipped this up, which means I'd test it in a lab or something first - not sure if it will work.

Executable: https://drive.google.com/file/d/0B1xagSWuDky9TXVsN...

This will dump the workstation types into a table called custom.workstation_types

Here is the SIM source code:

CODE --> ISL

EVENT INIT:

	VAR SQL_H : N12
	VAR SQL_CMD : A2000
	VAR CON_STATUS : N9 = 0

	DLLLOAD SQL_H, "MDSSysUtilsProxy.dll"
	IF SQL_H = 0
		EXITCONTINUE
	ENDIF
	DLLCALL_CDECL SQL_H, sqlInitConnection("micros", "ODBC;UID=custom;PWD=custom", "")
	DLLCALL_CDECL SQL_H, sqlIsConnectionOpen( REF CON_STATUS )
	IF CON_STATUS = 0
		EXITCONTINUE
	ENDIF

	FORMAT SQL_CMD AS "INSERT INTO CUSTOM.workstation_types (workstation_id, workstation_type) VALUES (", @WSID, ", {0})"
	DLLCALL_CDECL SQL_H, sqlExecuteQuery( SQL_CMD )

ENDEVENT 

And here is the code for the executable:

CODE

using Microsoft.Win32;
using System;
using System.Data;
using System.Data.Odbc;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
 
namespace CreateGetWorkstationType
{
    class Program
    {
        private static IDbConnection _IDbConnection;
 
        static void Main(string[] args)
        {
            /****
             * 
             * Will create a table called custom.workstation_types
             * 
             * Interface will cause all workstations to write the ID (object number in the workstation list in POS Config) plus their type
             * 
             * Types:
             * 
             * 0 - WS4
             * 1 - WS4LX
             * 2 - WS5
             * 3 - WS5A
             * 4 - Win32
             * 5 - Server
             * 
             * ***/
 
            using (_IDbConnection = new OdbcConnection("DSN=micros;UID=custom;PWD=custom"))
            {
                try
                {
                    _IDbConnection.Open();
                } catch (Exception ex)
                {
                    File.WriteAllText("exception.txt", ex.Message);
                    return;
                }
 
                //get object number to use for new interface
                int nextObjNum = 0;
                string sql_cmd = string.Format(
                @"SELECT FIRST o.obj_num + 1
                    FROM MICROS.interface_def as o
                    WHERE
                    (
                        SELECT i.obj_num
                        FROM MICROS.interface_def as i
                        WHERE i.obj_num = o.obj_num +1
                    ) IS NULL
                    ORDER BY obj_num"
                );
                var nextObjNumTbl = Query(sql_cmd, 30);
                if (nextObjNumTbl == null || nextObjNumTbl.Rows.Count == 0)
                {
                    File.WriteAllText("exception.txt", "Could not get next available object number from the interface table");
                    return;
                }
                int.TryParse(nextObjNumTbl.Rows[0][0].ToString(), out nextObjNum);
 
                //create interface
                sql_cmd = string.Format("INSERT INTO MICROS.interface_def (obj_num, name) VALUES ({0}, 'Get Workstation Type')", nextObjNum);
                Execute(sql_cmd, 30);
 
                //create custom table for the workstations to dump their type into
                sql_cmd = "CREATE TABLE CUSTOM.workstation_types (workstation_id INT, workstation_type INT)";
                Execute(sql_cmd, 30);
 
                //output the SIM file
                string pmsFile = string.Format("pms{0}.isl", nextObjNum);
                for (int i = 0; i < CALFolders.Length; i++)
                {
                    string simPath = Path.Combine(CALFolders[i], pmsFile);
                    string simContent = string.Format(Properties.Resources.pmsX, i);
                    File.WriteAllText(simPath, simContent);
                }
 
                //reboot all workstations to trigger the INIT event
                sql_cmd = "select lan_addr, lan_node_seq, workstation_type from micros.lan_node_def where lan_node_seq <> (select server_lan_node_seq from micros.rest_def) and (lan_node_seq in (select lan_node_seq from micros.dev_def where dvc_tbl_seq in (select uws_dev_seq from micros.uws_def)) or lan_node_seq in (select lan_node_seq from micros.dev_def where dvc_tbl_seq in (select order_device from micros.order_device_def))) order by lan_addr";
                var nodes = Query(sql_cmd, 30);
                foreach (DataRow node in nodes.Rows)
                {
                    RebootNode(node["lan_addr"].ToString());
                }
            }
        }
        public static void RebootNode(string WorkstationName)
        {
            Process p = new Process();
            p.StartInfo.FileName = MicrosPath + "\\Common\\Bin\\RemoteReboot.exe";
            p.StartInfo.Arguments = WorkstationName;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.Start();
        }
        public static DataTable Query(string QueryString, int timeout)
        {
            if (string.IsNullOrEmpty(QueryString))
                return null;
 
            using (IDbCommand Cmd = _IDbConnection.CreateCommand())
            {
                Cmd.CommandText = QueryString;
                Cmd.CommandTimeout = timeout;
                using (IDataReader DbDataReader = Cmd.ExecuteReader())
                {
                    if (DbDataReader.FieldCount == 0)
                        return null;
 
                    DataTable tempTable = new DataTable();
                    DataColumn tempColumn;
                    using (DataTable schemaTable = DbDataReader.GetSchemaTable())
                    {
                        for (int i = 0; i < schemaTable.Rows.Count; i++)
                        {
                            tempColumn = new DataColumn((string)schemaTable.Rows[i]["ColumnName"], (Type)schemaTable.Rows[i]["DataType"]);
                            //have to do this because numeric fields can be null in the micros database
                            tempColumn.AllowDBNull = true;
                            tempTable.Columns.Add(tempColumn);
                        }
                    }
 
                    DataRow tempRow;
                    while (DbDataReader.Read())
                    {
                        tempRow = tempTable.NewRow();
                        for (int i = 0; i < DbDataReader.FieldCount; i++)
                            tempRow[i] = DbDataReader[i];
                        tempTable.Rows.Add(tempRow);
                    }
                    return tempTable;
                }
            }
        }
        public static int Execute(string QueryString, int timeout)
        {
            if (string.IsNullOrEmpty(QueryString))
                return 0;
 
            using (IDbCommand Cmd = _IDbConnection.CreateCommand())
            {
                Cmd.CommandText = QueryString;
                Cmd.CommandTimeout = timeout;
                return Cmd.ExecuteNonQuery();
            }
        }
        public static string[] CALFolders
        {
            get
            {
                string microsPath = MicrosPath;
                string[] calFolders = new string[]
                {
                    microsPath + @"\Res\CAL\WS4\Files\CF\Micros\ETC\", //WS4
                    microsPath + @"\Res\CAL\WS4LX\Files\CF\Micros\ETC\", //WS4LX
                    microsPath + @"\Res\CAL\WS5\Files\CF\Micros\ETC\", //WS5
                    microsPath + @"\Res\CAL\WS5A\Files\CF\Micros\ETC\", //WS5A
                    microsPath + @"\Res\CAL\Win32\Files\Micros\Res\Pos\Etc\", //Win32
                    microsPath + @"\Res\Pos\Etc\", //Server
                };
                return calFolders;
            }
        }
        public static string MicrosPath
        {
            get
            {
                try
                {
                    string regPath = Is64Bit ? "SOFTWARE\\Wow6432Node\\Micros\\" : "SOFTWARE\\Micros\\";
                    var microsKey = Registry.LocalMachine.OpenSubKey(regPath);
                    if (microsKey == null)
                        return "C:\\Micros";
                    return microsKey.GetValue("DIR_MICROS").ToString();
                }
                catch (Exception ex)
                {
                    //if we can't get it from the registry, default to C:\Micros
                    return "C:\\Micros";
                }
            }
        }
        public static bool Is64Bit
        {
            get
            {
                bool is64bit = false;
                using (Process p = Process.GetCurrentProcess())
                    IsWow64Process(p.Handle, out is64bit);
                return is64bit;
            }
        }
 
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsWow64Process(
            [In] IntPtr hProcess,
            [Out] out bool wow64Process
        );
    }
} 

RE: Device Info - Micros CE 6.0 Terminals

Forgot to mention, when you have what you need, make sure to delete the interface or they will keep writing to that table every time the workstation reboot.

RE: Device Info - Micros CE 6.0 Terminals

If you're still looking at this, I actually ended up recreating the DLL we used because I was asked to query our stores again for a new program.

https://drive.google.com/drive/folders/0B1xagSWuDk...

Just drop the WSInfo folder in the CE folder in all the CE clients, and the Win32 package in the win32 folder. It will create a custom table called custom.workstation_info and dump the platform version, cal version, and workstation name into the table.

RE: Device Info - Micros CE 6.0 Terminals


Hello...

It does not have to do with the issue they are trying now, but in a previous issue I need to open a .isl file to make modifications for the issue of invoices. In the previous topic where the program was the links are down

RE: Device Info - Micros CE 6.0 Terminals

(OP)
Sorry for the late response. But, thank you for this. About to deploy to production after lab test. Works great. How hard would it be to pull the serial number as well?

RE: Device Info - Micros CE 6.0 Terminals

The serial number for the server is easy enough to grab but it isn't contained on the workstations in the software.

RE: Device Info - Micros CE 6.0 Terminals

(OP)
Gotcha. No WMI equivalent in CE. Just getting an accurate inventory of WS types is a huge win for us. Thanks again!!

RE: Device Info - Micros CE 6.0 Terminals

The most aggravating thing is, we use a number of different types of win32 clients. The 2010, 2015, and Workstation 6 don't reliably have serial numbers we can pull. In fact every Workstation 6 we've tested returns "Serial Number Placeholder" or something like that. Our non Micros units though return the actual serial number.


FYI if you going the DLL route instead of the SIM route, that DLL won't work on a Workstation 4 as it will only work on CE 5+

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close