Thursday, July 10, 2014

C# Using PSTool PsExec to execute programs on remote systems 2

Small update. I haven't implemented all the remarks of Cjorn yet.

public interface IValidator
    {
        DirectoryInfo OutputDirectoryFromClient { get; set; }
        DirectoryInfo OutputDirectoryOnServer { get; set; }
        DirectoryInfo WorkbenchDirectoryFromClient { get; set; }
        DirectoryInfo WorkbenchDirectoryOnServer { get; set; }

        FileInfo FileToValidate { get; set; }
        FileInfo FmeBatch { get; set; }
        FileInfo FmeWorkbench { get; set; }

        FileInfo PsExec { get; set; }
        FileInfo FmeExec { get; set; }

        string UserName { get; set; }
        string Password { get; set; }
        string ServerName { get; set; }

        string StandardError { get; }
        string StandardOutput { get; }

        void Validate();

    }

public class Validator : IValidator
    {
        public DirectoryInfo OutputDirectoryFromClient { get; set; }

        public DirectoryInfo OutputDirectoryOnServer { get; set; }

        public DirectoryInfo WorkbenchDirectoryFromClient { get; set; }

        public DirectoryInfo WorkbenchDirectoryOnServer { get; set; }

        public FileInfo FmeBatch { get; set; }

        public FileInfo FileToValidate { get; set; }

        public FileInfo FmeWorkbench { get; set; }

        public FileInfo PsExec { get; set; }

        public FileInfo FmeExec { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

        public string ServerName { get; set; }

        public string StandardError { get; private set; }

        public string StandardOutput { get; private set; }


        private void CreateSourceCopy()
        {
            File.Copy(FileToValidate.FullName, WorkbenchDirectoryFromClient.FullName + "source.sdf");
        }

        private void RemoveSourceCopy()
        {
            if (File.Exists(WorkbenchDirectoryFromClient.FullName + "source.sdf"))
                File.Delete(WorkbenchDirectoryFromClient.FullName + "source.sdf");
        }

        private void RemoveOutput()
        {
            if (File.Exists(OutputDirectoryFromClient.FullName + "validated.sdf"))
                File.Delete(OutputDirectoryFromClient.FullName + "validated.sdf");
        }

        public void Validate()
        {
            RemoveSourceCopy();
            RemoveOutput();

            CreateSourceCopy();

            var arg = ServerName + @" cmd.exe -u " + UserName + @" -p " + Password + @" /c " + FmeBatch.FullName;

            var p = new Process
                {
                    StartInfo =
                        {
                            UseShellExecute = false,
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            RedirectStandardInput = true,
                            FileName = PsExec.FullName,
                            Arguments = arg,
                            CreateNoWindow = true
                        }
                };

            using (p)
            {
                p.Start();

                StandardOutput = p.StandardOutput.ReadToEnd();
                StandardError = p.StandardError.ReadToEnd();

                //One should add an amount of time before we exit as this could lock up your app if the process never exits.
                p.WaitForExit();
            }

            RemoveSourceCopy();
        }
    }

public class ValidatorViewModel : ViewModelBase
    {
        public List<string> ValidationErrors { get; set; }

        private string _standardOutput;
        public string StandardOutput { get { return _standardOutput; } set { _standardOutput = value; OnPropertyChanged("StandardOutput"); } }

        private string _standardError;
        public string StandardError { get { return _standardError; } set { _standardError = value; OnPropertyChanged("StandardError"); } }

        #region Constructor
        public ValidatorViewModel(IValidator validator)
        {
            Validator = validator;
            ValidationErrors = new List<string>();
        }
        #endregion

        #region Properties & Variables
        public IValidator Validator { get; private set; }
        private string _sourceFileName;
        public string SourceFileName { get { return _sourceFileName; } set { _sourceFileName = value; OnPropertyChanged("SourceFileName"); } }
        #endregion
       
        #region Commands
        private RelayCommand _sourceUploadCommand;
        public ICommand SourceUploadCommand
        {
            get
            {
                return _sourceUploadCommand ?? (_sourceUploadCommand = new RelayCommand(param => SourceUploadExecute(),
                                                                                      param => CanSourceUploadExecute()));
            }
        }

        private void SourceUploadExecute()
        {
            try
            {
                var ofd = new OpenFileDialog
                {
                    InitialDirectory = "c:\\",
                    Filter = "sdf files (*.sdf)|*.sdf|All files (*.*)|*.*",
                    RestoreDirectory = true
                };
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    Validator.FileToValidate = new FileInfo(ofd.FileName);
                    SourceFileName = Validator.FileToValidate.FullName;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private bool CanSourceUploadExecute()
        {
            return true;
        }

        private RelayCommand _validateUploadCommand;
        public ICommand ValidateUploadCommand
        {
            get
            {
                return _validateUploadCommand ?? (_validateUploadCommand = new RelayCommand(param => ValidateUploadExecute(),
                                                                                      param => CanValidateUploadExecute()));
            }
        }

        private void ValidateUploadExecute()
        {
            try
            {
                try
                {
                    Validator.Validate();
                    StandardError = Validator.StandardError;
                    StandardOutput = Validator.StandardOutput;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private bool CanValidateUploadExecute()
        {
            ValidationErrors.Clear();

            if (Validator.OutputDirectoryFromClient == null)
            {
                ValidationErrors.Add("OutputDirectoryFromClient is not set.");
                return false;
            }

            if (Validator.OutputDirectoryOnServer == null)
            {
                ValidationErrors.Add("OutputDirectoryOnServer is not set.");
                return false;
            }

            if (Validator.WorkbenchDirectoryOnServer == null)
            {
                ValidationErrors.Add("WorkbenchDirectoryOnServer is not set.");
                return false;
            }

            if (Validator.FileToValidate == null)
            {
                ValidationErrors.Add("FileToValidate is not set.");
                return false;
            }

            if (Validator.FmeWorkbench == null)
            {
                ValidationErrors.Add("FmeWorkbench is not set.");
                return false;
            }

            if (Validator.PsExec == null)
            {
                ValidationErrors.Add("PsExec is not set.");
                return false;
            }

            if (Validator.FmeExec == null)
            {
                ValidationErrors.Add("FmeExec is not set.");
                return false;
            }

            if (Validator.FmeBatch == null)
            {
                ValidationErrors.Add("FmeBatch is not set.");
                return false;
            }

            if (!Directory.Exists(Validator.OutputDirectoryFromClient.FullName))
            {
                ValidationErrors.Add("Invalid Output Directory From Client Path");
                return false;
            }

            return true;
        }

        private RelayCommand _openDestinationCommand;
        public ICommand OpenDestinationCommand
        {
            get
            {
                return _openDestinationCommand ?? (_openDestinationCommand = new RelayCommand(param => OpenDestinationExecute(),
                                                                                      param => CanOpenDestinationExecute()));
            }
        }

        private void OpenDestinationExecute()
        {
            try
            {
                Process.Start("explorer.exe", Validator.OutputDirectoryFromClient.FullName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private bool CanOpenDestinationExecute()
        {
            return true;
        }
        #endregion
    }

public TrackValidatorViewModel() : base(new Validator())
        {
            Validator.OutputDirectoryFromClient = new DirectoryInfo(@"\\hictblockap022\FME\TrackValidator\");
            Validator.OutputDirectoryOnServer = new DirectoryInfo(@"E:\FME\TrackValidator\");
            Validator.WorkbenchDirectoryFromClient = new DirectoryInfo(@"\\hictblockap022\FME\Infranet\TrackValidator\");
            Validator.WorkbenchDirectoryOnServer = new DirectoryInfo(@"E:\FME\Infranet\TrackValidator\");

            Validator.FmeBatch = new FileInfo(Validator.WorkbenchDirectoryOnServer + "trackvalidator.bat");
            Validator.FmeWorkbench = new FileInfo(Validator.WorkbenchDirectoryOnServer + "trackvalidator.fmw");

            Validator.PsExec = new FileInfo(@"C:\Users\Public\Documents\Infranet\PSTools\PsExec.exe");
            Validator.FmeExec = new FileInfo(@"C:\Program Files\FME\fme.exe");

            Validator.UserName = "CXP8200";
            Validator.Password = "password";
            Validator.ServerName = @"\\hictblockap022";
        }

  public class SwitchValidatorViewModel : ValidatorViewModel
    {
        public SwitchValidatorViewModel() : base(new Validator())
        {
            Validator.OutputDirectoryFromClient = new DirectoryInfo(@"\\hictblockap022\FME\SwitchValidator\");
            Validator.OutputDirectoryOnServer = new DirectoryInfo(@"E:\FME\SwitchValidator\");
            Validator.WorkbenchDirectoryFromClient = new DirectoryInfo(@"\\hictblockap022\FME\Infranet\SwitchValidator\");
            Validator.WorkbenchDirectoryOnServer = new DirectoryInfo(@"E:\FME\Infranet\SwitchValidator\");

            Validator.FmeBatch = new FileInfo(Validator.WorkbenchDirectoryOnServer + "switchvalidator.bat");
            Validator.FmeWorkbench = new FileInfo(Validator.WorkbenchDirectoryOnServer + "switchvalidator.fmw");

            Validator.PsExec = new FileInfo(@"C:\Users\Public\Documents\Infranet\PSTools\PsExec.exe");
            Validator.FmeExec = new FileInfo(@"C:\Program Files\FME\fme.exe");

            Validator.UserName = "CXP8200";
            Validator.Password = "password";
            Validator.ServerName = @"\\hictblockap022";
        }
    }

<UserControl x:Class="BRail.InfraNet.TrackValidator.TrackValidatorView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0" Grid.Row="0" Command="{Binding SourceUploadCommand}" Content="Open Source" Margin="0,5,5,5"/>
        <Button Grid.Column="1" Grid.Row="0" Command="{Binding ValidateUploadCommand}" Content="Validate Source" Margin="5"/>
        <Button Grid.Column="2" Grid.Row="0" Command="{Binding OpenDestinationCommand}" Content="Open Result" Margin="5,5,0,5"/>
        <TextBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" Margin="0,5,0,0" IsReadOnly="True" Height="25" TextWrapping="Wrap" Text="{Binding SourceFileName, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top"/>
        <TextBox Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3" Margin="0,5,0,0" TextWrapping="Wrap" Text="{Binding StandardError}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="Auto"/>
    </Grid>
</UserControl>

<Window x:Class="BRail.InfraNet.TrackValidator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BRail.InfraNet.TrackValidator"
        Title="Master Validator" Height="Auto" Width="Auto">
   
      <Grid Margin="5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
            <Border BorderBrush="LightBlue" BorderThickness="5" Margin="5" Grid.Column="0">
                <Grid Margin="5">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="25"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Row="0" Height="20" TextAlignment="Center" Text="TrackValidator" Background="LightBlue" FontStyle="Italic" FontWeight="Bold"/>
                    <local:TrackValidatorView Grid.Row="1" Margin="0,5,0,0" DataContext="{Binding Source={StaticResource TrackValidatorViewModel}}"/>
                </Grid>
            </Border>
            <Border BorderBrush="LightBlue" BorderThickness="5" Margin="5" Grid.Column="1">
                <Grid Margin="5">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="25"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Row="0" Height="20" TextAlignment="Center" Text="SwitchValidator" Background="LightBlue" FontStyle="Italic" FontWeight="Bold"/>
                    <local:TrackValidatorView Grid.Row="1" Margin="0,5,0,0" DataContext="{Binding Source={StaticResource SwitchValidatorViewModel}}"/>
                </Grid>
            </Border>
           
            </Grid>
   
</Window>

Tuesday, July 8, 2014

C# Using PSTool PsExec to execute programs on remote systems.

Download PSTool here
Usefull information about PSExec.exe

Class I used to execute a program (FME + extra parameters) on a remote server.

public class TrackValidator
    {
        public string DestinationDirectoryPathFromClient { get; private set; }
        public string DestinationDirectoryPathFromServer { get; private set; }

        public string TrackUploadBatchName { get; private set; }
        public FileInfo SourceFile { get; set; }
        public string CopiedSourceFileName { get; private set; }
        public string OutputSourceFileName { get; private set; }
        public string FmeExePath { get; private set; }
        public string WorkbenchPath { get; private set; }

        public string WorkbenchName { get; private set; }

        public FileInfo PsExec { get; private set; }

        public string ServerName { get; private set; }

        public string UserName { get; private set; }
        public string Password { get; private set; }

        public TrackValidator()
        {
            DestinationDirectoryPathFromClient = @"\\hictblockap022\FME\TrackUpload\";
            DestinationDirectoryPathFromServer = @"E:\FME\TrackUpload\";
            TrackUploadBatchName = "trackupload.bat";
            CopiedSourceFileName = "source.sdf";
            OutputSourceFileName = "output.sdf";

            PsExec = new FileInfo(@"c:\data\fme\PsTools\PsExec.exe");
            ServerName = @"\\hictblockap022";
            UserName = "CXP8200";
            Password = "password";

            FmeExePath = @"C:\Program Files\FME\fme.exe";

            WorkbenchPath = @"E:\FME\Workbenches\TrackUpload\";
            WorkbenchName = "trackupload.fmw";
        }

        private void CreateBatch()
        {
            if(SourceFile == null)
                throw new Exception("Undefined Sourcefile.");
            if(!SourceFile.Exists)
                throw  new Exception("Sourcefile doesn't exist.");

            const char c = '"';

            using (var sw = new StreamWriter(DestinationDirectoryPathFromClient + TrackUploadBatchName))
            {
                sw.WriteLine(c + FmeExePath + c + " " + WorkbenchPath + WorkbenchName);
                sw.WriteLine(@"--SourceDataset_SDF3 " + DestinationDirectoryPathFromServer + CopiedSourceFileName);
                sw.WriteLine(@"--TOLERANCE_VAL 0.01");
                sw.WriteLine(@"--DestDataset_SDF3 " + DestinationDirectoryPathFromServer + OutputSourceFileName);
            }
        }

        private void CreateSource()
        {
            File.Copy(SourceFile.FullName, DestinationDirectoryPathFromClient + CopiedSourceFileName);
        }

        private void RemoveBatch()
        {
            if(File.Exists(DestinationDirectoryPathFromClient + TrackUploadBatchName))
                File.Delete(DestinationDirectoryPathFromClient + TrackUploadBatchName);
        }

        private void RemoveOutput()
        {
            if(File.Exists(DestinationDirectoryPathFromClient + OutputSourceFileName))
                File.Delete(DestinationDirectoryPathFromClient + OutputSourceFileName);
        }

        private void RemoveSource()
        {
            if (File.Exists(DestinationDirectoryPathFromClient + CopiedSourceFileName))
                File.Delete(DestinationDirectoryPathFromClient + CopiedSourceFileName);
        }

        public void Upload()
        {
            RemoveBatch();
            RemoveSource();
            RemoveOutput();

            CreateSource();
            CreateBatch();

            string arg = ServerName + @" cmd.exe -u " + UserName + @" -p " + Password + @" /c " + DestinationDirectoryPathFromServer + TrackUploadBatchName;

            var p = new Process
            {
                StartInfo =
                {
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true,
                    FileName = PsExec.FullName,
                    Arguments =  arg,
                    CreateNoWindow = true
                }
            };
            p.Start();

            string output = p.StandardOutput.ReadToEnd();
            string errormessage = p.StandardError.ReadToEnd();

            p.WaitForExit();

            RemoveSource();
            RemoveBatch();
        }

    }

Wednesday, March 19, 2014

FME : Create SDF from coordinates in excel


In this example I will create point geometries into an SDF using the coordinates from an excel file.
  • Source Data
   
  •  Create a blank workspace
  •  Add Reader and Configure Data Source (Excel)
  • Add and Configure Vertex Creator
  •  Add Writer and Configure Data Destination (SDF)

Tuesday, November 26, 2013

Enable MbUnit Tests within Resharper 7.1 and Higher

Introduction

It is not possible to run unit tests written with the MbUnit test framework from within Resharper 7.1 and higher. To allow you to run them using Resharper you have to install a plugin.

Download

Install

Unzip and place them inside the following folder:
C:\Program Files (x86)\JetBrains\ReSharper\v7.1\Bin\plugins\


References


Gallio : Automated Integration Tests Autocad

1.     Introduction

Gallio is a very flexible, and extensible testing framework usedto run tests against the code that depends on the AutoCAD API.

2.     Download

Get the lastest version of Gallio at http://www.gallio.org

3.     Extract Gallio

Extract the downloaded .zip file to any location on your computer.
Before you extract the ZIP file, be sure to check its properties and click “Unblock” if that option is available.

4.     Setup MSVS 2012 (Existing or new project)

Add References

·         acdbmgd.dll (Autocad)
·         acmgd.dll (Autocad)
·         Gallio.dll, MbUnit.dll (The default Gallio test runner looks for tests written in your DLL that use the MbUnit testing framework.)

Configuration

·         Make sure you set your target framework correctly
·         External References should be set to 'Copy Local'= false (otherwise netload assemblies won't work)

5.     Create Batch

Create a .bat file and add the following code to it:
SET GALLIO_RUNTIME_PATH=C:\Users\Mysth\Downloads\GallioBundle-3.4.14.0\bin\
"C:\Users\Mysth\Downloads\GallioBundle-3.4.14.0\bin\Gallio.Echo.exe" gallio.dll /r:AutoCAD
pause

Place the batch alongside the assembly containing the tests.

6.     Reports

Gallio can generate reports with the results of the tests run in either html format or xml format.
Add the following to the batch to auto generate reports :
SET GALLIO_RUNTIME_PATH=C:\Data\GallioBundle-3.4.14.0\bin
"C:\Data\GallioBundle-3.4.14.0\bin\Gallio.Echo.exe" BRail.InfraNet.IntegrationTests.Domain.dll /r:AutoCAD/rt:xml /rt:html
Pause
Example run on BRail.InfraNet.Domain assembly



7.     Example

For this example to work add an extra assembly BeDeveloped.Framework.AutoCad.dll to your project.



Create a Test Class where our tests will be written in.
publicclassTests
    {
        [Test]
publicvoidTestCircleEqual()
        {
var services = newActiveServices();

services.EntityService.CreateCircle(0, 0, 20);

var id = services.DocumentService.GetLast();
var circle = services.EntityService.GetEntity(id) asCircle;

if (circle != null)
            {
Assert.AreEqual(20, circle.Radius);
            }
        }

[Test]
publicvoidTestCircleNotEqual()
        {
var services = newActiveServices();

services.EntityService.CreateCircle(0, 0, 10);

var id = services.DocumentService.GetLast();
var circle = services.EntityService.GetEntity(id) asCircle;

if (circle != null)
            {
Assert.AreEqual(20, circle.Radius);
}
        }
    }



Build your project and run the previously configured .bat file. Gallio should launch Autocad, load all the necessary assemblies and execute all tests. Gallio will close Autocad once all tests are executed.  You should see the following test result.
One test passedone should have failed.



8.     Known Issues

System.NotSupportedException:
An attempt was made to load an assembly
from a network location which would have caused the assembly to be sandboxed in
previous versions of the .NET Framework. This release of the .NET Framework
does not enable CAS policy by default, so this load may be dangerous. If this
load is not intended to sandbox the assembly, please enable the
loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569
for more information.