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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Device Info - Micros CE 6.0 Terminals 2

Status
Not open for further replies.
Nov 29, 2004
21
US
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.
 
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.
 
Sure. It isn’t anything my work would care about me posting so I’ll post it tomorrow when I get in.
 
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?
 
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.
 
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!!
 
The CAL package failed to install on a WS5a. Oh well, was worth a shot. Thanks again.
 
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.
 
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:
This will dump the workstation types into a table called custom.workstation_types

Here is the SIM source code:

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


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.
 

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
 
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?
 
The serial number for the server is easy enough to grab but it isn't contained on the workstations in the software.
 
Gotcha. No WMI equivalent in CE. Just getting an accurate inventory of WS types is a huge win for us. Thanks again!!
 
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+
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top