Hi I have a wpf application that plays sounds on events such as button click. And the current code I have now plays the sound file, but Ive realized that it has to be in another folder which for example if the user deletes, makes the application pretty much not useable.
I was wondering, How could I get a .wav file without creating a whole new folder in the application Release directory.
Any ideas?
Thanks.
If the .wav files is added to your project at the root then marked as content (Right Click on the .wav file and click properties. Then change the build action to content) then it will be copied directly to the root output folder
You can the reference the wav file in code or XAML as a relative path (simple "Myfile.wav")
I believe this is what you are asking for?
How about putting the .wav-file as en embedded resource in the dll?
Just add the file to the project, right-click on the file and set Build Action to Embedded Resource.
Then you can load the .wav file as a stream and save it to disc like this:
private void WriteEmbeddedResourceToFile(string writePath, string assemblyName)
{
Assembly asm = Assembly.GetExecutingAssembly();
Stream s = asm.GetManifestResourceStream(assemblyName);
if (s != null)
{
var file = new byte[s.Length];
s.Read(file, 0, (int)s.Length);
File.WriteAllBytes(writePath, file);
s.Close();
}
}
The string assemblyName must be set like this: namespace.(if you put the file in a folder, insert folder subpath here).filename.wav
Alternatively, you can drop saving it to disc, and just use the stream directly:
private byte[] GetEmbeddedResource(string assemblyName)
{
Assembly asm = Assembly.GetExecutingAssembly();
Stream s = asm.GetManifestResourceStream(assemblyName);
if (s != null)
{
var file = new byte[s.Length];
s.Read(file, 0, (int)s.Length);
s.Close();
return file;
}
}
Then, when you want to load the file, GetEmbeddedResource will return the byte array.
Related
In my code I am prompting the user to load a json file.
I am then attempting to copy this file into an sqlite database.
Once I have the data I am then able to manipulate it as needed - but I need to get it there in the first place.
So step 1 is to get the data in.
I have progressed as far as prompting the user to navigate to the file they want - but when I try and read the file I get this error ..
ERROR: resources must reside in the root directory thus must start with a '/' character in Codename One! Invalid resource: file:///tmp/temp3257201851214246357..json
So I think that I need to copy this file to the root directory
I cannot find a link that shows me how to do this.
Here is my code so far ...
case "Import Script":
try
{
JSONParser json = new JSONParser();
if (FileChooser.isAvailable()) {
FileChooser.showOpenDialog(".json", e2-> {
String file = (String)e2.getSource();
if (file == null) {
home.add("No file was selected");
home.revalidate();
} else {
home.add("Please wait - busy importing");
home.revalidate();
String extension = null;
if (file.lastIndexOf(".") > 0) {
extension = file.substring(file.lastIndexOf(".")+1);
}
if ("json".equals(extension)) {
FileSystemStorage fs = FileSystemStorage.getInstance();
try {
InputStream fis = fs.openInputStream(file);
try(Reader r = new InputStreamReader(Display.getInstance().getResourceAsStream(getClass(), file), "UTF-8"))
{
Map<String, Object> data = json.parseJSON(r);
Result result = Result.fromContent(data);
...... I progress from here
The error is occurring on this line ...
try(Reader r = new InputStreamReader(Display.getInstance().getResourceAsStream(getClass(), file), "UTF-8"))
If I hard code a filename and manually place it in the /src folder it works ... like this ...
try(Reader r = new InputStreamReader(Display.getInstance().getResourceAsStream(getClass(), '/test.json'), "UTF-8"))
But that defeats the purpose of them selecting a file
Any help would be appreciated
Thanks
I suggest watching this video.
It explains the different ways data is stored. One of the core sources of confusion is the 3 different ways to store files:
Resources
File System
Storage
getResourceAsStream returns a read only path that's physically embedded in the jar. It's flat so all paths to getResourceAsStream must start with / and must have only one of those. I would suggest avoiding more than one . as well although this should work in theory.
The sqlite database must be stored in file system which is encapsulated as FileSystemStorage and that's really the OS native file system. But you can't store it anywhere you want you need to give the DB name to the system and it notifies you where the file is stored and that's whats explained in the code above.
I am new in android studio and I am using Parse to store images. I am creating an image gallery and I am able to display downloaded images from parse to gridview. The problem is everytime I restart the app, my SDcard will download the exact same files from Parse. Is there a way to delete these unnecessary files? Or how can I put these Downloaded image files into a temporary storage where they will be deleted once the user is finished with the app?
This is my code for downloading the images and store them in gridview:
for (ParseObject imageOb : objects) {
final ParseFile file = (ParseFile) imageOb.get("image");
file.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e == null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Uri uri = getImageUri(getApplicationContext(), bitmap);
File imageFiles = new File(getRealPathFromURI(uri));
imageAdapter.add(imageFiles.toString());
}
imageAdapter.notifyDataSetChanged();
}
});
}
There are some answers already on Stack overflow about temporary files, for example What is the best way to create temporary files
You could also manually delete the downloaded files when the application doesn't need them anymore. If you download them in onCreate you should delete them in onDestroy. Otherwise, check out this Article about the Android lifecycle
In my WPF app, I am creating a FlowDocument by building its XAML markup as a string, and then using XamlReader.Parse to turn the string into a FlowDocument object, which I then save to an XPS document file. It works.
I needed to include an image in my document, and so to achieve this, I create and save the image as a temporary file in the temp directory, and then reference it with an absolute path in my FlowDocument's XAML. This works too - during the XPS document creation process, the image actually gets embedded into the XPS document, which is great.
But the problem is, my app retains a file lock on this image until the app quits.
I am cleaning up all resources. There is NO file lock on my generated XPS file - just the image file. If I comment out the part of my code which creates the XPS file, then the image file does not get locked.
My code (I'm on .NET 4 CP):
var xamlBuilder = new StringBuilder();
// many lines of code like this
xamlBuilder.Append(...);
// create and save image file
// THE IMAGE AT THE PATH imageFilePath IS GETTING LOCKED
// AFTER CREATING THE XPS FILE
var fileName = string.Concat(Guid.NewGuid().ToString(), ".png");
var imageFilePath = string.Format("{0}{1}", Path.GetTempPath(), fileName);
using (var stream = new FileStream(imageFilePath, FileMode.Create)) {
var encoder = new PngBitmapEncoder();
using (var ms = new MemoryStream(myBinaryImageData)) {
encoder.Frames.Add(BitmapFrame.Create(ms));
encoder.Save(stream);
}
stream.Close();
}
// add the image to the document by absolute path
xamlBuilder.AppendFormat("<Paragraph><Image Source=\"{0}\" ...", imageFilePath);
// more lines like this
xamlBuilder.Append(...);
// create a FlowDocument from the built string
var document = (FlowDocument) XamlReader.Parse(xamlBuilder.ToString());
// set document settings
document.PageWidth = ...;
...
// save to XPS file
// THE XPS FILE IS NOT LOCKED. IF I LEAVE OUT THIS CODE
// AND DO NOT CREATE THE XPS FILE, THEN THE IMAGE IS NOT LOCKED AT ALL
using (var xpsDocument = new XpsDocument(filePath, FileAccess.ReadWrite)) {
var documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
documentWriter.Write(((IDocumentPaginatorSource) document).DocumentPaginator);
xpsDocument.Close();
}
(Actually, the fact that's it's a dynamically generated image in the temp directory is irrelevant - this issue occurs if I hard code in the path of any image file on my machine - it will get locked.)
One would think that there is a bug in the XPS creation code that causes the file lock.
Is there something else I can try? Or a way to remove the file lock via code?
You could change your xaml like this instead:
<Image>
<Image.Source>
<BitmapImage CacheOption="None" UriSource="your path" />
</Image.Source>
</Image>
to be able to play with the CacheOption parameter, to specify how the Xaml Builder should load the image file, as the default value seems to be keeping a lock on it (waiting for the GC to do its work it seems).
Here is some related question here on SO: How do you make sure WPF releases large BitmapSource from Memory?
I have the following requirement for a business application:
(All of this could be on local or server)
Allow user to select folder location
Show contents of folder
Print selected items from folder (*.pdf)
Display which files have been printed
Potentially move printed files to new location (sub-folder of printed)
How can I make this happen in Silverlight?
Kind regards,
ribald
First of all, all but the last item can be done (the way you expect). Due to security protocols, silverlight cannot access the user's drive and manipulate it. The closest you can get is accessing silverlight's application storage which will be of no help to you whatsoever in this case. I will highlight how to do the first 4 items.
Allow user to select folder location & Show contents of folder
public void OnSelectPDF(object sender)
{
//create the open file dialog
OpenFileDialog ofg = new OpenFileDialog();
//filter to show only pdf files
ofg.Filter = "PDF Files|*.pdf";
ofg.ShowDialog();
byte[] _import_file = new byte[0];
//once a file is selected proceed
if (!object.ReferenceEquals(ofg.File, null))
{
try
{
fs = ofg.File.OpenRead();
_import_file = new byte[fs.Length];
fs.Read(_import_file, 0, (int)fs.Length);
}
catch (Exception ex)
{
}
finally
{
if (!object.ReferenceEquals(fs, null))
fs.Close();
}
//do stuff with file - such as upload the file to the server
};
}
If you noticed, in my example, once the file is retrieved, i suggest uploading it to a webserver or somewhere with temporary public access. I would recommend doing this via a web service. E.g
//configure the system file (customn class)
TSystemFile objFile = new TNetworkFile().Initialize();
//get the file description from the Open File Dialog (ofg)
objFile.Description = ofg.File.Extension.Contains(".") ? ofg.File.Extension : "." + ofg.File.Extension;
objFile.FileData = _import_file;
objFile.FileName = ofg.File.Name;
//upload the file
MasterService.ToolingInterface.UploadTemporaryFileAsync(objFile);
Once this file is uploaded, on the async result, most likely returning the temporary file name and upload location, I would foward the call to some javascript method in the browser for it to use the generic "download.aspx?fileName=givenFileName" technique to force a download on the users system which would take care of both saving to a new location and printing. Which is what your are seeking.
Example of the javascript technique (remember to include System.Windows.Browser):
public void OnInvokeDownload(string _destination)
{
//call the browser method/jquery method
//(I use constants to centralize the names of the respective browser methods)
try
{
HtmlWindow window = HtmlPage.Window;
//where BM_INVOKE_DOWNLOAD is something like "invokeDownload"
window.Invoke(Constants.TBrowserMethods.BM_INVOKE_DOWNLOAD, new object[] { _destination});
}
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
}
Ensure you have the javascript method existing either in an included javaScript file or in the same hosting page as your silverlight app. E.g:
function invokeDownload(_destination) {
//some fancy jquery or just the traditional document.location change here
//open a popup window to http://www.myurl.com/downloads/download.aspx? fileName=_destination
}
The code for download.aspx is outside the scope of my answer, as it varies per need and would just lengthen this post (A LOT MORE). But from what I've given, it will "work" for what you're looking for, but maybe not in exactly the way you expected. However, remember that this is primarily due to silverlight restrictions. What this approach does is rather than forcing you to need a pluging to view pdf files in your app, it allows the user computer to play it's part by using the existing adobe pdf reader. In silverlight, most printing, at least to my knowledge is done my using what you call and "ImageVisual" which is a UIElement. To print a pdf directly from silverlight, you need to either be viewing that PDF in a silverlight control, or ask a web service to render the PDF as an image and then place that image in a control. Only then could you print directly. I presented this approach as a lot more clean and direct approach.
One note - with the temp directory, i would recommend doing a clean up by some timespan of the files on the server side everytime a file is being added. Saves you the work of running some task periodically to check the folder and remove old files. ;)
I'm trying to read & modify an XML file present in the Silverlight project from a view's code behind.
This is how I've read & modified the XML file:
StreamResourceInfo s = Application.GetResourceStream(new Uri("XML/Settings.xml", UriKind.Relative));
XElement doc = XElement.Load(s.Stream, LoadOptions.None);
IEnumerable<XElement> settingElement = (from b in doc.Descendants(
"setting")
select b).Take(1);
if (settingElement.Count<XElement>() > 0)
{
foreach (var node in newsIdNode)
{
node.Remove();
}
}
What I want to do now, is to save the XML file. I tried the following:
doc.Save(s.Stream, SaveOptions.None);
But got a runtime error that the stream is not writable.
How can I save changes to this XML file?
You can't- the stream is only for reading. If you want to save something consider isolated storage, saving to a file or persisting state via Web services.