Define download path dotnetbrowser - download

I use dotnetbrowser to display a web browser on a old windows framework.
have you an idea to define the download path ?
My dotnetbroser is enable, i can show my webpage but i don't found in documentation or exemple how define this simple download path.
The only exemple that i've found is about the download event detection.
I use WPF in C#
Thanks.

The DotNetBrowser.DownloadItem.DestinationFile property is writable and can be used to configure the path to store the file.
To set this property in your application, you need to subclass the DotNetBrowser.DefaultDownloadHandler and implement its AllowDownload(DownloadItem) method. Then you need to configure your download handler as shown in the documentation article: File Download
You can also configure and use DotNetBrowser.WPF.WPFDefaultDownloadHandler instance to show file chooser and select the path to store the file.

This is a solution
Défine your browser like variable :
BrowserView myBrowserView;
Browser myBrowser;
Create the browser properly :
this.myBrowser = BrowserFactory.Create();
this.myBrowserView = new WPFBrowserView(this.myBrowser);
Create event detection for download
this.myDowloadHandler = new SampleDownloadHandler();
this.myBrowser.DownloadHandler = myDowloadHandler;
Add it to a container, here, a grid
grid_navigateur.Children.Add((UIElement)myBrowserView.GetComponent());
Now we are going to use our "SampleDownloadHandler" class
class SampleDownloadHandler : DownloadHandler
{
public bool AllowDownload(DownloadItem download)
{
download.DestinationFile = "exemple\of\path\whith\file\name";
download.DownloadEvent += delegate(object sender, DownloadEventArgs e)
{
DownloadItem downloadItem = e.Item;
if (downloadItem.Completed)
{
System.Windows.MessageBox.Show("Download complete");
}
};
return true;
}
My personalisated class define path and name of the file who is download and pop a message when is over.
(to found the file name, you do to cut the string download.DestinationFile after the last )

Related

Download with file name defaulting to date-time of user event in Vaadin Flow app

In my Vaadin Flow web app (version 14 or later), I want to present to my user a link that will download a data file to them. The default name of the file to be downloaded should be determined at the moment the user initiates the download.
I am aware of the Anchor widget in Vaadin Flow. With an Anchor, the default name for the downloaded file will be the resource name given in the URL of the link. Unfortunately, that is determined when the page loads rather than later when the user clicks the link. So this approach fails to meet my need to label the download with the date-time captured at the moment the user initiates the download.
String when = Instant.now().toString().replace( "-" , "" ).replace( ":" , "" ); // Use "basic" version of standard ISO 8601 format for date-time.
StreamResource streamResource = new StreamResource( "rows_" + when + ".txt" , ( ) -> this.makeContent() );
Anchor anchor = new Anchor( streamResource , "Download generated data" );
Perhaps the solution would be the use of a Button widget rather than an Anchor. Using a button for dynamically-created content is shown in the manual in the Advanced Topics > Dynamic Content page. Unfortunately, the example there loads a resource on the page rather than doing a download for the user.
➥ Can a Button in Vaadin Flow be used to initiate a download?
➥ Is there some other approach to initiating a download with a URL determined when the user initiates the download rather than when the page loads?
Can a Button in Vaadin Flow be used to initiate a download?
Sort of yes, but it requires some client side implementation. There is File Download Wrapper add-on in Directory, which does this. With it is possible to wrap e.g. Button. However I think it will not solve problem of yours fully. I suspect that the setting the filename in click event wont apply (it comes too late). But I do think, that it would be possible to add filename provider callback feature to this add-on.
Consider this HACK that simulates a click on a dynamically added Anchor on client-side:
private void downloadWorkaround(Component anyComponent, int delay) {
Anchor hiddenDownloadLink = new Anchor(createStreamResource(), "Workaround");
hiddenDownloadLink.setId("ExportLinkWorkaround_" + System.currentTimeMillis());
hiddenDownloadLink.getElement().setAttribute("style", "display: none");
var parent = anyComponent.getParent().orElseThrow();
var parenthc = (HasComponents) parent;
for (Component c : parent.getChildren().collect(Collectors.toList())) {
if (c.getId().orElse("").startsWith("ExportLinkWorkaround_")) {
// clean up old download link
parenthc.remove(c);
}
}
parenthc.add(hiddenDownloadLink);
UI.getCurrent().getPage().executeJs("setTimeout(function(){" + // delay as workaround for bug when dialog open before
"document.getElementById('" + hiddenDownloadLink.getId().orElseThrow() + "').click();"
+ "}, " + delay + ");"
);
}
Call the method on button click event or something. The additional delay is required sometimes. For me the delay was necessary to start the download from a modal dialog OK button that also closed the dialog. But perhaps you don't even need that.
I had no luck with the file download wrapper add-on mentioned by Tatu for my specific use case: I wanted to show a dialog under some circumstances before providing the download to user.
Based on the question of Clearing up Vaadin StreamResource after file download (which is partly the same as the answer of Steffen Harbich here in this question) I came to this solution (Vaadin 23):
Just provide a normal button with a normal clickHandler.
In the clickHandler you determine the file name, create a local StreamResource, add it to an invisible UI element and trigger a click event on this element.
Clickhandler:
private void doOnDownloadBtnClicked( Event e )
{
String filename = createFileName(); // implementation left to you
downloadFile( filename, this::inputStreamProvider );
}
InputStream provider:
private InputStream inputStreamProvider()
{
....
}
File download (may be extracted to an Utility class):
private final StreamResourceRegistry myStreamResourceRegistry;
private void downloadFile( String aFileName, InputStreamFactory aInputStreamFactory )
{
myStreamResourceRegistry = new StreamResourceRegistry(VaadinSession.getCurrent());
var executor = new DownloadExecutor( aInputStreamFactory );
var sr = new StreamResource( aFileName, executor );
StreamRegistration reg = myStreamResourceRegistry.registerResource( sr );
executor.myRegistration = reg;
var hiddenDownloadLink = new Anchor(sr, "Hidden");
var hiddenDownloadLinkId =
StringUtils.replaceChars( "DownloadLinkWorkaroundId-" + new SecureRandom().nextLong(),
'-',
'_' ) ;
hiddenDownloadLink.setId( hiddenDownloadLinkId);
var hiddenElement = hiddenDownloadLink.getElement();
executor.myHiddenElement = hiddenElement;
hiddenElement.setAttribute("style", "display: none");
var uiParent = UI.getCurrent().getElement();
executor.myParentElement = uiParent;
uiParent.appendChild(hiddenElement);
LOG.debug( "Going to simulate click event" );
UI.getCurrent().getPage().executeJs("$0.click();", hiddenElement );
}
/**
* Wrapper for the given InputStreamFactory.
* <p>
* It is needed to let Vaadin first give a chance to call the InputStream provider, before the
* temporary added hidden anchor is removed and the StreamRegistration is unregistered.
*/
private static final class DownloadExecutor implements InputStreamFactory
{
private InputStreamFactory myInputStreamFactory;
private StreamRegistration myRegistration;
private Element myHiddenElement;
private Element myParentElement;
private DownloadExecutor( InputStreamFactory aInputStreamFactory )
{
super();
myInputStreamFactory = aInputStreamFactory;
}
#Override
public InputStream createInputStream()
{
var result = myInputStreamFactory.createInputStream();
myParentElement.removeChild( myHiddenElement );
myRegistration.unregister();
return result;
}
}
Note: If the above fileDownload is extracted to an own helper class (e.g. a spring bean with #SessionScope), the initialization of myStreamResourceRegistry should be done in the constructor of the bean.

How to select a file in finder in Xamarin?

I am trying to select a file in the Finder, that is not happening the method works well in Obj-C but in Xamarin Finder gets activated but the file is not getting selected.
Whereas if I use Xamarin command to open the file it opens.
Here is the snippet of code that I wrote. Guide me if I am doing something wrong or missing anything?
public override void DidFinishLaunching(NSNotification notification)
{
string fullPath = "/Users/anoopvaidya/Desktop/A/ClientInfoConfig.cs";
NSUrl url = NSUrl.FromString(fullPath);
NSUrl[] urls = { url };
NSWorkspace.SharedWorkspace.OpenFile(fullPath);
//works. But I only want to select in Finder
NSWorkspace.SharedWorkspace.ActivateFileViewer(urls);
//doesn't work
}
Is it related to OS version? I am using 10.13.6.
You need to use a file:// based url:
Example:
using (var url = new NSUrl("file", "localhost", "/Users/Sushi/Desktop/StackOverflow.png"))
{
NSWorkspace.SharedWorkspace.ActivateFileViewer(new NSUrl[] { url });
}

How to force download Sitecore media items (images)?

I need to have force download action after clicking on Sitecore media link. I didn't find any useful Sitecore advance how to achieve that.
In Sitecore configuration you can define which mime types will be force downloaded. But problem is, if you want to do it for images. Because if you do this
<mediaType name="JPEG image" extensions="jpg, jpeg, jpe">
<mimeType>image/jpeg</mimeType>
<forceDownload>true</forceDownload>
</mediaType>
all images will disappear because of browser won't be able to present them in HTML!
How to make all Sitecore media files force downloaded on click?
After some investigation in Sitecore's code with decompiler I decide that the best way is to extend Sitecore MediaRequestHandler.
But how to recognize if I want to present an image and download an image? We have to add query string parameter to URL, something like "dl=1"
public class MediaRequestHandler : Sitecore.Resources.Media.MediaRequestHandler, System.Web.SessionState.IRequiresSessionState
{
protected override bool DoProcessRequest(HttpContext context, MediaRequest request, Media media)
{
// identify query string param from requested URL
bool isDownload = Utils.UrlUtils.HasQueryParam(context.Request.Url, "dl", "1");
if (isDownload)
{
using (MediaStream stream = media.GetStream())
{
// we have to check if file is not already force downloaded by Sitecore
if (!stream.ForceDownload)
{
string mediaName = media.MediaData.MediaItem.Name + "." + media.MediaData.Extension;
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + mediaName + "\"");
}
context.Response.AddHeader("Content-Length", stream.Length.ToString());
}
}
// it must be called after all logic
return base.DoProcessRequest(context, request, media);
}
}
Some remarks for the code:
all logic must be before calling original DoProcessRequest method because after processing it will flush all headers to response (!)
there must be query string parameter which decide if to force download file or not
some mime types already have "forcedownload" attribute from configuration so you have to check it to avoid duplicate header "Content-Disposition" (this cause problem in Chrome, downloaded file will have extension something like "filename-, attachment")

NotifyFilter of FileSystemWatcher not working

I have a windows service (and verified the code by creating a similar WinForms application) where the NotifyFilter doesn't work. As soon as I remove that line of code, the service works fine and I can see the event-handler fire in the WinForms application.
All I'm doing is dropping a text file into the input directory for the FileSystemWatcher to kick off the watcher_FileChanged delegate. When I have the _watcher.NotifyFilter = NotifyFilters.CreationTime; in there, it doesn't work. When I pull it out, it works fine.
Can anyone tell me if I'm doing something wrong with this filter?
Here is the FSW code for the OnStart event.
protected override void OnStart(string[] args)
{
_watcher = new FileSystemWatcher(#"C:\Projects\Data\Test1");
_watcher.Created += new FileSystemEventHandler(watcher_FileChanged);
_watcher.NotifyFilter = NotifyFilters.CreationTime;
_watcher.IncludeSubdirectories = false;
_watcher.EnableRaisingEvents = true;
_watcher.Error += new ErrorEventHandler(OnError);
}
private void watcher_FileChanged(object sender, FileSystemEventArgs e)
{
// Folder with new files - one or more files
string folder = #"C:\Projects\Data\Test1";
System.Console.WriteLine(#"C:\Projects\Data\Test1");
//Console.ReadKey(true);
// Folder to delete old files - one or more files
string output = #"C:\Temp\Test1\";
System.Console.WriteLine(#"C:\Temp\Test1\");
//Console.ReadKey(true);
// Create name to call new zip file by date
string outputFilename = Path.Combine(output, string.Format("Archive{0}.zip", DateTime.Now.ToString("MMddyyyy")));
System.Console.WriteLine(outputFilename);
//Console.ReadKey(true);
// Save new files into a zip file
using (ZipFile zip = new ZipFile())
{
// Add all files in directory
foreach (var file in Directory.GetFiles(folder))
{
zip.AddFile(file);
}
// Save to output filename
zip.Save(outputFilename);
}
DirectoryInfo source = new DirectoryInfo(output);
// Get info of each file into the output directory to see whether or not to delete
foreach (FileInfo fi in source.GetFiles())
{
if (fi.CreationTime < DateTime.Now.AddDays(-1))
fi.Delete();
}
}
I've been having trouble with this behavior too. If you step through the code (and if you look at MSDN documenation, you'll find that NotifyFilter starts off with a default value of:
NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite
So when you say .NotifyFilter = NotifyFilters.CreationTime, you're wiping out those other values, which explains the difference in behavior. I'm not sure why NotifyFilters.CreationTime is not catching the new file... seems like it should, shouldn't it!
You can probably just use the default value for NotifyFilter if it's working for you. If you want to add NotifyFilters.CreationTime, I'd recommend doing something like this to add the new value and not replace the existing ones:
_watcher.NotifyFilter = _watcher.NotifyFilter | NotifyFilters.CreationTime;
I know this is an old post but File Creation time is not always reliable. I came across a problem where a Log file was being moved to an archive folder and a new file of the same name was created in it's place however the file creation date did not change, in fact the meta data was retained from the previous file (the one that was moved to the archive) .
Windows has this cache on certain attributes of a file, file creation date is included. You can read the article on here: https://support.microsoft.com/en-us/kb/172190.

resource listing

I writing wicket webapp. I want to:
list all resources - videoPreview in the folder
preview it
add link to show in main preview panel.
I read a lot and look examples about resources, but seems like can't understand smthg. I write such funny code:
RepeatingView rv = new RepeatingView("showVideo");
add(rv);
File vidPrevDir = (new File("data/catalog/"+product+"/videoPreview"));
File[] list = vidPrevDir.listFiles();
for (File file : list) {
final String previewFile = file.getName();
AjaxLink link = new AjaxLink(rv.newChildId()){
#Override
public void onClick(AjaxRequestTarget target) {
container.name="iframe";
container.attrs.clear();
container.attrs.put("class", "viewPanel");
container.attrs.put("allowfullscreen", "yes");
container.attrs.put("src", "http://www.youtube.com/embed/"+previewFile.substring(previewFile.indexOf("___"), previewFile.length()-4));
target.add(container);
}
};
rv.add(link);
link.add(new Image("videoPreview", product+"/videoPreview/"+file.getName()));
}
In application i call
getResourceSettings().addResourceFolder("data");
It's work, but i feel bad when i see that. So my question is how to make such things in wicket? Maybe there is resource listing or java.io.File->wicket.Image converter ?
I only found built-in method:
ServletContext context = WicketApplication.get().getServletContext();
Set productList = context.getResourcePaths("/catalog");
It list filenames, not resources, but it is preferable approach, then i use in question.

Resources