Debugging WP8 Native Code using a file - windows-phone-8

I'm developing a WP8 app that has some native code (runtime component).
Inside the runtime component I need to check to content of a c style array.
Because this array is not small, I thought the best I could do is write the array in a file
using fopen/fwrite/fclose;
Checking the returned value from fopen and fwrite, I can see that it succeeded.
But I cannot find the file (using Windows Phone Power Tools).
So where has the file been written?
Is there another way to dump the content of the array to a file (on the computer) from visual studio ?

I'm unfamiliar with the fopen/fwrite/fclose APIs in WP8. Which probably means it's not a whitelisted API you can use to submit your app with. It's best if you just use "Windows::Storage::ApplicationData::Current->LocalFolder" when working with IsoStore in C++. See Win8 code sample # http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh700361.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1

Thanks Justin,
here's how I ended up doing it:
auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
Concurrency::task<Windows::Storage::StorageFile^> createFileOp(
folder->CreateFileAsync(L"Data.bin", Windows::Storage::CreationCollisionOption::ReplaceExisting));
createFileOp.then(
[nData, pData](Windows::Storage::StorageFile^ file)
{
return file->OpenAsync(Windows::Storage::FileAccessMode::ReadWrite);
})
.then([nData, pData](Windows::Storage::Streams::IRandomAccessStream^ stream)
{
auto buffer = ref new Platform::Array<BYTE>(pData, nData);
auto outputStream = stream->GetOutputStreamAt(0);
auto dataWriter = ref new Windows::Storage::Streams::DataWriter(outputStream);
dataWriter->WriteBytes(buffer);
return dataWriter->StoreAsync();
})
.wait();
Now compare that to what I "meant" :
FILE *fp = fopen("Data.bin", "wb");
if (fp)
{
int ret = fwrite(pData, 1, nData, fp);
fclose(fp);
}

Related

Embarcadero C++ : How to notify user if new update is available?

I am beginner in Embarcadero C++, If my application is developed in Embarcadero C++ and installed in client machine then how my application notify user if new update is available? If user clicked on yes button then it will first download the application then install it.
Please let me know if anybody have any Idea.
Here is how I check if new version of program is available on the server, using
Indy Client component TIdHTTP.
Let's say you have uploaded a new version of your application. Besides installation or zip file containing you application, upload a one line text file (applicationBuildData.txt) which contains build value (integer), delimiter (;) and optionally some other data (version number, program name, etc...). For example:
20170215; ProgamName rel. 1.2.
This is the only line in applicationBuildData.txt file. Here is the code sample (I've modified my original code a bit):
void __fastcall TfrmDialog::Button1Click(TObject *Sender)
{
TIdHTTP *IdHTTP1 = new TIdHTTP(this);
// let's say this is current app build (on user's side)
int currAppBuild = 20170101;
int prodBuildNew = 0;
UnicodeString prodVersionNew;
UnicodeString version_str;
try {
// get content of applicationBuildData.txt into string
version_str = IdHTTP1->Get("http://www.your-site.com/applicationBuildData.txt");
prodBuildNew = StrToInt(version_str.SubString(1, version_str.Pos(";") - 1).Trim());
prodVersionNew = version_str.SubString(version_str.Pos(";") + 1, 100).Trim();
}
catch (...)
{
prodBuildNew = 0;
prodVersionNew = "???";
}
if (prodBuildNew == 0) {
// ...faild to get data from server...
// display message
}
else if (prodBuildNew > currAppBuild) {
// new version is available
// display message
}
else {
// application version is up to date
// display message
}
delete IdHTTP1;
}
In this example, current build number is smaller then uploaded build number and it will indicate user that new version is available.
Note: currAppBuild is usually some global constant, or global variable that presents build version. After new version on the server is detected, you can either download installation/zip or simply display message and let the user go to your site and download new version manually.
Edit: How to download the file to your local disk using TIdHTTP component, check the following video:
https://www.youtube.com/watch?v=fcN8K3R4iZE

Windows Phone 8 choose text file C#

i have a question. If there is a possibility at windows phone 8 at visual studio to create button event to read text file? i know about streamReader and if i declare wchich exacly file i want to read, but if i want to choose from list of files wchich i want to display. i did research on the Internet but i didint find an answer. I know i can use isolatedStorage to read music, video, image but not text files, on the app i created few files with text in it and i want users to have posibility to display one from this file, whichever they want to see. So, can you tell me how to do this?
You can use IsolatedStorage to read any file type you wish. You must of been using something like a Launcher that filters out the file type based on the Chooser.
You can open a file like this:
private async Task<string> ReadTextFile(string file_name)
{
// return buffer
string file_content = "";
// Get the local folder
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
// Get the file
StorageFile file;
try
{
file = await local.GetFileAsync(file_name);
}
catch (Exception ex)
{
// no file, return empty
return file_content;
}
// Get the stream
System.IO.Stream file_stream = await file.OpenStreamForReadAsync();
// Read the data
using (StreamReader streamReader = new StreamReader(file_stream))
{
file_content = streamReader.ReadToEnd(); // read the full text file
streamReader.Close();
}
// Close the stream
file_stream.Close();
}
// return
return file_content;
}
If you want to get the PackageLocation (files that you added into the project like assets and images) then replace the LocalFolder with
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
With Windows Phone 8.1, File Pickers are allowed, consisting the same functionality you are expecting, so probably you might want to upgrade your app to WP8.1.
Here's more info on this API : Working with File Pickers

