I am working on programmatically creating a package with a data flow task containing a Script Component as a Source. I have been able to create the package, data flow task, and add a Script Component. However, the Script Component appears to default to a Transform.
Does anyone know how to get it to be a Souce?
Here is my class with the single method I'm working on:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DynamicPackageCreator.Models;
using Microsoft.SqlServer.Dts.Runtime;
using System.IO;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
// Alias to prevent ambiguity
using dtsColumnDataType = Microsoft.SqlServer.Dts.Runtime.Wrapper.DataType;
namespace DynamicPackageCreator
{
public class DtsClient
{
public void CreatePackageWithDataFlowAndScriptSource(string filePath, string dataFlowName, string sourceName, List<OutputDefinition> outputDefinitions)
{
// Create the Package
Package pkg = new Package();
pkg.Name = Path.GetFileNameWithoutExtension(filePath);
// Create the Dataflow task
Executable e = pkg.Executables.Add("STOCK:PipelineTask");
TaskHost thMainPipe = e as TaskHost;
thMainPipe.Name = dataFlowName;
MainPipe dataFlowTask = thMainPipe.InnerObject as MainPipe;
// Create Source Component
IDTSComponentMetaData100 sourceComponent = dataFlowTask.ComponentMetaDataCollection.New();
sourceComponent.Name = sourceName;
sourceComponent.ComponentClassID = SsisComponentType.ScriptComponent.GetComponentClassId();
// Get the design time srcDesignTime of the component
CManagedComponentWrapper srcDesignTime = sourceComponent.Instantiate();
// Initialize the component
srcDesignTime.ProvideComponentProperties();
int lastOutputId = 0;
// Add metadata
foreach (var outputDefinition in outputDefinitions)
{
var output = srcDesignTime.InsertOutput(DTSInsertPlacement.IP_AFTER, lastOutputId);
output.Name = outputDefinition.OutputName;
lastOutputId = output.ID;
var outputColumnCollection = output.OutputColumnCollection;
foreach (var outputColumnDefinition in outputDefinition.OutputColumnDefinitions)
{
var outputColumn = outputColumnCollection.New();
outputColumn.Name = outputColumnDefinition.ColumnName;
outputColumn.SetDataTypeProperties(dtsColumnDataType.DT_WSTR, outputColumnDefinition.ColumnSize, 0, 0, 0);
}
}
// Reinitialise the metadata
srcDesignTime.ReinitializeMetaData();
// Save the package
Application app = new Application();
app.SaveToXml(filePath, pkg, null);
}
}
}
The OutputDefinition class is a custom class I created for holding the definitions used when creating the outputs.
So, the solution to this issue is to remove all inputs from the component. By default the component has an "Input 0" and an "Output 0" which correlates to being a Transform script component type. A source type would have no Inputs, and a destination would have no Outputs.
To remove the inputs and outputs, add:
sourceComponent.OutputCollection.RemoveAll();
sourceComponent.InputCollection.RemoveAll();
Here:
// ...
// Initialize the component
srcDesignTime.ProvideComponentProperties();
// Remove default inputs and outputs
sourceComponent.OutputCollection.RemoveAll();
sourceComponent.InputCollection.RemoveAll();
int lastOutputId = 0;
// ...
Related
I am trying to access the macros inside of an Access database (accdb).
I tried using:
using Microsoft.Office.Interop.Access.Dao;
...
DBEngine dbe = new DBEngine();
Database ac = dbe.OpenDatabase(fileName);
I found a container["Scripts"] that had a document["Macro1"] which is my target. I am struggling to access the contents of the document. I also question if the Microsoft.Office.Interop.Access.Dao is the best reference for what I am trying to achieve.
What is the best way to view the content of the macros and modules?
You can skip the DAO part, it's not needed in this case. Macros are project specific, so in order to get them all, you would need to loop through your projects. In my example, i just have one project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Access;
namespace Sandbox48
{
public class Program
{
public static void Main(string[] args)
{
Microsoft.Office.Interop.Access.Application oAccess = null;
string savePath = #"C:\macros\";
oAccess = new Microsoft.Office.Interop.Access.Application();
// Open a database in exclusive mode:
oAccess.OpenCurrentDatabase(
#"", //filepath
true //Exclusive
);
var allMacros = oAccess.CurrentProject.AllMacros;
foreach(var macro in allMacros)
{
var fullMacro = (AccessObject)macro;
Console.WriteLine(fullMacro.Name);
oAccess.SaveAsText(AcObjectType.acMacro, fullMacro.FullName, $"{savePath}{ fullMacro.Name}.txt");
}
Console.Read();
}
}
}
I'm trying to run a python script from unity (C# script) to use its output which is a text file in my game later, the thing is that when I run the C# script in unity nothing happens (Python script works fine on its own). Can anyone tell me what I'm missing?
Thanks.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.IO;
using UnityEngine.UI;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Runtime.InteropServices;
public class PyCx : MonoBehaviour {
public Text Message;
public GameObject OpenPanel1 = null;
// Use this for initialization
void Start () {
python ();
read ();
ShowMessage ();
}
public void python(){
ProcessStartInfo pythonInfo = new ProcessStartInfo ();
Process python;
pythonInfo.FileName=#"C:\Users\HP\AppData\Local\Programs\Python\Python36-32\python.exe";
pythonInfo.Arguments=#"C:\Users\HP\Documents\projet1.pyw";
pythonInfo.CreateNoWindow = false;
pythonInfo.UseShellExecute = false;
python = Process.Start (pythonInfo);
python.WaitForExit ();
python.Close ();
}
public void read(){
using (var reader = new StreamReader ("C://Users//HP//Documents//result.txt")) {
string line = reader.ReadToEnd ();
Message.text = (line);
}
}
public void ShowMessage(){
OpenPanel1.SetActive (true);
Message.IsActive ();
}
// Update is called once per frame
void Update () {
}
}
Instead of using a process which can be unreliable outside your controlled development environment (you don't know if your users will even have Python installed and which version) you could try to run Python directly in your code using IronPython, IronPython is a Python interpreter for the CLR so it doesn't even require Python to be installed to execute your scripts.
To use it you need to download the compiled binaries from http://ironpython.net/download/
Then copy all the required assemblies in your resources folder:
IronPython.dll
IronPython.Modules.dll
Microsoft.Scripting.Core.dll
Microsoft.Scripting.dll
Microsoft.Scripting.Debugging.dll
Microsoft.Scripting.ExtensionAttribute.dll
Microsoft.Dynamic.dll
Then you will have access to the Python Engine, you can initialize it as follows:
PythonEngine engine = new PythonEngine();
engine.LoadAssembly(Assembly.GetAssembly(typeof(GameObject)));
engine.ExecuteFile("Project1.py");
You can see more info here: http://ironpython.net/documentation/
References
http://shrigsoc.blogspot.com.es/2016/07/ironpython-and-unity.html
https://forum.unity.com/threads/ironpython-in-unity-a-good-idea.225544/
Download Unity Python package using the link Unity Python 0.4.1
Then, go to Edit > Project Settings > Player > Other Settings >
Configuration and change Scripting Runtime Version to "Experimental
(.NET 4.6 Equivalent)".
Assume you have a small code snippet test.py in Python like this:
class Test():
def __init__(self, name):
self.name = name
def display(self):
return "Hi, " + self.name
You can use it from C# like this
using System.Collections;
using System.Collections.Generic;
using IronPython.Hosting;
using UnityEngine;
public class PythonInterfacer : MonoBehaviour {
void Start () {
var engine = Python.CreateEngine();
ICollection<string> searchPaths = engine.GetSearchPaths();
//Path to the folder of greeter.py
searchPaths.Add(#"C:\Users\Codemaker\Documents\PythonDemo\Assets\Scripts\Python\");
//Path to the Python standard library
searchPaths.Add(#"C:\Users\Codemaker\Documents\PythonDemo\Assets\Plugins\Lib\");
engine.SetSearchPaths(searchPaths);
dynamic py = engine.ExecuteFile(#"C:\Users\Codemaker\Documents\PythonDemo\Assets\Scripts\Python\test.py");
dynamic obj = py.Test("Codemaker");
Debug.Log(obj.display());
}
}
Here is mine that works. Hope this helps.
var psi = new ProcessStartInfo();
// point to python virtual env
psi.FileName = #"C:\Users\someone\Documents\git-repos\PythonVenvs\venv\Scripts\python.exe";
// Provide arguments
var script = #"Assets\Scripts\somecoolpythonstuff\cool.py";
var vidFileIn = "111";
var inputPath = #"Assets\input";
var outputPath = #"Assets\output";
psi.Arguments = string.Format("\"{0}\" -v \"{1}\" -i \"{2}\" -o \"{3}\"",
script, vidFileIn, inputPath, outputPath);
// Process configuration
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
// Execute process and get output
var errors = "nothing";
var results = "nothing";
using (var process = Process.Start(psi))
{
errors = process.StandardError.ReadToEnd();
results = process.StandardOutput.ReadToEnd();
}
// grab errors and display them in UI
StringBuilder buffy = new StringBuilder();
buffy.Append("ERRORS:\n");
buffy.Append(errors);
buffy.Append("\n\n");
buffy.Append("Results:\n");
buffy.Append(results);
// ui text object
responseText.Text = buffy.ToString();
You can try the following github repository code. You will get a basic idea of using python code in unity from a file
Unity Python Demo
I have a project where i will have to build dual stacked virtual machines. I usually work with powershell but it does not appear to be able to do that. I may have to use C#. I am kinda rusty on this but for some reason this code give me an error "Cannot create an instance of the abstract class or interface 'VMware.Vim.VimClient'".
using System.Text;
using VMware.Vim;
namespace Vimfunctions
{
public class VimFunctions
{
protected VimClient ConnectServer(string viServer, string viUser, string viPassword)
{
**VimClient vClient = new VimClient();**
ServiceContent vimServiceContent = new ServiceContent();
UserSession vimSession = new UserSession();
vClient.Connect("https://" + viServer.Trim() + "/sdk");
vimSession = vClient.Login(viUser, viPassword);
vimServiceContent = vClient.ServiceContent;
return vClient;
}
I added the reference to the project. I must have forgot to do something.
As per https://communities.vmware.com/thread/478700:
"either stick with the PowerCLI 5.5 release as mentioned or to modify your code to use the VimClientImpl class instead of VimClient (which is now an interface)."
A complete simple example I used:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VMware.Vim;
namespace vSphereCli
{
class Program
{
static void Main(string[] args)
{
VMware.Vim.VimClientImpl c = new VimClientImpl();
ServiceContent sc = c.Connect("https://HOSTNAME/sdk");
UserSession us = c.Login("admin#vsphere.local", "password");
IList<VMware.Vim.EntityViewBase> vms = c.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, null, null);
foreach (VMware.Vim.EntityViewBase tmp in vms)
{
VMware.Vim.VirtualMachine vm = (VMware.Vim.VirtualMachine)tmp;
Console.WriteLine((bool)(vm.Guest.GuestState.Equals("running") ? true : false));
Console.WriteLine(vm.Guest.HostName != null ? (string)vm.Guest.HostName : "");
Console.WriteLine("");
}
Console.ReadLine();
}
}
}
Add a reference to "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\VMware.Vim.dll". Update the hostname, password; and volia!
I need to parse through all the user variables in my ssis packages. As of now, I am able to get the names and values of ALL the variables in my package. I need to grab the name and the value and dump them to a table. As of now, I can display the name and the value through a message box, but I cant seem to figure out, how on script task I would be able to dump these values to a table. Any help will be appreciated.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
//using System;
////using Microsoft.SqlServer.Dts.Runtime;
namespace ST_81ec2398155247148a7dad513f3be99d.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
// Load a sample package that contains a variable that sets the file name.
Package pkg = app.LoadPackage(
#"C:\PackagePath\" +
#"Template0719.dtsx",
null);
Variables pkgVars = pkg.Variables;
foreach (Variable pkgVar in pkgVars)
{
MessageBox.Show(pkgVar.Name);
MessageBox.Show(pkgVar.Value.ToString());
}
Console.Read();
}
}
}
Since you know how to get the list of variables, you could create a data source script component.
Discussion on OOoForum.org
In python, using pyuno, I can do it like this:
table = self.model.createInstance("com.sun.star.text.TextTable")
This doesn't seem to work in C#. Here is my test code (I realize I probably don't need all those using statements, but I am adapting someone else's code):
using System;
using unoidl.com.sun.star.lang;
using unoidl.com.sun.star.uno;
using unoidl.com.sun.star.bridge;
using unoidl.com.sun.star.frame;
using unoidl.com.sun.star.document;
using unoidl.com.sun.star.text;
using unoidl.com.sun.star.container;
using unoidl.com.sun.star.util;
using unoidl.com.sun.star.table;
using unoidl.com.sun.star.beans;
namespace FromScratch
{
class MainClass
{
public static void Main(string[] args)
{
XComponentContext componentContext =
uno.util.Bootstrap.bootstrap();
XMultiServiceFactory multiServiceFactory = (XMultiServiceFactory)
componentContext.getServiceManager();
XTextDocument document;
XComponentLoader loader = (XComponentLoader)
multiServiceFactory.createInstance
("com.sun.star.frame.Desktop");
document = (XTextDocument) loader.loadComponentFromURL
("private:factory/swriter", "_blank", 0,
new PropertyValue[0]);
XText text = document.getText();
XTextCursor cursor = text.createTextCursor();
XTextTable table = (XTextTable)
multiServiceFactory.createInstance
("com.sun.star.text.TextTable");
table.initialize(2, 2);
text.insertTextContent(cursor, table, false);
}
}
}
Most of it seems to work fine, but when it gets to this line:
table.initialize(2, 2);
I get a runtime error:
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
at FromScratch.MainClass.Main (System.String[] args) [0x00063] in /home/matthew/Desktop/OpenOfficeSample/FromScratch/Main.cs:37
Apparently, this line:
XTextTable table = (XTextTable)
multiServiceFactory.createInstance
("com.sun.star.text.TextTable");
doesn't actually set table to anything.
What is going on here?
Solution (from OOoForum.org):
You must get the text table from the document multiservice factory, not from the multiservice factory of the service manager. You can do this by casting your document (a Model) to XMultiServiceFactory and calling its createInstance method.
XTextTable table = (XTextTable)
((XMultiServiceFactory)document).createInstance
("com.sun.star.text.TextTable");
See DevGuide.