• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

return information from dos shell

Journer

Banned
is there any way to run dos shell commands and return their output directly into your program? currently i'm just executing a process that outputs the results to a file, but it would be 10x easier if i didn't have to deal with all these filestreams and whatnot. any ideas?
 
If you're launching these commands from within your own process, depending on the language you are using, you should be able to capture the ouput stream and error stream from those programs. You can then parse it and do whatever you need to.
 
You can do something like this:

ProcessStartInfo args = new ProcessStartInfo();
// Set properties of args
using (Process someProcess = Process.Start(args))
using (TextReader reader = someProcess.StandardOutput)
{
// This call forces MAIN to wait for the process to finish. Addresses the deadlock issue discussed nicely on MSDN.
// myLog is my internal logger that writes to a text file.
myLog.WriteLine(reader.ReadToEnd());
someProcess.WaitForExit();

reader.Close();
someProcess.Close();
}
 
well the problem is i don't have access to the programs code...this is what i'm trying to do:

butil -stat filename returns things like this:

Btrieve Utilities Version 4.11
Copyright 1982, 1988, Novell, Inc. All Rights Reserved.

File Stats for ACTS-PAY.DAT
Record Length = 406 Variable Records = No
Number of Keys = 3
Page Size = 4096 Unused Pages = 0
Total Records = 12418

Key Position Length Duplicates Modifiable Type Null Total

0 24 21 No Yes Lstring -- 12418
0 2 13 No Yes Lstring -- 12418
1S 95 7 Yes Yes Lstring -- 4587
2S 2 13 Yes Yes Lstring -- 12216

all i need is the filename and the total records, the problem is though that different versions of the program output the results in a slightly different format, so if the wording is off a little bit it doesnt work
 
for example, here is another version of the output from a later version of butil:

Btrieve Maintenance Utility 9.10.020.000
Copyright (C) Pervasive Software Inc. 2005
All Rights Reserved.

File Statistics for ACTS-PAY.DAT

File Version = 6.00
Page Size = 512
Page Preallocation = No
Key Only = No
Extended = No

Total Number of Records = 5721
Record Length = 406
Data Compression = No
Variable Records = No

Available Linked Duplicate Keys = 0
Balanced Key = No
Log Key = 0
System Data = No
Total Number of Keys = 3
Total Number of Segments = 4

Key Position Type Null Values* ACS
Segment Length Flags Unique Values
0 1 24 21 Lstring M -- 5721 --
0 2 2 13 Lstring M -- 5721 --
1 1 95 7 Lstring RMD -- 2630 --
2 1 2 13 Lstring RMD -- 5376 --

Legend:
< = Descending Order
D = Duplicates Allowed
I = Case Insensitive
M = Modifiable
R = Repeat Duplicate
A = Any Segment (Manual)
L = All Segments (Null)
* = The values in this column are hexadecimal.
?? = Unknown
-- = Not Specified

The command completed successfully.
 
Since the output is nondeterministic, you can use Regex's to create a "pool" of all valid sets of strings you're looking for. If there are 9 different versions of butil, you'll possibly have 9 different Regex's OR'ed together.
 
Originally posted by: tfinch2

What does that have to do with reading console output from an external process?

EDIT: I see now the software he is using is Pervasive software.

This still doesn't make sense! He's trying to parse certain words from what is being output to the Console. You want to elaborate, KLin?
 
dhaval: ill look into regex, never done anything with it before

KLin: i can't/dont want to use SQL connections for this. it would be such a pain in the ass that it wouldn't be worth it
 
Why not? You create a connection to whatever file you need, do a select count(*) from the file, then you're done.
 
Looks like pervasive 9.1 to me. I was able to get a recordcount in MS access pretty easily using an ADO connection.
 
Well I'm able to get the recordcount from a pervasive sql table in a C#.net console app. Yes I'm that bored on a Friday night. 😛
 
Originally posted by: Dhaval00
KLin: Maybe you should go through the entire thread, and actually read the problem. Journer has no issues "selecting" data.

I have read the thread. The OP stated he just needed 2 pieces of information in a previous post. The recordcount of a file and the filename itself.


 
Originally posted by: KLin
Originally posted by: Dhaval00
KLin: Maybe you should go through the entire thread, and actually read the problem. Journer has no issues "selecting" data.

I have read the thread. The OP stated he just needed 2 pieces of information in a previous post. The recordcount of a file and the filename itself.

My take on it was that Journer doesn't have access to the file. If he has, then what you suggested will/might work.
 
IMO, if the OP can run the butil utility to get the stats, then he has access to the database files(or tables) to be able to query them directly in C#.

Here's what I did to get it to work:

1. downloaded/installed pervasive sql 9.5 workgroup version and the pervasive .net provider.
2. Got the list of tables from the demodata database using a dir *.wkd /b (.dat files is probably an older version of pervasive).
3. Wrote the following ugly ugly code into a console app. 😛

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;



