Current filter:
                                You should refresh the page.
                                  • Greetings,
                                    Is it possible to create a PowerShell interface for an XAF application?
                                    My particular XAF application is Web based, but, there is a number of tasks in it, that are long-running and administrative in nature, which would be served well by having a PowerShell administrative interface.

                                    -Eugene

                                2 Solutions

                                Creation Date Importance Sort by

                                Eugene,
                                I am an avid PowerShell user and have done a lot of XAF manipulation with it.
                                The primary objective is to get a Object Space instantiated then you can do most anything with it.
                                I do this by creating a class inheriting the cmdlet after referencing the System.Management.Automation to the project.

                                Below are 2 samples

                                1. the class uses to retrieve the Object Space
                                2. sample PowerShell code that uses the above cmdlet.

                                I hope this helps

                                using System;
                                using System.Data;
                                using DevExpress.Data.Filtering;
                                using DevExpress.ExpressApp;
                                using DevExpress.ExpressApp.Security;
                                using DevExpress.ExpressApp.Security.ClientServer;
                                using DevExpress.ExpressApp.Security.Strategy;
                                using DevExpress.ExpressApp.Xpo;
                                using DevExpress.Persistent.BaseImpl;
                                using System.Management.Automation;

                                namespace TBX.Module.PS
                                {

                                    [Cmdlet("Get", "TBXObjectSpace")]
                                    public class Get_TBXObjectSpace : Cmdlet
                                    {

                                        // Fields...
                                        private string _PassWord = "";
                                        private string _UserName;
                                        private string _ConnectionString;

                                        [Parameter(Mandatory = true)]
                                        public string ConnectionString
                                        {
                                            get { return _ConnectionString; }
                                            set
                                            {
                                                _ConnectionString = value;
                                            }
                                        }

                                        [Parameter(Mandatory = true)]
                                        public string UserName
                                        {
                                            get { return _UserName; }
                                            set
                                            {
                                                _UserName = value;
                                            }
                                        }

                                        [Parameter(Mandatory = false)]
                                        public string PassWord
                                        {
                                            get { return _PassWord; }
                                            set
                                            {
                                                _PassWord = value;
                                            }
                                        }

                                        protected override void ProcessRecord()
                                        {
                                            object o = GetObjectSpace();
                                            WriteObject(o);
                                        }

                                        public IObjectSpace GetObjectSpace()
                                        {
                                            XpoTypesInfoHelper.GetXpoTypeInfoSource();
                                            XafTypesInfo.Instance.RegisterEntity(typeof(TBX.Module.BusinessObjects.ScheduleEvent));
                                            XafTypesInfo.Instance.RegisterEntity(typeof(TBX.Module.BusinessObjects.Client));
                                            XafTypesInfo.Instance.RegisterEntity(typeof(TBX.Module.BusinessObjects.GLRegister));
                                            XafTypesInfo.Instance.RegisterEntity(typeof(Person));
                                            XafTypesInfo.Instance.RegisterEntity(typeof(TBX.Module.BusinessObjects.SecurityUser));
                                            XafTypesInfo.Instance.RegisterEntity(typeof(TBX.Module.BusinessObjects.SecurityRole));
                                            XafTypesInfo.Instance.RegisterEntity(typeof(OidGenerator));     // Added by Greytrix 20150129 to work with auto generate code in ApprovalEntry

                                            // Begin/Greytrix/Mahendra/20150901/Updated code to encrypt connection string.
                                            //string connectionString = ConnectionString;//@"Data Source=localhost\SQLExpress;Initial Catalog=TBDemo;User ID=sa;Password=sasa";
                                            string connectionString = TBX.Module.SecurityEngine.GetConnectionString(ConnectionString);
                                            // End/Greytrix/Mahendra/20150901/Updated code to encrypt connection string.

                                            Console.WriteLine(String.Format("Connecting to {0}", "Database")); //connectionString));
                                            XPObjectSpaceProvider directProvider = new XPObjectSpaceProvider(connectionString, null);
                                            IObjectSpace directObjectSpace = directProvider.CreateObjectSpace();
                                            //UpdateDatabase(directObjectSpace);

                                            AuthenticationStandard auth = new AuthenticationStandard();
                                            auth.SetLogonParameters(new AuthenticationStandardLogonParameters(UserName, PassWord));

                                            Console.WriteLine("Building Security");
                                            SecurityStrategyComplex security = new SecurityStrategyComplex(typeof(TBX.Module.BusinessObjects.SecurityUser), typeof(TBX.Module.BusinessObjects.SecurityRole), auth);
                                            security.Logon(directObjectSpace);

                                            Console.WriteLine("Building secureObjectSpace");
                                            SecuredObjectSpaceProvider osProvider = new SecuredObjectSpaceProvider(security, connectionString, null);
                                            // Jira:152 MS20151126 To resolve "Transferring requests via ICommandChannel is prohibited within the security engine." error in PowerShell script.
                                            osProvider.AllowICommandChannelDoWithSecurityContext = true;        // Greytrix/Mahendra/20151126/To resolve "Transferring requests via ICommandChannel is prohibited within the security engine." error in PowerShell script.
                                            // End:152
                                            IObjectSpace securedObjectSpace = osProvider.CreateObjectSpace();

                                            Console.WriteLine("...Done");
                                            return securedObjectSpace;

                                        }
                                    }
                                }

                                ##########
                                #PowerShell script that uses the above commandlet
                                ##########
                                #Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
                                $TBXPath = "C:\TBX"
                                $Year = [DateTime]::Now.Year
                                $Month = [DateTime]::Now.Month
                                $Day = [DateTime]::Now.Day
                                $FailedFile = "C:\TBX\Failed$Year-$Month-$Day.IMP"
                                $FailedReasonFile = "C:\TBX\FailedReason$Year-$Month-$Day.Log"
                                $HasFailedTransaction  = $False

                                if($TBXCredentials = $Host.UI.PromptForCredential('Need Credentials', 'Please enter your user name and password.','', ""))
                                {
                                    # Get TBX Credential
                                    $User     = $TBXCredentials.UserName;
                                    $Password = $TBXCredentials.GetNetworkCredential().Password;
                                }
                                else
                                {
                                    Exit
                                }

                                # Read Application Configuration file from TBX path and get the Active connection string
                                    $Appconfig = [XML](Get-Item "$TBXPath\TBX.exe.config" | Get-Content);
                                    $CompanyConnection = "";
                                    If ($TBXCompany -eq "Default") { $CompanyConnection = "connectionString"; }
                                    else { $CompanyConnection = "connectionString$TBXCompany"; }
                                    $ConString = $Appconfig.configuration.connectionStrings.add | where name -EQ $CompanyConnection;
                                # Create ObjectSpace if it is null
                                If (!$OS)
                                {
                                    Import-Module "$TBXPath\TBX.Module.dll";
                                    $OS = Get-TBXObjectSpace -ConnectionString $ConString.connectionString -UserName $User -PassWord $Password
                                }

                                Function Create-TBXTimeEntry
                                {
                                    Param(
                                        $OS           = $OS,
                                        $TBXPath      = "C:\TBX",
                                        [Parameter(mandatory=$true)] $Employee,
                                        #[Parameter(mandatory=$true)] $ProjectTask,
                                        [Parameter(mandatory=$true)] $Engagement,
                                        #[Parameter(mandatory=$true)] $Client,
                                        [Parameter(mandatory=$true)] $WorkCode,
                                        $TransDate = $Null,
                                        $HoursUnits   = 1,
                                        #$Rate         = 100,
                                        $Description = "",
                                        $Reimbursable = $false,
                                        $TBXCompany   = "Default",
                                        $File
                                    )

                                    # Create ObjectSpace if it is null
                                    If (!$OS)
                                    {

                                        # Read Application Configuration file from TBX path and get the Active connection string
                                        $Appconfig = [XML](Get-Item "$TBXPath\TBX.exe.config" | Get-Content);
                                        $CompanyConnection = "";
                                        If ($TBXCompany -eq "Default") { $CompanyConnection = "connectionString"; }
                                        else { $CompanyConnection = "connectionString$TBXCompany"; }
                                        $ConString = $Appconfig.configuration.connectionStrings.add | where name -EQ $CompanyConnection;

                                        Import-Module "$TBXPath\TBX.Module.dll";
                                        $OS = Get-TBXObjectSpace -ConnectionString $ConString.connectionString -UserName Admin -PassWord Admin
                                    }

                                    if (!$Employee -or !$Engagement -or !$WorkCode)
                                    {
                                        Write-Host "Fail:- Fail to create Time Entry because either Employee, ProjectTask, Engagement, Client or WorkCode object is/are not exists." -ForegroundColor Red;
                                    }
                                    else
                                    {
                                        try
                                        {
                                            #If ($Client.Active -ne $True)
                                            #{
                                            #    $Client.Active = 1
                                            #    $Client.Save()
                                            #    $os.CommitChanges()
                                            #}
                                            If ($Engagement.Active -ne $True)
                                            {
                                                $Engagement.Active = 1
                                                $Engagement.Save()
                                                $os.CommitChanges()
                                            }
                                            #if(!$Client)
                                            #{
                                            #    return $False
                                            #}
                                            # Create new TimeDetail record
                                            $NewTime              = $OS.CreateObject([TBX.Module.BusinessObjects.TimeDetail]);
                                            $NewTime.Employee     = $Employee;
                                            if($TransDate) { $NewTime.TransDate    = $TransDate;}
                                            $NewTime.ProjectTask  = $ProjectTask;
                                            $NewTime.Engagement   = $Engagement;
                                            #$NewTime.Client       = $Client;
                                            $NewTime.Workcode     = $WorkCode;
                                            $NewTime.HoursUnits   = $HoursUnits;
                                            #$NewTime.Rate         = $Rate;
                                            $NewTime.Reimbursable = $Reimbursable;
                                            If ($Description -ne "") {$NewTime.ExtendedDescription = $Description}
                                            $NewTime.IndexID = "Imported on $([Datetime]::Today) with file $File"

                                            $NewTime.Save();
                                            $NewTime.Session.CommitChanges();

                                            Write-Host "Pass:- TimeDetail Created." -ForegroundColor Green;
                                            Return $True
                                        }
                                        catch
                                        {
                                            #$OS.Rollback()
                                            Write-Host "Fail:- Fail to create new Time Entry. $($Error[0].Exception.Message)" -ForegroundColor Red;
                                            Return $False
                                        }
                                    }

                                    Return $True
                                }

                                [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null

                                $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
                                $OpenFileDialog.initialDirectory = $initialDirectory
                                $OpenFileDialog.filter = "IMP (*.IMP)| *.IMP"
                                $OpenFileDialog.ShowDialog() | Out-Null

                                $File = $OpenFileDialog.FileName
                                <#

                                1. Transaction_No
                                2. Line_Date
                                3. UserCode
                                4. Trans_Date
                                5. EmployeeCode
                                6. ClientCode
                                7. EngagementCode
                                8. WorkCode
                                9. HoursUnits
                                10. Taxable
                                11. Comment

                                #>

                                $CSV = Import-CSV $File -Header Transaction_No,Line_Date, UserCode, Trans_Date, EmployeeCode, ClientCode, EngagementCode, WorkCode, HoursUnits, Taxable, Comment

                                foreach($CSVItem in $CSV)
                                {
                                    $EmployeeCode =  $CSVItem.EmployeeCode
                                    $employeeCriteria = $OS.ParseCriteria("EmployeeCode = '$EmployeeCode'")
                                    $Employee = $OS.FindObject([TBX.Module.BusinessObjects.Employee],$employeeCriteria)
                                    #$Employee
                                    $ClientCriteria = $OS.ParseCriteria("ClientCode = '00$($CSVItem.ClientCode)'")
                                    $Client = $OS.FindObject([TBX.Module.BusinessObjects.Client],$ClientCriteria)
                                    #$Client
                                     If ($Client.Active -ne $True)
                                            {
                                                If($client)
                                                {
                                                $Client.Active = 1
                                                $Client.Save()
                                                $os.CommitChanges()
                                            }
                                        }

                                    $EngagementCode =  [String]::Format("{0:0000}", [int]::Parse($CSVItem.EngagementCode))
                                    $EngagementCriteria = $OS.ParseCriteria("EngagementCode = '$EngagementCode' and Client = '$($Client.Oid)'")
                                    $Engagement = $OS.FindObject([TBX.Module.BusinessObjects.Engagement],$EngagementCriteria)
                                    #$Engagement
                                     If ($Engagement.Active -ne $True)
                                    {
                                        $Engagement.Active = 1
                                        $Engagement.Save()
                                        $os.CommitChanges()
                                    }
                                    If ($Engagement.Client.Active -ne $True)
                                    {
                                        $Engagement.Client.Active = 1
                                        $Engagement.Save()
                                        $os.CommitChanges()
                                    }

                                    $WorkCode =  $CSVItem.WorkCode
                                    #$WorkCode

                                    $WorkCodeCriteria = $OS.ParseCriteria("WorkCode = '$WorkCode'")
                                    $WorkCode = $OS.FindObject([TBX.Module.BusinessObjects.WrkCode],$WorkCodeCriteria)
                                    #$WorkCode

                                    #$CSVItem
                                    If(!$WorkCode -or !$Engagement -or !$Employee)
                                    {
                                        $HasFailedTransaction = $True
                                        $CSVItem | Export-Csv -Append -Path $FailedFile
                                        If(!$WorkCode)
                                {
                                                Write-Host "Failed: Workcode $($CSVItem.WorkCode) was not found in TBx" -ForegroundColor Red
                                                "$([DateTime]::Now.ToString()) Failed: Workcode $($CSVItem.WorkCode) was not found in TBx" | Out-File -FilePath $FailedReasonFile -Append
                                }
                                        If(!$Engagement)
                                {
                                                Write-Host "Failed: Engagement $($CSVItem.EngagementCode) was not found in TBx" -ForegroundColor Red
                                                "$([DateTime]::Now.ToString()) Failed: Engagement $($CSVItem.EngagementCode) was not found in TBx" | Out-File -FilePath $FailedReasonFile -Append
                                }
                                        If(!$Employee) {
                                                Write-Host "Failed: Employee $($CSVItem.EmployeeCode) was not found in TBx" -ForegroundColor Red
                                                "$([DateTime]::Now.ToString()) Failed: Employee $($CSVItem.EmployeeCode) was not found in TBx" | Out-File -FilePath $FailedReasonFile -Append
                                }
                                    }
                                    Else
                                    {

                                         $timeinfo = $CSVItem.Trans_Date
                                         $template = 'MMddyy'
                                         $TransDate = [DateTime]::ParseExact($timeinfo, $template, $null)

                                         $Result = Create-TBXTimeEntry -OS $OS -Employee $Employee -Engagement $Engagement -WorkCode $WorkCode -HoursUnits $CSVItem.HoursUnits -Description $CSVItem.Comment -TransDate $TransDate -File $File
                                         If($Result -ne $True)
                                        {
                                                $HasFailedTransaction = $True
                                                $CSVItem | Export-Csv -Append -Path $FailedFile -Force
                                                Write-Host "Failed: Time Entry Creation Failed" -ForegroundColor Red
                                        }
                                    }

                                   <#

                                    #>
                                }

                                If ($HasFailedTransaction)
                                {
                                    [System.Windows.MessageBox]::Show("There where one or more Failed records. Open $FailedFile for specific records")
                                }

                                • Dennis (DevExpress Support) 07.23.2018

                                  Robert, thank you for sharing your experience with the XAF community.

                                Hello Eugene,
                                We have not yet researched this possibility ourselves, but if you can somehow instantiate an XafApplication and consume its services from this environment, I do not see any difficulties with this scenario. Refer to the Platforms - Create a ConsoleXafApplication thread to learn more on how to create a GUI-less application.

                                See Also:
                                Access XAF Application Data in a non-XAF Application
                                How to: Use the Integrated Mode of the Security System in Non-XAF Applications
                                How to: Use XAF Reports in a non-XAF Application
                                Data Manipulation and Business Logic