I am trying to run a JSFL script from within a C# project, where the JSFL script opens up a .fla file, modifies it n times, and exports n .swf files before closing. From the C# project, I am starting up the JSFL script through the Process class. I try to wait for the JSFL process to finish through the myProcess.WaitForExit() command, but it doesn't work. The remainder of my code C# executes before the JSFL process finishes exporting its .swf files. Is there any way I can throw something that the C# project can catch from the JSFL file or some other solution?
One solution (although most likely not the best one) would be for your C# code to look for the SWF files being created. Only once they've been updated/created will the JSFL script have finished, so you know that it will be safe for your C# to move on. In case there is no way of knowing how many SWF files the C# program needs to look for, you could instead let the JSFL script write to a log file of some sort, and to have the C# program read that log on a interval, looking for some sort of token to indicate that the JSFL script has completed it's task.
Granted, this may be far from the best method (and I don't know C# well enough to know whether what you're seeing is by design or a sign of something being wrong). But it may just be the case that running JSFL/Flash is completely asynchronous and if so, maybe the log file approach is the quickest path to solving the problem.
I have the same problem with another application that calls an external JSFL script.
What I do is write a file once finished to a target directory, and in the calling application, poll for that file. As soon as the file appears, I know the task has finished, and I delete the temp file, and carry on. Oh - and before starting I look for and delete any temp files so I don't get a false positive.
It's not so nice as events, but you have to work with what you've got.
Have you tried to set a custom Listener that will execute a function when the JSFL done. Don't forget that it's still based on ECMA which is a procedual language.
By the way, JSFL has a LOW-LEVEL C API.
C LEVEL API
This is absolutely possible, and I've already posted a solution here on stack overflow, complete with a detailed problem description and all the C# and JSFL source code necessary to implement it: Automating publishing of FLA files; calling Process.Start multiple times
To summarize... first of all, waiting on the JSFL script process is useless, because you're actually calling Flash.exe, which will remain open/running after the JSFL completes, so you'd be waiting on a process exit event that will never occur.
The trick is to use a JSFL function at the end of the JSFL script which executes a windows command line command, and it's that call which will signal your C# app that the JSLF script has completed. So basically you'll have your main instance of your C# app, but you want to modify your C# app so that a 2nd instance can be run from a command line with a particular switch. When you're C# app is called with a particular switch (from the JSLF file), then instead of running normally, you want your program to simply signal a wait handle in the main instance of your application and then close. I use a simple third-party open-source library called XDMessaging, which facilitates such inter-process communication. It lets you open a named channel in your C# app, which can receive a command from the 2nd instance, signaling the main instance that the JSFL script has finished and it's safe to continue.
But involving file watcher like this is not the best solution so I catch the Flash process and keep watch on the process title and tell the JSFL render some window title for the flash window after finish the execution.
Related
I am looking for an idea on how I can launch a C# process based on something happening on a Windows server. My first challange is to determine when to start the first process. It needs to monitor a SFTP folder to see if a certain file type has been delivered. My initial thought was to have the task scheduler start a Perl script, have the script look to see if the file exists and then start the process. But once it has started the process, I don't want it to look for the file till the next day.
The second issue is that the first process moves files to another folder and then a third party application will start converting these files from PDFs to TEXT. The second process needs to start when this is done. I am not sure how to make this happen.
Thoughts??????
Write a windows service which uses a filewatcher to monitor for new files. https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
That can then use File.Move to move the file out and into the alternate directory for further processing. https://msdn.microsoft.com/en-us/library/system.io.file.move(v=vs.110).aspx
I would use a Task for this and a task.continuewith to kick off the next 'stage' of your workflow, etc. Might also want to do a file COPY first, then a file delete (instead of a move, that way if something screws up during the copy you still have your original to work with).
I'm writing a GUI in c#, in which when the uesr click on a button, the GUI calls for kitty.exe (which is exactly like PuTTy.exe, with extra features) to run some command in Linux, during this time there's a log on kitty ssh command shell which is passed to a log file (using KiTTY embedded feature). When it is finished, I check the log file for the word 'Succeed' or 'Fail'.
What I do nowadays is I wait (using the 'sleep' command in c#) 2 minutes, then I check the log file. This does work, but I want it to be more efficient, because it sometimes take 90 sec and sometimes 60 sec, and I don't want to wait so long after it is finished. Furthermore, it's not so elegant solution :o).
My question is how (and if) can I check the log running on the SSH windows in real time, and search for the key words (succeed or fail), rather than just wait for it to finish and then check it.
using the '>' in cmd.exe to call the kiTTy.exe and pass its log to a file does not work, by the way.
Thank you!
If you invoke your system process using System.Diagnostics.Process.Start(), then you can use the WaitForExit method after invoking. That will block further execution on the thread until the process completes at which point you can check the log. This may be preferable to waiting an arbitrary amount of time.
If you want to do it in real time rather than waiting until completion, there is a facility to get a stream reader via System.Diagnostics.Process.StandardOutput which you can use to look for the item of interest.
I have essentially two programs:
main.exe
update.exe
Update creates a flag file (update.inprogress) so that main cannot run while the update is in progress.
If main opens and that file exists, it immediately exits to prevent a program in use conflict.
I'm only having one issue. If the update is in process, the main program closes without and reason when they try to go in. I need to tell them the program is updating to keep them from calling us that the world has come to an end...
My question is, how can I issue a message that the update is in progress without tying up the main.exe? If I issue it from main.exe, then it will be in use and cannot be updated.
I was thinking of opening up notepad and putting a message in there but that just seems like a bad way of doing it.
I could also create another exe that only displays this message, but, if I have to update it, it will be in use too.. kind of defeats my purpose.
Anyone have a better idea?
Clarification:
This is a peer-to-peer network. The update could be run on workstation XYZ and someone could attempt to get into the main.exe at workstation ABC. This is why I am using a flag file. I have to way to check the process running on another workstation.
I assume that when update.exe runs, it does not need to update itself? If that is the case, you can modify update.exe to invoke main.exe if no updates are necessary.
For instance, if an update is necessary(you can accomplish this via a adding a version number to your main.exe and checking it), update.exe will create your update.inprogress file and run the updates. Then if another instance of update.exe runs, it will see the update.inprogress file and alert the user that update is in progress and terminate itself without tying up main.exe. If update.exe runs when no updates are necessary and update.inprogress does not exist, it will invoke main.exe programmatically.
I would suggest to create a thread from your update.exe to check for the existence of your main.exe process. In case it shows up, alert the user with a message from your update.exe.
I am working on method in a DLL. In my method I have been writing to the event log to allow me to determine whether things are working as I expect. One of the tasks I do in the method is create a process and run a command line application and I want to be able to capture the output of this that is normally written to the console and write it to the eventlog.
Code:
Process getNextIons = new Process();
getNextIons.StartInfo.FileName = #"""C:\Program Files\OpenMS-1.6\PrecursorIonSelector.exe""";
getNextIons.StartInfo.Arguments = #"-ini ""C:\Program Files\OpenMS-1.6\precursorionselector.ini""";
getNextIons.StartInfo.UseShellExecute = false;
getNextIons.StartInfo.RedirectStandardOutput = true;
getNextIons.Start();
getNextIons.WaitForExit();
System.Diagnostics.EventLog.WriteEntry("FMANWiff", "IPS: " + getNextIons.StandardOutput.ReadToEnd());
I have a console test application that calls my method and when I do this I am able to see that the process was started and ran correctly, however when I actually try to make use of the DLL, not using the test application, all I end up seeing is an entry:
IPS: And none of the output. I can tell it is running, however, as I can see a number of output files being updated.
Why am I not getting any output and how I can rectify this?
According to the Process.StandardOutput documentation your code has a potential deadlock.
When the caller reads from the redirected stream of a child process, it is dependent on the child. The caller waits on the read operation until the child writes to the stream or closes the stream. When the child process writes enough data to fill its redirected stream, it is dependent on the parent. The child process waits on the next write operation until the parent reads from the full stream or closes the stream. The deadlock condition results when the caller and child process wait on each other to complete an operation, and neither can proceed.
To avoid the possible deadlock, the last two lines of your sample code should be switched. You should also consider redirecting StandardError.
In your library, instead of writing directly to the location of choice you should be using
System.Diagnostics.Trace. By using Trace you can have your outside console application or whatever it be subscribe to the Trace event using a TraceListener.
By using Trace and TraceListeners, you can make you application adaptable to whatever logging situation you require without having to modify your library every time you want to change the logging system.
Below is a link to another Stack Overflow thread about trace logging with some good examples and information.
How can I add (simple) tracing in C#?
I'm creating a (C#) program that downloads binaries using NZB files, there may only be one instance of my application running at any time.
So when a user doubleclicks an .nzb-file and my program is not running, it should start and process it (easy, file registration).
Now if my program is already running, I do NOT want to launch a second instance - I want the already-running instance to pick up the specified file.
Making my app single-instance can be done using the Visual Basic DLL with the .IsSingleInstance trick, but I don't want to go there.
The right way seems to be to use a mutex to ensure my app is single-instance,
but now I'm stuck on how to pass the specified parameter (the .nzb file) to the already-running instance.
Help would be appreciated ! :-)
Try this: Your main program creates a named pipe or other interprocess communication facility and listens on it. You create a separate small program that, when run with an NZB file as a parameter, opens the pipe, feeds the file info into it, and exits. Your main program then processes the new file and downloads it.
Why not have one program that adds the file to a queue, and then kicks off the downloading program if it is not already running. That downloading program watches the queue, which is just a file that you append download file names to.
Look at the InitialInstanceActivator at the Genghis project
Use an IPC (inter process communication) mechanism such as .net remoting