Run DOS Commands from .NET with Free msDOScommand Class
The msDOScommand class, written in Visual Basic.Net, executes MS-DOS commands and provides both status and results.
Features:
* A guarantee that results are complete as a string from each of one or more MS-DOS commands. This is provided by terminating each MS-DOS command in a submitted batch with a dummy file create command. The existence of the dummy file (which is erased by default) proves when tested by msDOScommand that your prior commands executed...avoiding the very dangerous phenomenon of random failures in MS-DOS calls.
* Full thread safety which means that while one instance CANNOT issue more than one command for competing execution, you can access the Status property of this class while waiting for an MS-DOS job, and perform other work while waiting for the command.
You can download the msDOSCommand code here (2MB zip file).
Of course, there is no such thing as MS-DOS in a forensic sense and the existence of this particular black hole has long been a scandal of Windows. Since Windows is proprietary, the formal existence of the green screen world is fabular, spoken about in hushed terms around de campfire as The Land that Time Forgot into which developers have wandered never to return.
It has historically been difficult to convince many computer users that a GUI-based OS needs a line by line interface at all, since industrial specialization convinces us that anything so apparently peripheral must be a waste of our time. The notion of levels of an OS in which a GUI is naturally an evolution from a still existent green screen of line by line commands becomes as dangerous as biological evolution, and the user prefers to think of digital phenomena as *sui generis*, and that Intelligent Designers at Windows developed Windows in six days, and that on the Seventh day, they rested.
MS-DOS becomes like sex unmentionable despite the fact that many programs continue to issue MS-DOS commands in a cybernetic back alley. msDOScommand is my humble attempt to make explicit and hence safer the process of my own emission of MS-DOS commands in a follow-on project I am working on, to replace the Windows search command with the little puppy dog with something both faster, and more dignified, that isn't broken, as Windows search seems to be, by the use of international and otherwise non-standard file identifiers.
The forbidden land, the Land Before Time, of MS-DOS is constituted only by the existence of legacy but possibly ineradicable-in-future-releases command such as the shell() command of VB.Net, which is the only facility used by this class to issue commands to MS-DOS (if shell() disappears, this class won't work anymore).
MS-DOS becomes like an old dusty VCR recording of Mom and Dad having sex in 1983. This means that the shell() command is issued with shame, and this shame itself causes bugs. "Programming on purpose", in a phrase of P. J. Plauger, becomes impossible.
Because of the need to deal with potential folklore, this class makes minimal committments and as described above, creates an extra work file (subsequently erased) to make sure insofar as is possible in a nonstandard proprietary environment that the command submitted actually worked.
Pragmatically, and the above intemperate remarks aside, the class removes the VB programmer from having to code asynchronous calls to shell() to run MS-DOS commands.
The software as available comes with a comprehensive test form and application for Windows/.Net which allows you to create an msDOScommand instance, inspect it, test it, and so forth.
Also provided are new versions of the windowsUtilities.DLL and the utilities.DLL libraries originally shipped with my book Build Your Own .Net Language and Compiler.
msDOScommand was written in accordance with the Core Procedure method I described in Build Your Own, therefore instances have a Name, a dispose(), a self-inspect and a test() procedure. This makes instances more trustworthy than many classes.
I do ask that msDOScommand be used ethically. It has no special code for preventing evil commands such as creation of unknown cookies or erasing files. Since you will have the source you can consider adding these safeguards.
You can download the msDOSCommand code here (2MB zip file).
Ethical considerations re msdosCommand
The current version can issue pathological commands, as I have said. Moreover, the version I am working on has the capability of behaving as did one of the first computer virus, the unix self-replicating virus that was created by Robert Tappan Morris of Cornell University in 1987.
Now, the source code could itself undertake to scan commands for safety, and it could also limit the number of threads in the new version.
But, this would be a misallocation of my time.
This is because I would code the checks perforce as clearly as any other code, having a prior committment to transparency, therefore, the checks could be removed given that the source is distributed.
The fact is that shell() already exists, and that Microsoft is responsible for the relative lack of security that is created by a failure to acknowledge, properly, the existence of MS-DOS (for example, one searches in vain for a BNF definition of a Windows file that is not violated with impunity by third parties that use "invalid" identifiers to encode and international software, and I had to devise a minimal BNF in fileFinder).
Now, it SOUNDS pretty sleazy to say "not my responsibility". But this is because the fashion today is Zero Tolerance and Personal Responsibility as a sort of pose.
Again: all this code allows you to do is issue shell() safely. It merely replicates some features already available in .Net shell but in a more transparent and OO fashion.
Converting msDOSCommand to Visual Basic Express
msDOSCommand converts to Visual Basic Express easily. VB Express is a free VB.Net but unlike the older Learning editions, more full-featured.
The VB Express compiler, when used to compile the source code of msDOSCommand as downloaded from Developer Dot Star, emits more than a hundred warnings and three errors.
The warnings all have to do with local variables declared, mostly in utilities.vb, but not used, and local variables declared without explicit assignment of a starter value that are then used as reference parameters.
I agree with Microsoft in the latter case that it is poor practice to declare a variable without assigning it and then pass it by reference.
The errors are in one case statement in datatype_() in utilities where a case statement checks an object for number values, and, it is easily fixed: go to datatype_() and find Select Case objValue: change this to Select Case CType(objValue, integer).
Justa suggestion
I really like your work. It is impressive. I made a small change that helped me alot. For example if the command was "net" with no options, the user would get nothing back. It is helpful to get error message. In windows XP you can redirect stderr, unlike previous other Windows OSes. So I modified line 2433 to add the stderr redirection:
strCommands &= " > " & enquote(strOutputId) & " 2<&1"
I have not tested yet but it oughta work. I will probably also add a conditional test to determine the OS so it only applies the 2
Thanks, Steve!
Interesting point (that in XP you can redirect stderr). It confirms that MS-DOS still exists, exists in multiple versions, and is being evolved by a group of gnomes and elves at Microsoft.
I see them in my mind's eye, happy and contented at having a secure job but in a corner of the lunchroom muttering darkly about what new features they can sneak in.
Having a permanent job maintaining old software leading to a cozy retirement is for me the road not taken. I was maintaining a compiler but when I ran out of work like an idiot I looked for another job.
I am working on a new version with a script language but this has diverted me into a Garden of Forking Paths in which I'd like to follow up on some issues with the Build Your Own compiler, which will power the script language. I will incorporate stderr redirect.
Great to hear that my code is useful as always.
New vers with asynch commands will NOT be available in a day or
so. I have gotten sidetracked with some deeper issues.
I will endeavor in future to do a better job of making and keeping committments. My apologies if you were waiting for this new version.
Consider changing the source code yourself if you need this feature.
Again: my apologies.
New Version of msdoscommand vb.net
Just curious as the comment dates are over a year old. Will there ever be a "new version" or have you moved on to other things?
Thank you for what you have done. I am NOT a programmer. I "cut-n-paste" together samples, examples, and freebies to make my .net code do what I need for monitoring my network. None of it was possible before I found the msdoscommand class.
Thanks.
msdosCommand
Glad you found it. Sure you are not a programmer? I won't be working on new releases, probably, having a number of higher-priority projects to hand. But let me know if you have any specific comments or change requests.
Ping away
I wrote msdosCommand because "they" (the suits) expect us to monitor the network in a sort of perverted vigil, watching it all night long. This is silly. You should be able to issue pings and other commands from a monitor, go home and go to bed.
When my wife was suffering from postpartum depression, I had to drag my butt down to Tulsa, Oklahoma, essentially to babysit a network so one suit could say to another that they had a passel of "experts" on the case.
One has better things to do, and msdosCommand was written so you can do them safely, whence its timeout controls and so on.
Check out Dan Read's discussion of error handling and don't stop learning new things.
vb.net help
Hi sir,
how to run a ms dos batch work file in vb.net code.
ex: if create a .txt fiel by using stream write how to give the print command in dos print. please help me sir.
thanking you
running dos command in vb.net
hai Edward i have a doubt like i amtrying to run a batch file in vb.net but its not working ,created a new thread to run this (basically i was using Shell to do tht).Only for the application am running its not working but if i create a new application and try the same its working .any idea why it doesn't work in one and work in the other.Is it that the main thread is restricting other threads not to function properly.after running the application it shows the dos screen but doesn't perform the function properly....please let me know if you have experienced anything similar
Regards
Thomas
Are you using msdosCommand?
That's the free software on this site which handles many of the problems, and comes with documentation about handling other problems.
Here's what I think your problem may be...
Just running shell() in a different thread is NOT the answer.
This is because the new thread is accessing system files through the pseudo-DOS interface completely outside of .Net.
Meanwhile, other .Net threads are doing the same thing.
This creates collisions, possibly deadlocks.
My software at least tries to address the problem that exists when you use a safe-appearing legacy library function like shell() in Visual Basic, which runs well under .Net, but contains "gotchas" both as regards internationalization and here, the system facilities that are issued when you issue a batch command through shell.
The basic problem: when you issue any VB library command that violates thread safety, YOU are thread unsafe and YOUR program will "seem to work" at first, but then crash or hang, usually when you are proudly demonstrating your work to the boss from hell, who would like to fire you.
shell() is completely thread unsafe because in the batch command, it can do ANYTHING. This is an instance of the paradox of computing "power": you are empowered to mess up.
Not only are other threads in your application constantly interacting with the Windows file system, other applications on your system are doing the same.
msdosCommand cannot fully address all these problems. Instead, it provides a primitive framework in which to create the batch file and make sure it runs through to completion.
The contents of the batch file can still be dangerous. They can erase the user's hard disk, for starters.
It looks like you are doing it "your" way, therefore my advice is to do it "my" way.
Download the msdosCommand software, read the documentation, drink the Kool Aid and use the class.
printing from DOS software to modern (non-dotmatrix) printers
Can you help me find out how to print from DOS software to inkjet type modern printers rather than to just the old Epson compatible dot matrix type printers. I have some DOS programs that I use a lot but would like to have the capability of obtaining the Epson fonting on the newer printers.
Thank you for any information or help you can give me.
Bernie Tonroy


New version will be available in a day or so
I am working on a new version of this code. It allows the user to prefix any MS-DOS command with a semicolon. The effect is that the command is issued with no wait as is the default behavior.
If a semicolon precedes any command in the Command batch of 0..n newline-separated MS-DOS commands, then that command is used to create a new instance of the msdosCommand class running a new thread, running the doCommand() method already available.
I added this because in an MS-DOS command script, I wanted to serenade myself with the French and the Dutch national anthems, which involved calling Windows Media Player as a command line. There is no need to "wait" because of course WMP creates a Windows application.
Of course, the true destination is an msdosCommand class which supports a Turing-complete programming language in its Command script, but this awaits some further work on the fileFinder for finding frigging files in the f*d up environment of Windows!
I will upload the new version of msdosCommand in a day or so with semicolon-prefixed asynchronous commands.
Many thanks to Daniel Read for his assistance on these posts.