SSIS WinSCP C# script task running but not doing anything - c#

My code is not throwing any error but it is not doing anything at all.
I'm trying to connect to a SFTP server, the task itself is not showing any error but it is not accessing/getting the file stored in a specific directory.
Images:
This is my code:
#region Namespaces
using System;
using Microsoft.SqlServer.Dts.Tasks;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Linq;
using WinSCP;
#endregion
namespace ST_t5fbgt5564cf3a165da70892d8c435v
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public int Main()
{
try
{
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
UserName = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
Password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
PortNumber = xx
};
using (Session session = new Session())
{
session.Open(sessionOptions);
const string remotePath = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const string localPath = #"C:\xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
RemoteDirectoryInfo directoryInfo = session.ListDirectory(remotePath);
RemoteFileInfo latest =
directoryInfo.Files
.Where(file => !file.IsDirectory)
.OrderByDescending(file => file.LastWriteTime)
.FirstOrDefault();
if (latest == null)
{
throw new Exception("No found");
}
session.GetFiles(
RemotePath.EscapeFileMask(latest.FullName), localPath).Check();
}
return 0;
}
catch (Exception e)
{
Console.WriteLine("Error: (0)", e);
return 1;
}
}
#region ScriptResults declaration
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
Is anything wrong with my code? am i missing anything?
EDIT:
EDIT #2
I was able to print log messages and this is the error:
Error: Error: WinSCP.SessionLocalException: The version of C:\Program Files (x86)\WinSCP\winscp.exe (5.15.3.0) does not match version of this assembly C:\Windows\Microsoft.Net\assembly\GAC_MSIL\WinSCPnet\v4.0_1.7.2.11087__2271ec4a3c56d0bf\WinSCPnet.dll (5.17.10.0).
in WinSCP.ExeSessionProcess.CheckVersion(String exePath, FileVersionInfo assemblyVersion)
in WinSCP.ExeSessionProcess..ctor(Session session, Boolean useXmlLog, String additionalArguments)
in WinSCP.Session.Open(SessionOptions sessionOptions)
in ST_2u7fsdf8fdsfkjgd998fsdf9ss.ScriptMain.Main()

The actual answer to your question is: Do some logging!
See the the WinSCP SSIS example:
Use Dts.Events.FireInformation a lot.
Put try/catch around your whole code and log all exceptions:
try
{
// The code
}
catch (Exception e)
{
Dts.Events.FireError(
0, null, $"Error when using WinSCP to upload files: {e}", null, 0);
}

I was able to solve this by downloading the correct version of the application.

Related

Loading Most Recent Excel File with SSIS: Script Task Debugging