namespace SQLTest {
class Program {
static int Main(string[] args) {
int retval = 0;
string[] tables = new string[10];
tables[0] = "BILLING";
tables[1] = "CLASS";
tables[2] = "COURSE";
tables[3] = "DEPT";
tables[4] = "ENROLLS";
tables[5] = "FACULTY";
tables[6] = "PERSON";
tables[7] = "ROOM";
tables[8] = "STUDENT";
tables[9] = "TUITION";

string strConn = "Provider=PervasiveOLEDB;Data Source=DEMODATA;";
string strCommand;
OleDbConnection conn = new OleDbConnection(strConn);
OleDbDataAdapter adapter = new OleDbDataAdapter();
try {


for (int i = 0; i < tables.Length; i++)
{
strCommand = "SELECT Count(*) As TotalCount from " + tables;
adapter.SelectCommand = new OleDbCommand(strCommand, conn);
conn.Open();
DataSet ds = new DataSet();
adapter.Fill(ds);
foreach (DataTable dt in ds.Tables)
foreach (DataRow dr in dt.Rows)
{
Console.WriteLine("RecordCount = " + dr["TotalCount"]+ " for table: " + tables + "\n");
}
conn.Close();
}
Console.WriteLine("Processing complete.");
} catch (Exception ex) {
Console.WriteLine("Error occurred!");
Console.WriteLine(" Error message: " + ex.Message);
Console.WriteLine(" Error detail: " + ex.ToString());
retval = 1;
}
// Code to keep console window open after program execution.
// This is valuable if you are building your code from an IDE
// like VS.NET or SharpDevelop.
Console.Write("\nPress ENTER to continue");
Console.Read();
return retval;
}
}
}
 
woops left square bracket i right square bracket enables italics in the forum code. Forgot about that.


EDIT: And of course the add code button is still broke. 🙁
 
Klin: thanks for trying things out, glad i could occupy your bored Friday night, lol. Anyways, i'll try this out with my dat. files and see what i can come up with.

Dhavel: i do have access to the files. it's just a had a script that would output all the results i needed into a flat file and i figured it would be easier to just parse the file. but, ill try the code klin wrote and see if that makes things easier
 
Originally posted by: Journer
Klin: thanks for trying things out, glad i could occupy your bored Friday night, lol. Anyways, i'll try this out with my dat. files and see what i can come up with.

Dhavel: i do have access to the files. it's just a had a script that would output all the results i needed into a flat file and i figured it would be easier to just parse the file. but, ill try the code klin wrote and see if that makes things easier

I can email you the solution if you'd like, or just the code, so you can try it out. Send me a PM if you want.

 
Source=COMMENTS.DAT;

string[] tables = new string[10];
tables[0] = "COMMENTS";

thats all i changed. but i get the following errors that make no sense to me sense pervasive is running fine on this system.

Error occurred!
Error message: The 'PervasiveOLEDB' provider is not registered on the local mac
hine.
Error detail: System.InvalidOperationException: The 'PervasiveOLEDB' provider i
s not registered on the local machine.
at System.Data.OleDb.OleDbServicesWrapper.GetDataSource(OleDbConnectionString
constr, DataSourceWrapper& datasrcWrapper)
at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString cons
tr, OleDbConnection connection)
at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOpti
ons options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection o
wningObject)
at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
at System.Data.OleDb.OleDbConnection.Open()
at SQLTest.Program.Main(String[] args) in C:\Documents and Settings\jburns\My
Documents\Visual Studio 2008\Projects\cmdTest\cmdTest\Program.cs:line 41

Press ENTER to continue

do i need another library or something? also, keep in mind i'm programming this on vs08, but in 2.0 compat mode...cannot use any framework higher than that for now
 
i dont think it is going to work for me if i have to install a provider. the goal is to get my program to work without any extra dependencies aside from .net2.0
 
Originally posted by: Journer
i dont think it is going to work for me if i have to install a provider. the goal is to get my program to work without any extra dependencies aside from .net2.0

You don't need to add any references to the code for the provider. The provider just needs to be installed on the machine since you're using the provider as part of the connection string.
 
Originally posted by: KLin
Originally posted by: Journer
i dont think it is going to work for me if i have to install a provider. the goal is to get my program to work without any extra dependencies aside from .net2.0

You don't need to add any references to the code for the provider. The provider just needs to be installed on the machine since you're using the provider as part of the connection string.

yah, in that case, i can't use it because that would require installing the provider to get my program to work. the problem is, once this application is finished, it needs to run on the following environment with no other frameworks or anything to be installed:

sql server 05
.net 2.0
pervasive 8 or later

i'm pretty sure i can handle the sql 05 queries with no problem since they are built into the 2.0 framework, but as i thought earlier...pervasive wont be doable without this extra installation :'(

hmm,looking into it further, i cant even use the ado package at all because it is only supported on 8.7 and up. we have users that are on version well under that. looks like i'm going to have to stick to butil -stat and regex :/ now to figure out how the hell regex works
 
Back
Top