.Net FileSystemWatcher when renaming file oldName is null - filesystemwatcher

I am trying to keep on track with changes on the filesystem. Therefore I use the FileSystemWatcher. Unfortunately the Renamed event does not provide the oldName information on Windows 7 and Windows 8. On Windows XP it works perfect.
This is my program:
using System;
using System.IO;
namespace Watcher2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter Folder Name:");
string folder = Console.ReadLine();
Console.WriteLine("Watching folder "+folder);
FileSystemWatcher watcher = new FileSystemWatcher(folder, "*.*");
watcher.EnableRaisingEvents = true;
watcher.IncludeSubdirectories = true;
watcher.Renamed += watcher_Renamed;
Console.ReadLine();
}
static void watcher_Renamed(object sender, RenamedEventArgs e)
{
Console.WriteLine(string.Format("OldName is {0} \nName is {1}\nOldFullPath is {2}\nFullPath is {3}", (e.OldName ?? "NULL"), e.Name, e.OldFullPath, e.FullPath));
}
}
The RenamedEventArgs do not provide the OldName (e.OldName is NULL). Using Windows XP is no option :)
Am I missing something here?

I updated to Windows 8.1 now I get the OldName as expected..

Related

Creating a local database in windows phone app 8 using vs2012

I want to develop an app in windows phone 8.
I am totally new to this. I want to create a database for that app from which I can perform CRUID Operations.
I found some information while browsing and watching videos but I did't understand much of it.
Some Steps I did:
Installed windows phone app 8 sdk for vs2012
Added some Sqlite extension from Manage Nuget Packages.
Developed a basic interface for the app.
Copied and pasted the code with few changes
What I want:
Permanently Insert and Fetch data from database (I had downloaded a code from some website but after running it when I close the emulator and try to view the data previously entered, it won't return it)
Like it should be stored in phone memory or any such place
Display the fetched data in listview or grid
Please send me the link that i can go through or any such resembling question asked here
The MainPage.xaml.cs Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using CustomerPhoneApp.Resources;
using SQLite;
using System.IO;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Popups;
using System.Data.Linq;
using System.Diagnostics;
namespace CustomerPhoneApp
{
public partial class MainPage : PhoneApplicationPage
{
[Table("Users")]
public class User
{
[PrimaryKey, Unique]
public string Name { get; set; }
public string Age { get; set; }
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
try
{
var path = ApplicationData.Current.LocalFolder.Path + #"\users.db";
var db = new SQLiteAsyncConnection(path);
await db.CreateTableAsync<User>();
}
catch (Exception)
{
}
}
// Constructor
public MainPage()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
if (txtName.Text != "" && txtAge.Text != "")
{
var path = ApplicationData.Current.LocalFolder.Path + #"\users.db";
var db = new SQLiteAsyncConnection(path);
var data = new User
{
Name = txtName.Text,
Age = txtAge.Text,
};
int x = await db.InsertAsync(data);
}
else
{
MessageBox.Show("enter the title and Notes");
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
RetriveUserSavedData();
}
private async void RetriveUserSavedData()
{
string Result = "";
var path = ApplicationData.Current.LocalFolder.Path + #"\users.db";
var db = new SQLiteAsyncConnection(path);
List<User> allUsers = await db.QueryAsync<User>("Select * From Users");
var count = allUsers.Any() ? allUsers.Count : 0;
foreach (var item in allUsers)
{
Result += "Name: " + item.Name + "\nAge: " + item.Age.ToString() + "\n\n";
}
if (Result.ToString() == "")
{
MessageBox.Show("No Data");
}
else
{
MessageBox.Show(Result.ToString());
}
}
private void txtName_TextChanged(object sender, TextChangedEventArgs e)
{
}
private void txtName_GotFocus(object sender, RoutedEventArgs e)
{
txtName.Text = "";
}
private void txtAge_GotFocus(object sender, RoutedEventArgs e)
{
txtAge.Text = "";
}
}
}
1.-Permanently Insert and Fetch data from database (I had downloaded a code from some website but after running it when I close the emulator and try to view the data previously entered, it won't return it)
When you close the emulator you lost all apps installet on it, so if you close it, you lost all. If you want test your data save, you can close the application (only de app, not the emulator) and open it from your app list in the WP emulator.
Like it should be stored in phone memory or any such place
With SQL lite you canĀ“t store the data in the SD, it will be stored in your app directory, if you want use the SD to store data, you can use binary files
Display the fetched data in listview or grid
To show your data in the listview or grid, you need create a ViewModel or DataContext and then use Binding to "send" the data to de view.

Downloads with JavaFX WebView

my web application offers a download. Javascript creats at the click the url (it depends on the user input) and the browser should open it, so that the page isn't reloaded.
For that, I think I have to alternatives:
// Alt1:
window.open(pathToFile);
// Alt2:
var downloadFrame = document.getElementById('downloads');
if (downloadFrame === null) {
downloadFrame = document.createElement('iframe');
downloadFrame.id = 'downloads';
downloadFrame.style.display = 'none';
document.body.appendChild(downloadFrame);
}
downloadFrame.src = pathToFile;
Both works under Firefox. Problem with open new window method: If the creation of the file at the server needs more time, the new empty tab will be closed late.
Problem with iframe: If there is an error at the server, no feedback is given.
I think at firefox the iframe is the better solution. But the web application must run with an JavaFX WebView, too. JavaFX haven't a download feature, I have to write it. One possible way is to listen on the location property:
final WebView webView = new WebView();
webView.getEngine().locationProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) {
if (newLoc.cotains("/download")) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Save " + newLoc);
File saveFile = chooser.showSaveDialog(webView.getEngine().getScene().getWindow());
if (saveFile != null) {
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
is = new BufferedInputStream(new URL(newLoc).openStream());
os = new BufferedOutputStream(new FileOutputStream(saveFile));
while ((readBytes = is.read()) != -1) {
os.write(b);
}
} finally {
try { if (is != null) is.close(); } catch (IOException e) {}
try { if (os != null) os.close(); } catch (IOException e) {}
}
}
}
}
}
There are some problems:
The download start depends on a part of the url, because JafaFX supports no access to the http headers (that is bearable)
If the user starts the download with the same url two times, only the first download works (the change event only fires, if the url is new). I can crate unique urls (with #1, #2 and so on at the end). But this is ugly.
Only the "window.open(pathToFile);" method works. Loading an iframe don't fire the change location event of the website. That is expectable but I haven't found the right Listener.
Can someone help me to solve 2. or 3.?
Thank you!
PS: Sorry for my bad english.
edit:
For 2. I found a way. I don't know if it is a good one, if it is performant, if the new webview is deleted or is in the cache after download, ....
And the user don't get an feedback, when some a problem is raised:
webView.getEngine().setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
#Override public WebEngine call(PopupFeatures config) {
final WebView downloader = new WebView();
downloader.getEngine().locationProperty().addListener(/* The Listener from above */);
return downloader.getEngine();
}
}
I think you may just need to use copyURLtoFile to get the file...call that when the location changes or just call that using a registered java class. Something like this:
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
Using copyURLToFile the current page doesn't have to serve the file. I think registering the class is probably the easiest way to go... something like this:
PHP Code:
Download $filename
Java (in-line class in your javafx class/window... in this case my javafx window is inside of a jframe):
public class JavaApp {
JFrame cloudFrameREF;
JavaApp(JFrame cloudFrameREF)
{
this.cloudFrameREF = cloudFrameREF;
}
public void getfile(String filename) {
String newLoc = "http://your_web_site.com/send_file.php?filename=" + filename;
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
}
}
This part would go in the main javafx class:
Platform.runLater(new Runnable() {
#Override
public void run() {
browser2 = new WebView();
webEngine = browser2.getEngine();
appREF = new JavaApp(cloudFrame);
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
#Override public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
JSObject win
= (JSObject) webEngine.executeScript("window");
// this next line registers the JavaApp class with the page... you can then call it from javascript using "app.method_name".
win.setMember("app", appREF);
}
}
});
You may not need the frame reference... I was hacking some of my own code to test this out and the ref was useful for other things...