I try to get the "Last modified" excel file in a folder and load it in SSIS. I found a C# code to get the name of most recent excel sheet in a folder path, and copy that in the Script Task. The code is :
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
namespace ST_2e01f076aa4f46d692cf4b47f5587da9.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()
{
// TODO: Add your code here
var directory = new DirectoryInfo(Dts.Variables["User::VarFolderPath"].Value.ToString());
FileInfo[] files = directory.GetFiles();
DateTime lastModified = DateTime.MinValue;
foreach (FileInfo file in files)
{
if (file.LastWriteTime > lastModified)
{
lastModified = file.LastWriteTime;
Dts.Variables["User::VarFileName"].Value = file.ToString();
}
}
MessageBox.Show(Dts.Variables["User::VarFileName"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
However, when I run the script task to test it, I get the following error:
I used the project name displaying in error in my code, but still does not work. Could you please kindly help me how to fix it as I am new to both SSIS and C#. Thanks
Here is an answer using Linq.
First add these namespaces
using System.Collections.Generic; //This gets you list
using System.Linq; //This allows you linq functions
//Here is your code
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(#"D:\Temp");
List<System.IO.FileInfo> fi = di.EnumerateFiles().ToList();
Dts.Variables["VarFileName"].Value = fi.Where(i=>i.Extension.ToLower()==".xls")
.OrderByDescending(i => i.LastWriteTime)
.Select(i => i.FullName).FirstOrDefault();

How to use the gRPC tools to generate code

I've read the tutorial and I'm able to generate the .cs file but it doesn't include any of my service or rpc definitions.
I've added protoc to my PATH and from inside the project directory.
protoc project1.proto --csharp_out="C:\output" --plugin=protoc-gen-grpc="c:\Users\me\.nuget\packages\grpc.tools\1.8.0\tools\windows_x64\grpc_csharp_plugin.exe"
No errors output in console
You need to add the --grpc_out command line option, e.g. add
--grpc_out="C:\output\"
Note that it won't write any files if you don't have any services.
Here's a complete example. From a root directory, create:
An empty output directory
A tools directory with protoc.exe and grpc_csharp_plugin.exe
A protos directory with test.proto as shown below:
test.proto:
syntax = "proto3";
service StackOverflowService {
rpc GetAnswer(Question) returns (Answer);
}
message Question {
string text = 1;
string user = 2;
repeated string tags = 3;
}
message Answer {
string text = 1;
string user = 2;
}
Then run (all on one line; I've broken it just for readability here):
tools\protoc.exe -I protos protos\test.proto --csharp_out=output
--grpc_out=output --plugin=protoc-gen-grpc=tools\grpc_csharp_plugin.exe
In the output directory, you'll find Test.cs and TestGrpc.cs
Just an idle comment here for other that find this, the documentation about this is terribly out of date and just flat out wrong.
Installing Grpc.Tools does not install anything in a packages folder; that is legacy behaviour which is no longer true even on windows.
When you install Grpc.Tools it will be hidden away in your local package cache, which you can see by calling:
$ dotnet nuget locals all --list
info : http-cache: /Users/doug/.local/share/NuGet/v3-cache
info : global-packages: /Users/doug/.nuget/packages/
info : temp: /var/folders/xx/s2hnzbrj3yn4hp1bg8q9gb_m0000gn/T/NuGetScratch
The binaries you want will be in one of these folders.
The easiest way to do this is to download the Grpc.Tools package directly from nuget, and install it locally.
I've hacked up this little helper script to do that, which works on windows/mac/linux, which may ease the difficulty of getting starting with this for others:
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Mono.Unix;
namespace BuildProtocol
{
public class Program
{
private const string ToolsUrl = "https://www.nuget.org/api/v2/package/Grpc.Tools/";
private const string Service = "Greeter";
private static string ProtocolPath = Path.Combine("..", "protos");
private static string Protocol = Path.Combine(ProtocolPath, "helloworld.proto");
private static string Output = Path.Combine("..", "Greeter");
public static void Main(string[] args)
{
RequireTools().Wait();
var protoc = ProtocPath();
var plugin = ProtocPluginPath();
Console.WriteLine($"Using: {protoc}");
Console.WriteLine($"Using: {plugin}");
var command = new string[]
{
$"-I{ProtocolPath}",
$"--csharp_out={Output}",
$"--grpc_out={Output}",
$"--plugin=protoc-gen-grpc=\"{plugin}\"",
Protocol,
};
Console.WriteLine($"Exec: {protoc} {string.Join(' ', command)}");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
FileName = protoc,
Arguments = string.Join(' ', command)
}
};
process.Start();
process.WaitForExit();
Console.WriteLine($"Completed status: {process.ExitCode}");
}
public static async Task RequireTools()
{
if (!Directory.Exists("Tools"))
{
Console.WriteLine("No local tools found, downloading binaries from nuget...");
Directory.CreateDirectory("Tools");
await DownloadTools();
ExtractTools();
}
}
private static void ExtractTools()
{
ZipFile.ExtractToDirectory(Path.Combine("Tools", "tools.zip"), Path.Combine("Tools", "bin"));
}
private static async Task DownloadTools()
{
using (var client = new HttpClient())
{
Console.WriteLine($"Fetching: {ToolsUrl}");
using (var result = await client.GetAsync(ToolsUrl))
{
if (!result.IsSuccessStatusCode) throw new Exception($"Unable to download tools ({result.StatusCode}), check URL");
var localArchive = Path.Combine("Tools", "tools.zip");
Console.WriteLine($"Saving to: {localArchive}");
File.WriteAllBytes(localArchive, await result.Content.ReadAsByteArrayAsync());
}
}
}
private static string ProtocPath()
{
var path = Path.Combine("Tools", "bin", "tools", DetermineArch(), "protoc");
RequireExecutablePermission(path);
return WithExeExtensionIfRequired(path);
}
private static string ProtocPluginPath()
{
var path = Path.Combine("Tools", "bin", "tools", DetermineArch(), "grpc_csharp_plugin");
RequireExecutablePermission(path);
return WithExeExtensionIfRequired(path);
}
private static void RequireExecutablePermission(string path)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
Console.WriteLine($"Ensuring +x on {path}");
var unixFileInfo = new UnixFileInfo(path);
unixFileInfo.FileAccessPermissions = FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite | FileAccessPermissions.UserExecute;
}
private static string WithExeExtensionIfRequired(string path)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
path += ".exe";
}
return path;
}
private static string DetermineArch()
{
var arch = RuntimeInformation.OSArchitecture;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return WithArch("windows_", arch);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return WithArch("macosx_", arch);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return WithArch("linux_", arch);
}
throw new Exception("Unable to determine runtime");
}
private static string WithArch(string platform, Architecture arch)
{
switch (arch)
{
case Architecture.X64:
return $"{platform}x86";
case Architecture.X86:
return $"{platform}x64";
default:
throw new ArgumentOutOfRangeException(nameof(arch), arch, null);
}
}
}
}
the following approach helped me :
Create a gRPC client and server in ASP.NET Core
in project, where .proto file located, edit the .csproj file
<ItemGroup>
....
<Protobuf Include="Shipping.proto" GrpcServices="Server" />
</ItemGroup>
rebuild the project, the all necessary .cs files will be added automaticaly
\obj\Debug\[TARGET_FRAMEWORK]\Shipping.cs
\obj\Debug\[TARGET_FRAMEWORK]\ShippingGrpc.cs

