0

I'm trying to run interactive RPG/MAPICS programs from C#. To do this, I'm trying to launch a .ws file via PCSWS.EXE and write input to it from C#.

The emulator launches just fine, but I can't seem to be able to send input to it, either by Standard Input or by SendMessage (I tried both via SETTEXT and KEYDOWN).

What am I doing wrong, here? How should I approach launching an interactive RPG program from C#?

public void LaunchRPGApp(Application program)
{
    var processInfo = new ProcessStartInfo("pcsws.exe")
    {
        WindowStyle = ProcessWindowStyle.Normal,
        Arguments = "\"C:\\Program Files (x86)\\IBM\\Client Access\\Emulator\\Private\\veflast1.ws\"",
        RedirectStandardInput = true,
        UseShellExecute = false,
    };
    var process = Process.Start(processInfo);

    SendTextToProcess(process, "f");//Try via SendMessage

    using (var sr = process.StandardInput)//Try via StdIn
    {
        sr.Write("f");//does nothing
        sr.Close();
    }
}

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
private void SendTextToProcess(Process p, string text)
{
    const int WM_SETTEXT = 0x000C;
    const int WM_KEYDOWN = 0x0100;
    const int F_KEY = 0x46;
    Thread.Sleep(500);
    var child = FindWindowEx(p.MainWindowHandle, new IntPtr(0), "Edit", null);
    SendMessage(child, WM_KEYDOWN, F_KEY, null);//does nothing
    SendMessage(child, WM_SETTEXT, 0, text);//does nothing
}
Sarov
  • 545
  • 6
  • 17
  • Do you understand that `C:\Program Files (x86)\IBM\Client Access\Emulator\Private\veflast1.ws` is not a windows scripting file, but a workstation file from IBM Client Access? – jmarkmurphy Jun 22 '18 at 11:06
  • @jmarkmurphy I wasn't sure what it was, but it was, at least, clear it wasn't a scripting file. I've never worked with workstation files before. I assume that means input just can't be sent to one? – Sarov Jun 22 '18 at 13:09
  • I don't know what you mean. It is a configuration file for the 5250 emulator of Client Access. It doesn't make sense to send input to it as it is not a program. – jmarkmurphy Jun 22 '18 at 14:00
  • Step back a little farther, what are you trying to accomplish? We need some context as you are obviously heading in the wrong direction. – jmarkmurphy Jun 22 '18 at 14:03
  • @jmarkmurphy My initial goal is to be able to (somehow) launch interactive RPG programs from a C# desktop application. At my company, everyone currently accesses such via running those .ws files, which is why I tried going the route of spawning a process for it and sending input to that process. – Sarov Jun 22 '18 at 14:06
  • Ok, so you may still be able to do that with windows scripting, but you will need to write a windows script file. For computers that have IBM Client Access installed, `.ws` is likely associated with `PCSWS.EXE`. I suspect that a windows script that can send keystrokes to an open window can do what you want to do after you have started `PCSWS.EXE` with the appropriate configuration (`.ws`) file. – jmarkmurphy Jun 22 '18 at 15:02
  • Maybe you should check if `.ws` is actually associated with `PCSWS.EXE`. – jmarkmurphy Jun 22 '18 at 15:14

2 Answers2

1

Here is something to try, I am not a C# programmer, but I found this here

ProcessStartInfo startInfo = new ProcessStartInfo("pcsws.exe");
startInfo.WindowStyle = ProcessWindowStyle.Normal;

startInfo.Arguments = "C:\\Program Files (x86)\\IBM\\Client Access\\Emulator\\Private\\veflast1.ws";
Process.Start(startInfo);

There is documentation on the command line arguments for PCSWS.EXE here

jmarkmurphy
  • 11,030
  • 31
  • 59
  • Once I added \" around the path, it managed to run the emulator just fine, but I'm still not sure how to send input - while it did let me redirect the standard input and send input, that input did not seem to appear within the emulator. – Sarov Jun 22 '18 at 15:57
  • Maybe `PCSWS.EXE` doesn't accept standard input. Maybe you have to send keystrokes to the window? – jmarkmurphy Jun 22 '18 at 16:21
  • Can't seem to get keystrokes to work, either. I've updated my Question to include the PCSWS.EXE, though; thank you for that. – Sarov Jun 22 '18 at 19:09
  • Got it - see my Answer below. Thanks for your assistance. – Sarov Jun 25 '18 at 18:30
1

Found the solution - a VBScript macro may be run on starting the PCSWS.EXE by appending "/M={macroName}" to the arguments. Note that the macro must exist in a specific folder. The macro then sends keystrokes using autECLSession.autECLPS.SendKeys.

Like so:

public void LaunchRPGApp(Application program)
{
    MakeMacro(program);

    const string wsPathAndFilename =
        "C:\\Program Files (x86)\\IBM\\Client Access\\Emulator\\Private\\flast1.ws";
    var processInfo = new ProcessStartInfo("pcsws.exe")
    {
        Arguments = "{wsPathandFilename} /M=name.mac"
    };
    Process.Start(processInfo);
}

private void MakeMacro(Application program)
{
    var macroText = GetMacroText(program);//Method to get the content of the macro

    var fileName =
        $"C:\\Users\\{Environment.UserName}\\AppData\\Roaming\\IBM\\Client Access\\Emulator\\private\\name.mac";

    using (var writer = new StreamWriter(fileName))
    {
        writer.Write(macroText);
    }
}
Sarov
  • 545
  • 6
  • 17