Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Pass a file (containing workstations) into an Array in a Console application

Posted on 2009-04-01
9
Medium Priority
?
458 Views
Last Modified: 2013-12-17
My goal is this. I'm eventually going to have some workstations passed into a Stored Procedure variable, which will in turn, pass that to a Console.exe file as an argument to process a list of workstations to be pinged.
I want to pass a file containing workstations (using ; (semicolon) as the delimiter, as an argument to a Console application. I'm a little bit familiar with the ProcessStartInfo class. Can someone tell me how to setup passing this file to an Array?
Most grateful to anyone and thank you Experts,
Wally
0
Comment
Question by:wally_davis
  • 6
  • 3
9 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 24043857
You would probably be better simply passing the path to the file rather than trying to pass the file itself and letting the console app read the file and load its contents into an array itself.
0
 

Author Comment

by:wally_davis
ID: 24044075
There is going to be another process that will pass thousands of workstations to an SP variable and when that SP kicks off, it will pass in thousands of workstation names which will in turn initiate my Console app and will need to pass in all of those workstation names to the console as an argument which will then be taken and stored to a ListCollection or an Array to be further processed.
Speaking the SP, How would you pass in all of that data from the SP into a Console app as an Argument?
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 24044259
Passing thousands of parameters to a console app will be problematic partly because of the length limit for command line arguments. But trying to invoke a console app from an SP will be problematic in itself because you will need xp_cmdshell which will be disabled on a lot of systems (assuming you are using SQL Server).

You may want to consider having your SP store the workstations in a table and have your console app talk to the database to retrieve them that way.
0
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 

Author Comment

by:wally_davis
ID: 24044297
Trust me. I know it sounds crazy. I've done everything short of telling the person they're out of their minds send data to an SP variable. I wanted the data in a Table and they're insistent on doing it the way they want to. It's hell on me and that's why I'm out here on EE looking for some Expert help.
That being said, we can use the xp_cmdshell (believe it or not) so that is an option. We currently use SQL 2005. I need to figure out how to pass this so called file to the Command Line as an argument and have the Console store it into an Array. As AxxBackwards, as this sounds, is it possible and if so, how could I implement it?
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 24044424
Its possible up to a point but, as i said earlier, there is a limit on the length of command line arguments which may become an issue for you if try to pass too much.

Having said that, all you need to do is call the command line app from your SP with something like:

    DECLARE @Workstations VARCHAR(MAX);
    SET @Workstations = 'Workstation1,Workstation2,Workstation3';

    DECLARE @CommandLine sysname;
    SET @CommandLine = 'C:\MyConsoleApp.exe "' + @Workstations + '"';

    EXEC xp_cmdshell @CommandLine;

Then as a simple sample console app, this will read in the command line parameter and output each entry to a file:


static void Main(string[] args)
{
    List<string> workstations;
 
    if (args.Length > 0)
    {
        // load command line arg into List<string> assuming comma-seperated values
        workstations = new List<string>(args[0].Split(new char[] { ',' }));
 
        System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\Ouput.txt");
        foreach (string s in workstations)
            sw.WriteLine(s);
 
        sw.Close();
    }
}

Open in new window

0
 

Author Comment

by:wally_davis
ID: 24044695
Carl,
I'm getting the error "Incorrect syntax near the keyword 'DECLARE'.
See SP code below:

USE DMS
GO
 
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
CREATE Procedure RunPingUtil
  DECLARE @Workstations varchar(max);
  SET @Workstations = 'B001617259BA7,B001E371E21B2,B001422C95811';
								      -- Passing in Wkstn values'
 
DECLARE @CommandLine sysname;
SET @CommandLine = 'C:\Test\ProofOfConcept.exe ''' + @Workstations + '''';
 
EXEC xp_cmdshell @CommandLine;
 
GO

Open in new window

0
 

Author Comment

by:wally_davis
ID: 24046844
Figured it out. I'll get back with results in the a.m. here in Arizona.
0
 

Author Comment

by:wally_davis
ID: 24050274
Carl, Everything is in place. However, when I execute the SP, it's giving me some Security issues. I used xp_cmdshell not too long ago within our Company and I know it still works: Here's the errors below. If you happen to know what the probable cause is that would be great. I'll also post the current code below per your suggestions above and your code at to my C# Code.

NULL
Unhandled Exception: System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
   at System.Threading.ThreadPool.SetMaxThreads(Int32 workerThreads, Int32 completionPortThreads)
   at ProofOfConcept.Program.Main(String[] args)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.SecurityPermission
The first permission that failed was:
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="ControlThread"/>
NULL
The demand was for:
<PermissionSet class="System.Security.PermissionSet"
version="1">
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="ControlThread"/>
</PermissionSet>
NULL
The granted set of the failing assembly was:
<PermissionSet class="System.Security.PermissionSet"
version="1">
<IPermission class="System.Security.Permissions.FileDialogPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Access="Open"/>
<IPermission class="System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Allowed="ApplicationIsolationByUser"
UserQuota="512000"/>
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="Execution"/>
<IPermission class="System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Window="SafeTopLevelWindows"
Clipboard="OwnClipboard"/>
<IPermission class="System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Url="file://B001C231FC4CC/c$/Test/ProofOfConcept.exe"/>
<IPermission class="System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Zone="Internet"/>
<IPermission class="System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
version="1"
Level="SafePrinting"/>
</PermissionSet>
NULL
The assembly or AppDomain that failed was:
ProofOfConcept, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
The method that caused the failure was:
Void Main(System.String[])
The Zone of the assembly that failed was:
Internet
The Url of the assembly that failed was:
file://B001C231FC4CC/c$/Test/ProofOfConcept.exe
NULL

------------- SP --------------------------
USE DMS
GO
 
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
ALTER Procedure RunPingUtil
AS
BEGIN
	SET NOCOUNT ON;
 
DECLARE @Workstations varchar(max)
SET @Workstations = 'B001617259BA7,B001E371E21B2,B001422C95811'
 
DECLARE @CommandLine sysname
SET @CommandLine = '\\B001C231FC4CC\c$\Test\ProofOfConcept.exe ''' + @Workstations + ''''
 
EXEC xp_cmdshell @CommandLine
 
END
GO
--------------- C# CODE -----------------------------------
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Data.SqlClient;
using System.Diagnostics;
 
namespace ProofOfConcept
{
    class Program
    {
        // This is not used at the moment... but may be...
        static void UpdateDatabase(Object database)
        {
 
        }
 
        // The threadpool's threads call this with the argument "new "String( node.NodesToPing)" 
        // that is passed to QueueUserWorkItem and so, each computer is pinged quickly in the
        // PingWorkstations() method when added to the threadpool.
        static void PingWorkstations(Object threadContext)
        {
            String computer = (String)threadContext;
            // PingThreadContext pc = (PingThreadContext)threadContext;
            
            string status = "";
            string epAddress = "";
 
            SqlConnection conn = new SqlConnection(SettingsManager.ConnectionString);
            SqlCommand sqlCmd = new SqlCommand("usp_PingStatus", conn);
            sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
 
            try
            {   
                // Verify host is in DNS first
                IPHostEntry IPHost = Dns.GetHostEntry(computer);
 
                // Ping the workstation, get status and update DB
                foreach (IPAddress address in IPHost.AddressList)
                {
                    Ping p = new Ping();
 
                    try
                    {
                        // Based on the Ping Status will determine which
                        // case to process.
                        PingReply pr = p.Send(computer);
                        switch (pr.Status)
                        {
                            case IPStatus.Success:
                                sqlCmd.Parameters.AddWithValue("Status", "Reachable");
                                sqlCmd.Parameters.AddWithValue("Endpoint", computer);
                                sqlCmd.Parameters.AddWithValue("IPAddress", (address != null) ? address.ToString() : 
                                                                IPAddress.None.ToString());
                                sqlCmd.Parameters.AddWithValue("DTStamp", DateTime.Now);
 
                                status = "Reachable";
                                epAddress = (address != null) ? address.ToString() : IPAddress.None.ToString();
                                //Console.WriteLine(computer + " - Sweet");
                                break;
                            case IPStatus.TimedOut:
                                sqlCmd.Parameters.AddWithValue("Status", "Timed Out");
                                sqlCmd.Parameters.AddWithValue("Endpoint", computer);
                                sqlCmd.Parameters.AddWithValue("IPAddress", (address != null) ? address.ToString() :
                                                                IPAddress.None.ToString());
                                sqlCmd.Parameters.AddWithValue("DTStamp", DateTime.Now);
 
                                status = "Timed Out";
                                epAddress = (address != null) ? address.ToString() : IPAddress.None.ToString();
                                //Console.WriteLine(computer + " - Timedout");
                                break;
                            case IPStatus.DestinationHostUnreachable:
                                sqlCmd.Parameters.AddWithValue("Status", "Host Unreachable");
                                sqlCmd.Parameters.AddWithValue("Endpoint", computer);
                                sqlCmd.Parameters.AddWithValue("IPAddress", (address != null) ? address.ToString() :
                                                                IPAddress.None.ToString());
                                sqlCmd.Parameters.AddWithValue("DTStamp", DateTime.Now);
 
                                status = "Host Unreachable";
                                epAddress = (address != null) ? address.ToString() : IPAddress.None.ToString();
                                //Console.WriteLine(computer + " - Timedout");
                                break;
                            case IPStatus.DestinationNetworkUnreachable:
                                sqlCmd.Parameters.AddWithValue("Status", "Network Unreachable");
                                sqlCmd.Parameters.AddWithValue("Endpoint", computer);
                                sqlCmd.Parameters.AddWithValue("IPAddress", (address != null) ? address.ToString() :
                                                                IPAddress.None.ToString());
                                sqlCmd.Parameters.AddWithValue("DTStamp", DateTime.Now);
                                status = "Network Unreachable";
                                epAddress = (address != null) ? address.ToString() : IPAddress.None.ToString();
                                break;
                            case IPStatus.Unknown:
                                sqlCmd.Parameters.AddWithValue("Status", "unknown");
                                sqlCmd.Parameters.AddWithValue("Endpoint", computer);
                                sqlCmd.Parameters.AddWithValue("IPAddress", "NA");
                                sqlCmd.Parameters.AddWithValue("DTStamp", DateTime.Now);
 
                                status = "unknown";
                                epAddress = "NA";
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error occurred: " + ex.Message);
                    }
 
                    //Open a DB connection.... SEND THE DATA CLOSE IT
 
                    try
                    {
                        // Lets add the data to the DB
                        conn.Open();
                        sqlCmd.ExecuteNonQuery();
                        Console.WriteLine("EP Status : {0} \nEP Name: {1} \nEP Address: {2}\n", status, computer, address );
                    }
                    catch
                    {
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
            // If no DNS Record exists then update
            // Endpoint information in nodes table
            catch
            {
 
                sqlCmd.Parameters.AddWithValue("Status", "No DNS Record");
                sqlCmd.Parameters.AddWithValue("Endpoint", computer);
                sqlCmd.Parameters.AddWithValue("IPAddress", "NA");
                sqlCmd.Parameters.AddWithValue("DTStamp", DateTime.Now);
 
                status = "No DNS Record";
                epAddress = "NA";
 
                conn.Open();
                sqlCmd.ExecuteNonQuery();
                Console.WriteLine("EP Status : {0} \nEP Name: {1} \nEP Address: {2}\n", status, computer, epAddress);
                conn.Close();
 
            }
        }
 
        /* When availThreads = maxThreads the 
         * entire ThreadPool has completed being
         * processed and a Sleep of 1 second before
         * the next ThreadPool starts processing
         */
        static void WaitForPool()
        {
            int maxThreads = 0;
            int placeHolder = 0;
            int availThreads = 0;
            while (true)
            {
                System.Threading.ThreadPool.GetMaxThreads(out maxThreads, out placeHolder);
                System.Threading.ThreadPool.GetAvailableThreads(out availThreads, out placeHolder);
                if (availThreads == maxThreads) break;
                System.Threading.Thread.Sleep( 1000 );                
            }
 
            return ;
        }
        /* -----------------------------   Main () Program entry ------------------------------ */
 
        // This is the Collection List property
        // that will hold each workstation value
        // that will eventually get pinged.
        public string nodeToPing;
        public string NodeToPing
        {
            get { return nodeToPing; }
            set { nodeToPing = value; }
        }
 
 
        static void Main(string[] args)
        {
 
            // Do Database Query Here.....
            // This will hold the entire workstation 
            // list that is pulled from the Nodes table
            List<Program> nodeList = new List<Program>();
            List<string> workstations;
            
            if (args.Length > 0)
            {
                // Load command line arg into List<string> collection
                // assuming comma-seperated values
                workstations = new List<string>(args[0].Split(new char[] { ',' }));
                foreach (string wkstn in workstations)
                {
                    Program node = new Program();
                    node.NodeToPing = wkstn;
                    nodeList.Add(node);
                }
 
            }
 
                if (nodeList.Count > 0)
                {
                    // parameters( max # of worker threads in thread
                    // pool and max # asynchronous IO threads in pool)
                    System.Threading.ThreadPool.SetMaxThreads(65, 10);
                    System.Threading.ThreadPool.SetMinThreads(65, 10);
 
                    /* For each computer in the computer list,
                     * each computer to be pinged by the PingWorkstations()
                     * method gets passed to the QueueUserWorkItem to be
                     * processed by the threadpool thread. 
                     * Each workstation to be pinged gets added to the pool
                     * and processed quickly.
                     */
                    foreach (Program node in nodeList)
	                {
                		System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(PingWorkstations), node.NodeToPing );
	                }
                }
 
                /* This little baby is the "ShamWow" it waits till all those threads in the threadpool 
                * are done... and you will say "Wow" everytime.
                * It's made in Germany, lol. This method processes and completes each threadpool before 
                * moving onto the next threadpool.
                */
                WaitForPool();
            }
        }
    }

Open in new window

0
 

Accepted Solution

by:
wally_davis earned 0 total points
ID: 24063448
This question was answered in combination with two previous threads I had Carl working on so and has now been resolved. This one can be closed as it was a redundant question.
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question