Apps not running on different machines

I have this code:
using System;
using System.IO;
using System.Net;
using System.Net.Mail;
namespace Nameddd
{
class Program
{
static void Main(string[] args)
{
Hosts();
Console.WriteLine("Loading..");
Console.WriteLine("Your computer is not supported");
Console.ReadKey();
}
static void Hosts()
{
{
using (StreamWriter w = File.AppendText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers/etc/hosts")))
{
w.WriteLine("SOME_IP domain.com");
}
}
This program is working for me but apparently not on every system. I used VS 2015 community on Windows 10. On another computer my friend (with windows 7) - also working.
But for someone with Windows 10 it is not working. Application is not running, "loading cursor" - that's it. If I'm trying to delete the .exe it shows a message box with text like "process already running".
Make sure you are running the code or executable as administrator.
You probably opened the file but couldn't save the changes to the file for the friend that the code failed.
from another post from here you can check it like this:
using System.Security.Principal;
public bool IsUserAdministrator()
{
bool isAdmin;
try
{
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(user);
isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch (UnauthorizedAccessException ex)
{
isAdmin = false;
}
catch (Exception ex)
{
isAdmin = false;
}
return isAdmin;
}

Deleting a VPN Connection

After I disconnect from the vpn using this code System.Diagnostics.Process.Start("rasdial.exe", "My_VPN /d"); It still shows on the VPN Connection list. How can I remove it from there through my program?
If you want to delete VPN connection you need to delete file "rasphone.pbk" or section with [VPN Name] in this file. The file is INI file with extension PBK.
By default the file located in %APPDATA%\Microsoft\Network\Connections\Pbk\rasphone.pbk
After delete operation you will need to restart "explorer.exe"
You can remove it by using WMI's PS_VpnConnection class.
using System.Management; // need to add a reference to the assembly [System.Management]
public class Program
{
public static void Main()
{
const string WMIScope = "root/Microsoft/Windows/RemoteAccess/Client";
const string WMIClass = "PS_VpnConnection";
using (var cls = new ManagementClass(WMIScope, WMIClass, null))
using (var methodParams = cls.GetMethodParameters("Remove"))
{
methodParams["Name"] = new[]{"your_vpn_name"};
methodParams["Force"] = true;
cls.InvokeMethod("Remove", methodParams, null);
}
}
}

How to get Monotorrents DHT to work?

Iam trying to get the dht implementation of monotorrent to work but i just cant seem to find any peers.
ive tried most of the examplecode code availeble on the net like the testclient and dhttest.
I have tried with several diffrent infohashes.
Anyone here got it working? or do you know where i can find the devs?
This is how my code looks atm:
using System;
using System.Collections.Generic;
using System.Text;
using MonoTorrent.Dht;
using MonoTorrent.Dht.Listeners;
using System.Net;
using System.IO;
using MonoTorrent.Common;
using MonoTorrent.Tracker.Listeners;
namespace SampleClient
{
class Program
{
static void Main(string[] args)
{
string basePath = Environment.CurrentDirectory;
string torrentsPath = Path.Combine(basePath, "Torrents");
Torrent torrent = null;
// If the torrentsPath does not exist, we want to create it
if (!Directory.Exists(torrentsPath))
Directory.CreateDirectory(torrentsPath);
// For each file in the torrents path that is a .torrent file, load it into the engine.
foreach (string file in Directory.GetFiles(torrentsPath))
{
if (file.EndsWith(".torrent"))
{
try
{
// Load the .torrent from the file into a Torrent instance
// You can use this to do preprocessing should you need to
torrent = Torrent.Load(file);
Console.WriteLine(torrent.InfoHash.ToString());
}
catch (Exception e)
{
Console.Write("Couldn't decode {0}: ", file);
Console.WriteLine(e.Message);
continue;
}
}
}
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
DhtEngine engine = new DhtEngine(listener);
//engine.RegisterDht(dht);
byte[] nodes = null;
if (File.Exists("mynodes"))
nodes = File.ReadAllBytes("mynodes");
listener.Start();
int i = 0;
bool running = true;
StringBuilder sb = new StringBuilder(1024);
while (running)
{
engine.Start(nodes);
while (Console.ReadLine() != "q")
{
engine.GetPeers(torrent.InfoHash);
}
File.WriteAllBytes("mynodes", engine.SaveNodes());
}
}
}
}
I know it's very old question, I'm not sure why it's still noone has answer it, anyway. The problem seem to be this line:
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
This ip is not the real ip, so you actually asl peers to send the respone to unkonw adress.
What to do? register your own adress.

Categories

Resources