windows 8 app FileOpenPicker np file info

I'm trying to get some file information about a file the user select with the FileOpenPicker, but all the information like the path and name are empty. When I try to view the object in a breakpoint I got the following message:
file = 0x03489cd4 <Information not available, no symbols loaded for shell32.dll>
I use the following code for calling the FileOpenPicker and handeling the file
#include "pch.h"
#include "LocalFilePicker.h"
using namespace concurrency;
using namespace Platform;
using namespace Windows::Storage;
using namespace Windows::Storage::Pickers;
const int LocalFilePicker::AUDIO = 0;
const int LocalFilePicker::VIDEO = 1;
const int LocalFilePicker::IMAGES = 2;
LocalFilePicker::LocalFilePicker()
{
_init();
}
void LocalFilePicker::_init()
{
_openPicker = ref new FileOpenPicker();
_openPicker->ViewMode = PickerViewMode::Thumbnail;
}
void LocalFilePicker::askFile(int categorie)
{
switch (categorie)
{
case 0:
break;
case 1:
_openPicker->SuggestedStartLocation = PickerLocationId::VideosLibrary;
_openPicker->FileTypeFilter->Append(".mp4");
break;
case 2:
break;
default:
break;
}
create_task(_openPicker->PickSingleFileAsync()).then([this](StorageFile^ file)
{
if (file)
{
int n = 0;
wchar_t buf[1024];
_snwprintf_s(buf, 1024, _TRUNCATE, L"Test: '%s'\n", file->Path);
OutputDebugString(buf);
}
else
{
OutputDebugString(L"canceled");
}
});
}
Can anybody see whats wrong with the code or some problems with settings for the app why it isn't work as expected.
First an explanation why you are having trouble debugging, this is going to happen a lot more when you write WinRT programs. First, do make sure that you have the correct debugging engine enabled. Tools + Options, Debugging, General. Ensure that the "Use Managed Compatibility Mode" is turned off.
You can now inspect the "file" option, it should resemble this:
Hard to interpret of course. What you are looking at is a proxy. It is a COM term, a wrapper for COM objects that are not thread-safe or live in another process or machine. The proxy implementation lives in shell32.dll, thus the confuzzling diagnostic message. You can't see the actual object at all, accessing its properties requires calling proxy methods. Something that the debugger is not capable of doing, a proxy marshals the call from one thread to another, that other thread is frozen while the debugger break is active.
That makes you pretty blind, in tough cases you may want to write a littler helper code to store the property in a local variable. Like:
auto path = file->Path;
No trouble inspecting or watching that one. You should now have confidence that there's nothing wrong with file and you get a perfectly good path. Note how writing const wchar_t* path = file->Path; gets you a loud complaint from the compiler.
Which helps you find the bug, you can't pass a Platform::String to a printf() style function. Just like you can't with, say, std::wstring. You need to use an accessor function to convert it. Fix:
_snwprintf_s(buf, 1024, _TRUNCATE,
L"Test: '%s'\n",
file->Path->Data());

Windows phone 8 download then unzip to isolated storage

