i wrote like the following code.
but this code is not available...
when i execute, occur.
if anyone knows something, give me advice pls...
thanks in advance.
void sftp_OnTransferEnd(string src, string dst, int transferredBytes
, int totalBytes, string message)
{
if (sftp == null)
{
sftp = new Sftp(Const.SFTP_HOST, Const.SFTP_USER, Const.SFTP_PASSWORD);
sftp.Connect();
}
SftpChannel.rename("file/123_Uploading.zip", "file/123_Finished.zip");
}
--------------------------------------------
Sftp.cs
public void Rename(string oldPath, string newPath)
{
SftpChannel.rename(oldPath, newPath);
}
---------------------------------------------
Error occur the following place...
---------------------------------------------------------
ChannelSftp.cs
public void rename(String oldpath, String newpath)
{
・
・
・
int i=buf.getInt(); << i == 4
if(i==SSH_FX_OK) return;
throwStatusError(buf, i); << throw error
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e; << thrown error (id >> 4, message >> Failure)
throw new SftpException(SSH_FX_FAILURE, "");
}
}
The current NuGet package is still of version 1.1.1.13 which does not contain the Rename method. It would be great if the package maintainer could update it.
But in the meantime if anyone else needs it with the current NuGet package, here is a Reflection-based extension method solution. Not nice, but at least I can use the package without forking/rebuilding, etc.
public static void Rename(this Sftp client, string oldName, string newName) {
var channelProperty = client.GetType().GetProperty("SftpChannel", BindingFlags.NonPublic | BindingFlags.Instance);
channelProperty.GetValue(_client, null).CastTo<ChannelSftp>().rename(OldName, newName);
}
I added your
public void Rename(string oldPath, string newPath)
{
SftpChannel.rename(oldPath, newPath);
}
code into Sftp.cs class and I called it :
var sftp = new Sftp("sftp.example.com", username, password);
sftp.Connect(22);
sftp.Rename(oldValue, newValue);
sftp.Close();
then it renamed my file successfully.Thanks by the way
Related
For instance, I want to obtain the uri of a Spotify track and put it in another method as a String value, however I'm lost on how I'd go about doing that. I tried experimenting with SharedPreferences to get the value but getString method wasn't working. I was just wondering if there's a simpler way to getting say track.getUri (or any) in another method from the Async/Sync method. Any assistance would be greatly appreciated.
The code so far:
private static final String accessToken = "...";
private static final String id = "01iyCAUm8EvOFqVWYJ3dVX";
public static SharedPreferences.Editor editor;
private static final SpotifyApi spotifyApi = new SpotifyApi.Builder()
.setAccessToken(accessToken)
.build();
private static final GetTrackRequest getTrackRequest = spotifyApi.getTrack(id)
// .market(CountryCode.SE)
.build();
public static void getTrack_Sync() {
try {
final Track track = getTrackRequest.execute();
System.out.println("Name: " + track.getName());
} catch (IOException | SpotifyWebApiException | ParseException e) {
System.out.println("Error: " + e.getMessage());
}
}
#RequiresApi(api = Build.VERSION_CODES.N)
public void getTrack_Async() {
try {
final CompletableFuture<Track> trackFuture = getTrackRequest.executeAsync();
// Thread free to do other tasks...
// Example Only. Never block in production code.
final Track track = trackFuture.join();
String uri = track.getUri();
editor = getSharedPreferences("uri", 0).edit();
editor.putString("uri", uri);
editor.commit();
editor.apply();
System.out.println("Name: " + track.getUri());
} catch (CompletionException e) {
System.out.println("Error: " + e.getCause().getMessage());
} catch (CancellationException e) {
System.out.println("Async operation cancelled.");
}
}
public void go() {
getTrack_Async();
// String value = editor.getString("uri", )
}
To get the track you need some kind of information to start with. e.g. I have the spotify trackId and can find the track (synchronously) like this:
public Track getTrack(String trackId) {
return spotifyApi.getTrack(trackId).build().execute();
}
Now the Track object (specifically com.wrapper.spotify.model_objects.specification.Track) provides a lot of information. e.g. the field uri.
So you could do just:
public void run(String trackId) {
Track track = spotifyApi.getTrack(trackId).build().execute();
String uri = track.uri;
// now call something else with the uri?
}
Does that help? Your question was not entirely clear for me.
I got some questions regarding the use of threads, specially when you have to wait for a thread to be finished so you can perform other operations.
In my app, I use threads for operations such as http connections or when I read from or write to a RecordStore.
For example in the following class that I use to initialize my thread, I retrieve some customers from a webservice using the method called HttpQueryCustomers.
public class thrLoadCustomers implements Runnable {
private RMSCustomer mRMSCustomer;
private String mUrl;
public thrLoadCustomers(RMSCustomer rmsCust, String url) {
mRMSCustomer = rmsCust;
mUrl = url;
}
public void run() {
String jsonResultados = "";
try {
jsonResultados = HttpQueryCustomers();
} catch (IOException ex) {
//How to show a message from here??
} catch (SecurityException se) {
//How to show a message here??
} catch (NullPointerException npe) {
//How to show a message from here??
}
if (!jsonResultados.equals("")) {
try {
mRMSCustomer.save(jsonResultados);
} catch (RecordStoreException ex) {
//How to show a message from here???
}
}
}
public String HttpQueryCustomers() throws IOException,SecurityException,NullPointerException {
StringBuffer stringBuffer = new StringBuffer();
HttpConnection hc = null;
InputStream is = null;
System.out.println(mUrl);
try {
hc = (HttpConnection) Connector.open(mUrl);
if (hc.getResponseCode() == HttpConnection.HTTP_OK) {
is = hc.openInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
}
} finally {
is.close();
hc.close();
}
String jsonData = stringBuffer.toString();
return jsonData.toString();
}
}
Notice in the above class that I pass a parameter called rmsCust of the type RMSCustomer
RMSCustomer is a class that I use to handle all the operations related to RMS:
public class RMSCustomer {
private String mRecordStoreName;
private Customer[] mCustomerList;
public RMSCustomer(String recordStoreName) {
mRecordStoreName = recordStoreName;
}
public Customer[] getCustomers() {
return mCustomerList;
}
public Customer get(int index) {
return mCustomerList[index];
}
public void save(String data) throws RecordStoreException,JSONException,NullPointerException {
RecordStore rs = null;
int idNuevoRegistro;
String stringJSON;
try {
rs = RecordStore.openRecordStore(mRecordStoreName, true);
JSONArray js = new JSONArray(data);
//Set the size of the array
mCustomerList = new Customer[js.length()];
for (int i = 0; i < js.length(); i++) {
JSONObject jsObj = js.getJSONObject(i);
stringJSON = jsObj.toString();
idNuevoRegistro = addRecord(stringJSON, rs);
//Add a new Customer to the array
mCustomerList[i] = initializeCustomer(stringJSON, idNuevoRegistro);
}
} finally {
if (rs != null) {
rs.closeRecordStore();
}
}
}
public int addRecord(String stringJSON, RecordStore rs) throws JSONException,RecordStoreException {
byte[] raw = stringJSON.getBytes();
int idNuevoRegistro = rs.addRecord(raw, 0, raw.length);
return idNuevoRegistro;
}
public Customer initializeCustomer(String stringJSON, int idRecord) throws JSONException {
Customer c = new Customer();
JSONObject jsonObj = new JSONObject(stringJSON);
// Set Customer properties
//...
return c;
}
}
This class is used to show a list of customer and ,as you can see, it extends the List class and receives an array of Customers as a parameter.
public class ListCustomers extends List {
private final Customer[] mData;
public static ListCustomers create(Customer[] data) {
int i = 0;
for (; i < data.length; i++) {
if (data[i] == null) {
break;
}
}
String[] names = new String[i];
for (int j = 0; j < i; j++) {
names[j] = data[j].name;
}
return new ListCustomers(names, data);
}
protected ListCustomers(String names[], Customer[] data) {
super("List of Customer", IMPLICIT, names, null);
mData = data;
}
public Customer getSelectedObject() {
return mData[this.getSelectedIndex()];
}
}
Finally this is how I call the thread from the MIDlet (using all the 3 previous classes) when I want to show a List of Customers:
private void showCustomerList(String url) {
showWaitForm();
if (scrCustomerList == null) {
rmsCustomers = new RMSCustomer("rmsCustomers");
thrLoadCustomers load = new thrLoadCustomers(rmsCustomers, url);
Thread t = new Thread(load);
t.start();
try {
t.join();
} catch (InterruptedException ex) {
}
scrCustomerList = ListCustomers.create(rmsCustomers.getCustomers());
scrCustomerList.addCommand(cmdSelect);
scrCustomerList.addCommand(cmdBack);
scrCustomerList.setCommandListener(this);
}
mDisplay.setCurrent(scrCustomerList);
}
Now here's the problems I have :
The showWaitForm() doesn't work (it sets a form with a Gauge as the
Current form)
I don't know how to show all the exceptions that might be thrown from
within the thrLoadCustomers class.
I don't know whether using t.join() is the best choice
The last question is about something the book I'm reading says :
Threads, in particular, can be a scarce commodity. The MSA
specification requires that an application must be allowed to create
ten threads. Just because you can doesn’t mean you should. In general,
try to use the fewest resources possible so that your application will
run as smoothly as possible
This is the first time a use threads, and in my app I might have up to 10 threads (classes). However, I will only execute once thread at the time, will I be going against what the previous quotation says??
I hope I'm not asking too many questions. Thank you very much for your help.
P.D Much of the code I posted here wouldn't have been possible with the help of Gregor Ophey
Question #1 is about a different problem not related to threading, and for which very little code is shown. I'd suggest you to post a new dedicated question with proper explanation of the issue.
Questions #2 and #3: You could define a wrapper class like this:
public class WSResult {
private boolean success; //true if the WS call went ok, false otherwise
private String errorMessage; //Error message to display if the WS call failed.
private Object result; //Result, only if the WS call succeeded.
private boolean completed = false;
//TODO getter and setters methods here
}
In your screen, you can create an instance of result and wait for it:
WSResult result = new WSResult();
//Start thread here
new Thread(new LoadCustomersTask(result)).start();
//This is old school thread sync.
synchronized(result){
while(!result.isCompleted()){
result.wait();
}
}
//Here the thread has returned, and we can diaplay the error message if any
if(result.isSuccess()){
} else {
//Display result.getErrorMessage()
}
Then your runnable would be like this:
class LoadCustomersTask implements Runnable {
private final WSResult result;
public LoadCustomersTask(WSResult res){
result = res;
}
public void run(){
//Do the WS call
//If it went well
result.setSuccess(true);
result.setResult(jsonResultados);
//Else
result.setSuccess(false);
result.setErrorMessage("Your error message");
//In any case, mark as completed
result.setcompleted(true);
//And notify awaiting threads
synchronized(result){
result.notifyAll();
}
}
}
You can also do it with thread.join, but wait/notify is better because you not making the screen depend on the particular thread where the runnable runs. You can wait/notify on the result instance, as shown, or on the runnable if it is intended for a single use.
Question #4: Yes threads must not be abused, specially in JavaME where programs usually run in single core CPUs with a frecuency in the order of MHz. Try not to have more than 1-3 threads running at the same time. If you really need to, consider using a single thread for running all background tasks (a blocking queue).
I'm currently working on creating a namespace extension.
So I want to create an entry in Computer, and had explorer.exe calling my IShellFolder implementation.
I had it working for few minutes (I stupidly decided to clean up the code before commiting), so I'm somewhere near.
But I noticed something very strange: changing the GUID value of the Class change what I see in explorer.exe
I found that question which tells me I am not doing something bad
Here's the code:
AssemblyInfo.cs:
[assembly: ComVisible(false)]
[assembly: Guid("007C5100-4251-47BE-8141-D2AD3F496E6A")]
RootFolder.cs:
[ClassInterface(ClassInterfaceType.None)
[Guid("007C5101-4251-47BE-8141-D2AD3F496E6A"), ComVisible(true)]
public class RootFolder : IShellFolder, IShellFolder2, IPersistFolder, IPersistFolder2 {
private const String _mountPoint = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace\\{0}";
private const String _mountName = "CLSID\\{0}";
#region Shell Extension Registration
[ComRegisterFunction()]
public static void Register(Type t)
{
Console.WriteLine("Registering {0}...", t.GUID);
try {
if (t.GUID == null)
throw new ArgumentException("CLSID must not be null");
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(String.Format(_mountPoint, t.GUID.ToString("B")))) {
key.SetValue(null, "RootFolder");
}
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(String.Format(_mountName, t.GUID.ToString("B")), true)) {
key.SetValue(null, "RootFolder");
using (RegistryKey shFolder = key.CreateSubKey("ShellFolder")) {
shFolder.SetValue("Attributes", 0x78000040);
shFolder.SetValue("WantsFORPARSING", "");
}
}
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved")) {
key.SetValue(t.GUID.ToString("B"), "RootFolder");
}
IntPtr pidl = NativeMethod.SHGetKnownFolderIDList(KnownFolder.ComputerFolder.clsid, 0, IntPtr.Zero);
NativeMethod.SHChangeNotify(NativeMethod.FSNotification.UpdateDir, NativeMethod.ItemMeaning.IDList, pidl, IntPtr.Zero);
} catch (Exception ex) {
Logger.Write(Logger.Severity.Fatal, "Registration error: {0}", ex.Message);
throw; // Re-throw the exception
}
}
[ComUnregisterFunction()]
public static void Unregister(Type t)
{
try {
if (t.GUID == null)
throw new ArgumentException("CLSID must not be null");
Registry.CurrentUser.DeleteSubKey(String.Format(_mountPoint, t.GUID.ToString("B")), false);
using (RegistryKey k = Registry.ClassesRoot.OpenSubKey(String.Format(_mountName, t.GUID.ToString("B")), true)) {
if (k != null)
k.DeleteSubKey("ShellFolder");
}
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved")) {
if (key != null)
key.DeleteValue(t.GUID.ToString("B"), false);
}
IntPtr pidl = NativeMethod.SHGetKnownFolderIDList(KnownFolder.ComputerFolder.clsid, 0, IntPtr.Zero);
NativeMethod.SHChangeNotify(NativeMethod.FSNotification.UpdateDir, NativeMethod.ItemMeaning.IDList, pidl, IntPtr.Zero);
} catch (Exception ex) {
Logger.Write(Logger.Severity.Critical, "Registration error: {0}", ex.Message);
throw; // Re-throw the exception
}
}
#endregion
#region IShellFolder2 Inheritance
[All the methods looks like that, this is just a test]
public IEnumIDList EnumObjects(IntPtr hwndOwner, EnumObject flags)
{
Logger.Write("Tracing....");
throw new NotImplementedException();
}
#endregion
#region IPersistFolder2 Inheritance
[Ditto]
#endregion
}
I use the range 007C5{100...120}-4251-47BE-8141-D2AD3F496E6A for my GUIDs
When my extension has GUID 007C5101, it just shows "RootFolder" without any attributes.
When it has 007C5100 (same as assembly), or 007C5102, or 007C5103, it is shown as "System Folder" (even though it doesnt call my DLL).
I'm a little puzzled by this behaviour, how in the world can changing a GUID lead to this change ?
Note: I ran a search through the registry for 4251-47BE-8141-D2AD3F496E6A (the immutable part of my GUID), and couldn't find anything after unregistration.
I wanted to debug the Seed() method in my Entity Framework database configuration class when I run Update-Database from the Package Manager Console but didn't know how to do it. I wanted to share the solution with others in case they have the same issue.
Here is similar question with a solution that works really well.
It does NOT require Thread.Sleep.
Just Launches the debugger using this code.
Clipped from the answer
if (!System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Launch();
The way I solved this was to open a new instance of Visual Studio and then open the same solution in this new instance of Visual Studio. I then attached the debugger in this new instance to the old instance (devenv.exe) while running the update-database command. This allowed me to debug the Seed method.
Just to make sure I didn't miss the breakpoint by not attaching in time I added a Thread.Sleep before the breakpoint.
I hope this helps someone.
If you need to get a specific variable's value, a quick hack is to throw an exception:
throw new Exception(variable);
A cleaner solution (I guess this requires EF 6) would IMHO be to call update-database from code:
var configuration = new DbMigrationsConfiguration<TContext>();
var databaseMigrator = new DbMigrator(configuration);
databaseMigrator.Update();
This allows you to debug the Seed method.
You may take this one step further and construct a unit test (or, more precisely, an integration test) that creates an empty test database, applies all EF migrations, runs the Seed method, and drops the test database again:
var configuration = new DbMigrationsConfiguration<TContext>();
Database.Delete("TestDatabaseNameOrConnectionString");
var databaseMigrator = new DbMigrator(configuration);
databaseMigrator.Update();
Database.Delete("TestDatabaseNameOrConnectionString");
But be careful not to run this against your development database!
I know this is an old question, but if all you want is messages, and you don't care to include references to WinForms in your project, I made some simple debug window where I can send Trace events.
For more serious and step-by-step debugging, I'll open another Visual Studio instance, but it's not necessary for simple stuff.
This is the whole code:
SeedApplicationContext.cs
using System;
using System.Data.Entity;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace Data.Persistence.Migrations.SeedDebug
{
public class SeedApplicationContext<T> : ApplicationContext
where T : DbContext
{
private class SeedTraceListener : TraceListener
{
private readonly SeedApplicationContext<T> _appContext;
public SeedTraceListener(SeedApplicationContext<T> appContext)
{
_appContext = appContext;
}
public override void Write(string message)
{
_appContext.WriteDebugText(message);
}
public override void WriteLine(string message)
{
_appContext.WriteDebugLine(message);
}
}
private Form _debugForm;
private TextBox _debugTextBox;
private TraceListener _traceListener;
private readonly Action<T> _seedAction;
private readonly T _dbcontext;
public Exception Exception { get; private set; }
public bool WaitBeforeExit { get; private set; }
public SeedApplicationContext(Action<T> seedAction, T dbcontext, bool waitBeforeExit = false)
{
_dbcontext = dbcontext;
_seedAction = seedAction;
WaitBeforeExit = waitBeforeExit;
_traceListener = new SeedTraceListener(this);
CreateDebugForm();
MainForm = _debugForm;
Trace.Listeners.Add(_traceListener);
}
private void CreateDebugForm()
{
var textbox = new TextBox {Multiline = true, Dock = DockStyle.Fill, ScrollBars = ScrollBars.Both, WordWrap = false};
var form = new Form {Font = new Font(#"Lucida Console", 8), Text = "Seed Trace"};
form.Controls.Add(tb);
form.Shown += OnFormShown;
_debugForm = form;
_debugTextBox = textbox;
}
private void OnFormShown(object sender, EventArgs eventArgs)
{
WriteDebugLine("Initializing seed...");
try
{
_seedAction(_dbcontext);
if(!WaitBeforeExit)
_debugForm.Close();
else
WriteDebugLine("Finished seed. Close this window to continue");
}
catch (Exception e)
{
Exception = e;
var einner = e;
while (einner != null)
{
WriteDebugLine(string.Format("[Exception {0}] {1}", einner.GetType(), einner.Message));
WriteDebugLine(einner.StackTrace);
einner = einner.InnerException;
if (einner != null)
WriteDebugLine("------- Inner Exception -------");
}
}
}
protected override void Dispose(bool disposing)
{
if (disposing && _traceListener != null)
{
Trace.Listeners.Remove(_traceListener);
_traceListener.Dispose();
_traceListener = null;
}
base.Dispose(disposing);
}
private void WriteDebugText(string message)
{
_debugTextBox.Text += message;
Application.DoEvents();
}
private void WriteDebugLine(string message)
{
WriteDebugText(message + Environment.NewLine);
}
}
}
And on your standard Configuration.cs
// ...
using System.Windows.Forms;
using Data.Persistence.Migrations.SeedDebug;
// ...
namespace Data.Persistence.Migrations
{
internal sealed class Configuration : DbMigrationsConfiguration<MyContext>
{
public Configuration()
{
// Migrations configuration here
}
protected override void Seed(MyContext context)
{
// Create our application context which will host our debug window and message loop
var appContext = new SeedApplicationContext<MyContext>(SeedInternal, context, false);
Application.Run(appContext);
var e = appContext.Exception;
Application.Exit();
// Rethrow the exception to the package manager console
if (e != null)
throw e;
}
// Our original Seed method, now with Trace support!
private void SeedInternal(MyContext context)
{
// ...
Trace.WriteLine("I'm seeding!")
// ...
}
}
}
Uh Debugging is one thing but don't forget to call:
context.Update()
Also don't wrap in try catch without a good inner exceptions spill to the console.
https://coderwall.com/p/fbcyaw/debug-into-entity-framework-code-first
with catch (DbEntityValidationException ex)
I have 2 workarounds (without Debugger.Launch() since it doesn't work for me):
To print message in Package Manager Console use exception:
throw new Exception("Your message");
Another way is to print message in file by creating a cmd process:
// Logs to file {solution folder}\seed.log data from Seed method (for DEBUG only)
private void Log(string msg)
{
string echoCmd = $"/C echo {DateTime.Now} - {msg} >> seed.log";
System.Diagnostics.Process.Start("cmd.exe", echoCmd);
}
I am using svnkit-1.3.5.jar in my application. On one of my screens on clicking a button I need to display a jQuery dialog box containing list of folders present at a particular path in SVN. Does svnkit provide any method that retrieves all folder names present at a specific location? How do I achieve this in java?
Here is the code i use for the same purpose (uses svnkit library). Modified version of #mstrap's code for better clarity.
public static String NAME = "svnusername";
public static String PASSWORD = "svnpass";
public final String TRUNK_VERSION_PATH = "svn://192.168.1.1/path";
public static List<String> apiVersions;
public List<String> getApiVersion() {
logger.info("Getting API Version list....");
apiVersions = new ArrayList<String>();
SVNURL repositoryURL = null;
try {
repositoryURL = SVNURL.parseURIEncoded(TRUNK_VERSION_PATH);
} catch (SVNException e) {
logger.error(e);
}
SVNRevision revision = SVNRevision.HEAD;
SvnOperationFactory operationFactory = new SvnOperationFactory();
operationFactory.setAuthenticationManager(new BasicAuthenticationManager(NAME, PASSWORD));
SvnList list = operationFactory.createList();
list.setDepth(SVNDepth.IMMEDIATES);
list.setRevision(revision);
list.addTarget(SvnTarget.fromURL(repositoryURL, revision));
list.setReceiver(new ISvnObjectReceiver<SVNDirEntry>() {
public void receive(SvnTarget target, SVNDirEntry object) throws SVNException {
String name = object.getRelativePath();
if(name!=null && !name.isEmpty()){
apiVersions.add(name);
}
}
});
try {
list.run();
} catch (SVNException ex) {
logger.error(ex);
}
return apiVersions;
}
Cheers!!
final URL url = ...
final SVNRevision revision = ...
final SvnOperationFactory operationFactory = ...
final SvnList list = operationFactory.createList();
list.setDepth(SVNDepth.IMMEDIATES);
list.setRevision(revision);
list.addTarget(SvnTarget.fromURL(url, revision);
list.setReceiver(new ISvnObjectReceiver<SVNDirEntry>() {
public void receive(SvnTarget target, SVNDirEntry object) throws SVNException {
final String name = object.getRelativePath();
System.out.println(name);
}
});
list.run();