Debugging Package Manager Console Update-Database Seed Method

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);
}

How to embed a program inside another using GTK, XLib or any similar?

I'm trying to make a "simple" program, all it does is to list all opened programs and, once you choose one, it opens it inside your window (like a thumbnail you may say, but you can also interact).
One thing, it has to be one way only (I can't alter the embbeded program and add a "socket" or "plug" for instance). I want to be able to embbed any program (e.g. Opera, evince, JDownloader etc).
Does anyone have any idea of how can I do it?
If it can't be done using GTK, can it be done using X or any similar? How?
It appears that you're looking for something like XEmbed. A good tutorial in python and gtk is at http://www.moeraki.com/pygtktutorial/pygtk2tutorial/sec-PlugsAndSockets.html
You can use GtkPlug and GtkSocket for that.
using System;using Gtk;using System.Runtime.InteropServices; public partial class MainWindow : Gtk.Window{
public MainWindow () : base(Gtk.WindowType.Toplevel)
{
Gtk.Socket socket;
int xid;
Fixed fixed2=new Fixed();
this.socket = new Socket();
this.socket.WidthRequest = 500;
this.socket.HeightRequest = 500;
this.socket.Visible = true;
this.socket.Realized += new EventHandler(OnVideoWidgetRealized);
fixed2.Put(socket, 0, 0);
fixed2.SetSizeRequest(500,500);
this.Add(fixed2);
this.ShowAll();
OnButton17Clicked();
}
protected virtual void OnVideoWidgetRealized (object sender, EventArgs
args)
{
this.xid = (int)socket.Id;
Console.WriteLine("this.xid:"+this.xid);
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
this.socket = new Socket();
}
protected void OnButton17Clicked ()
{
var paramString = string.Format("-wid {0} 1.avi", xid);
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "mplayer.exe";
proc.StartInfo.Arguments = paramString;
proc.Start();
proc.WaitForExit();
}
public static void Main()
{
Application.Init();
new MainWindow();
Application.Run();
}}

File Read/Write Locks

I have an application where I open a log file for writing. At some point in time (while the application is running), I opened the file with Excel 2003, which said the file should be opened as read-only. That's OK with me.
But then my application threw this exception:
System.IO.IOException: The process cannot access the file because another process has locked a portion of the file.
I don't understand how Excel could lock the file (to which my app has write access), and cause my application to fail to write to it!
Why did this happen?
(Note: I didn't observe this behavior with Excel 2007.)
Here is a logger which will take care of sync locks. (You can modify it to fit to your requirements)
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Owf.Logger
{
public class Logger
{
private static object syncContoller = string.Empty;
private static Logger _logger;
public static Logger Default
{
get
{
if (_logger == null)
_logger = new Logger();
return _logger;
}
}
private Dictionary<Guid, DateTime> _starts = new Dictionary<Guid, DateTime>();
private string _fileName = "Log.txt";
public string FileName
{
get { return _fileName; }
set { _fileName = value; }
}
public Guid LogStart(string mesaage)
{
lock (syncContoller)
{
Guid id = Guid.NewGuid();
_starts.Add(id, DateTime.Now);
LogMessage(string.Format("0.00\tStart: {0}", mesaage));
return id;
}
}
public void LogEnd(Guid id, string mesaage)
{
lock (syncContoller)
{
if (_starts.ContainsKey(id))
{
TimeSpan time = (TimeSpan)(DateTime.Now - _starts[id]);
LogMessage(string.Format("{1}\tEnd: {0}", mesaage, time.TotalMilliseconds.ToString()));
}
else
throw new ApplicationException("Logger.LogEnd: Key doesn't exisits.");
}
}
public void LogMessage(string message)
{
lock (syncContoller)
{
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (!filePath.EndsWith("\\"))
filePath += "\\owf";
else
filePath += "owf";
if (!Directory.Exists(filePath))
Directory.CreateDirectory(filePath);
filePath += "\\Log.txt";
lock (syncContoller)
{
using (StreamWriter sw = new StreamWriter(filePath, true))
{
sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.sss") + "\t" + message);
}
}
}
}
}
}
How do you write the log? Have your own open/close or use some thirty party product?
I thing that the log is opened and locked only when it writes something. Once the data writing is finished, the code closes the file and, of course, releases the lock
This seems like a .NET issue. (Well; a Bug if you ask me).
Basically I have replicated the problem by using the following multi-threaded code:
Dim FS As System.IO.FileStream
Dim BR As System.IO.BinaryReader
Dim FileBuffer(-1) As Byte
If System.IO.File.Exists(FileName) Then
Try
FS = New System.IO.FileStream(FileName, System.IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
BR = New System.IO.BinaryReader(FS)
Do While FS.Position < FS.Length
FileBuffer = BR.ReadBytes(&H10000)
If FileBuffer.Length > 0 Then
... do something with the file here...
End If
Loop
BR.Close()
FS.Close()
Catch
ErrorMessage = "Error(" & Err.Number & ") while reading file:" & Err.Description
End Try
Basically, the bug is that trying to READ the file with all different share-modes (READ, WRITE, READ_WRITE) have absolutely no effect on the file locking, no matter what you try; you would always end up in the same result: The is LOCKED and not available for any other user.
Microsoft won't even admit to this problem.
The solution is to use the internal Kernel32 CreateFile APIs to get the proper access done as this would ensure that the OS LISTENs to your request when requesting to read files with a share-locked or locked access.
I believe I'm having the same type of locking issue, reproduced as follows:
User 1 opens Excel2007 file from network (read-write) (WindowsServer, version unkn).
User 2 opens same Excel file (opens as ReadOnly, of course).
User 1 successfully saves file many times
At some point, User 1 is UNABLE to save the file due to message saying "file is locked".
Close down User 2's ReadOnly version...lock is released, and User 1 can now save again.
How could opening the file in ReadOnly mode put a lock on that file?
So, it seems to be either an Excel2007 issue, or a server issue.

Resources