I'm writing a windows phone 8 application that have following functions
Download a zip file from the internet
Extract it to the isolated storage
I'm looking for a solution to deal with it but haven't found once. If you have any suggestion please help.
Thanks in advance!
EDIT:
I break it down into several steps:
Check if storage is available - DONE
Check if file is compressed - DONE
Use Background Transfer (or another method) to download to local folder and display information to user (percentage, ect.) - NOT YET
Unzip file to desired location in isolated storage - NOT YET
Do stuffs after that... - DONE
For step 4, I found and modified some script to extract file to isolated storage (using SharpGIS.UnZipper lib):
public async void UnzipAndSaveFiles(Stream stream, string name)
{
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var zipStream = new UnZipper(stream))
{
foreach (string file in zipStream.FileNamesInZip)
{
string fileName = Path.GetFileName(file);
if (!string.IsNullOrEmpty(fileName))
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
folder = await folder.CreateFolderAsync("html", CreationCollisionOption.OpenIfExists);
StorageFile file1 = await folder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);
//save file entry to storage
using (var writer = new StreamWriter(await file1.OpenStreamForWriteAsync()))
{
writer.Write(file);
}
}
}
}
}
}
This code is untested (since I haven't downloaded any file).
Can anyone point out any thing that should be corrected (enhanced)?
Can anyone help me to modify it to extract password-protected file (Obviously I have the key)?

Is there a way generate a shortcut file with adobe air?

Good afternoon,
I would like create a application that can can create folders and short cuts to folders in the file system. The user will click a button and it will put a folder on there desktop that has short cuts to files like //server/folder1/folder2 Can you create a desktop shortcut with code in adobe air? How would you do that? How do you create a folder? I keep thinking this should be easy but i keep missing it.
Thank you for your help sorry for the trouble,
Justin
If your deployment profile is Extended Desktop, you may be able to use NativeProcess and some simple scripts that you could package with your app. This approach would entail handling the functionality on a per OS basis, which would take some work and extensive testing. However, I wanted to at least share a scenario that I verified does work. Below is a test case that I threw together:
Test Case: Windows 7
Even though the Adobe documentation says that it prevents execution of .bat files, apparently it doesn't prevent one from executing the Windows Scripting Host: wscript.exe. This means you can execute any JScript or VBScript files. And this is what you would use to write a command to create a shortcut in Windows (since Windows doesn't have a commandline command to create shortcuts otherwise).
Here's a simple script to create a shortcut command, which I found on giannistsakiris.com, (converted to JScript):
// File: mkshortcut.js
var WshShell = new ActiveXObject("WScript.Shell");
var oShellLink = WshShell.CreateShortcut(WScript.Arguments.Named("shortcut") + ".lnk");
oShellLink.TargetPath = WScript.Arguments.Named("target");
oShellLink.WindowStyle = 1;
oShellLink.Save();
If you package this in your application in a folder named utils, you could write a function to create a shortcut like so:
public function createShortcut(target:File, shortcut:File):void {
if (NativeProcess.isSupported) { // Note: this is only true under extendedDesktop profile
var shortcutInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
// Location of the Windows Scripting Host executable
shortcutInfo.executable = new File("C:/Windows/System32/wscript.exe");
// Argument 1: script to execute
shortcutInfo.arguments.push( File.applicationDirectory.resolvePath("utils/mkshortcut.js").nativePath);
// Argument 2: target
shortcutInfo.arguments.push("/target:" + target.nativePath);
// Argument 3: shortcut
shortcutInfo.arguments.push("/shortcut:" + shortcut.nativePath);
var mkShortcutProcess = new NativeProcess();
mkShortcutProcess.start(shortcutInfo);
}
}
If one wanted to create a shortcut to the Application Storage Directory on the Desktop, the following would suffice:
var targetLocation:File = File.applicationStorageDirectory;
var shortcutLocation:File = File.desktopDirectory.resolvePath("Shortcut to My AIR App Storage");
createShortcut(targetLocation, shortcutLocation);
Obviously there's a lot of work to be done to handle different OS environments, but this is at least a step.
As far as I know, File class does not allow the creation of symbolic links. But you can create directories with createDirectory(): http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filesystem/File.html#createDirectory%28%29
Check if this can be useful: http://www.mikechambers.com/blog/2008/01/17/commandproxy-net-air-integration-proof-of-concept/
Air doesnt let you create shortcuts natively. Here's a workaround that works with Windows [may work on Mac but I don't have a machine to test].
Using Air, create a file that contains the following plain text
[InternetShortcut]
URL=C:\path-to-folder-or-file
Replace path-to-folder-or-file with your folder/file name
Save the file as test.url
Windows recognizes this file as a shortcut.
It is possible to coerce Adobe Air into creating symbolic links, other useful things, on a Mac. Here's how I did it:
You will need AIRAliases.js - Revision: 2.5
In the application.xml add:
<!-- Enables NativeProcess -->
<supportedProfiles>extendedDesktop desktop</supportedProfiles>
In the Air app JavaScript:
// A familiar console logger
var console = {
'log' : function(msg){air.Introspector.Console.log(msg)}
};
if (air.NativeProcess.isSupported) {
var cmdFile = air.File.documentsDirectory.resolvePath("/bin/ln");
if (cmdFile.exists) {
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
var processArgs = new air.Vector["<String>"]();
nativeProcessStartupInfo.executable = cmdFile;
processArgs.push("-s");
processArgs.push("< source file path >");
processArgs.push("< link file path >");
nativeProcessStartupInfo.arguments = processArgs;
nativeProcess = new air.NativeProcess();
nativeProcess.addEventListener(air.NativeProcessExitEvent.EXIT, onProcessExit);
nativeProcess.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, onProcessOutput);
nativeProcess.addEventListener(air.ProgressEvent.STANDARD_ERROR_DATA, onProcessError);
nativeProcess.start(nativeProcessStartupInfo);
} else {
console.log("Can't find cmdFile");
}
} else {
console.log("Not Supported");
}
function onProcessExit(event) {
var result = event.exitCode;
console.log("Exit Code: "+result);
};
function onProcessOutput() {
console.log("Output: "+nativeProcess.standardOutput.readUTFBytes(nativeProcess.standardOutput.bytesAvailable));
};
function onProcessError() {
console.log("Error: "+nativeProcess.standardError.readUTFBytes(nativeProcess.standardError.bytesAvailable));
};
Altering the syntax of the command and parameters passed to NativeProcess you should be able to get real shortcuts on Windows too.