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.

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