Blog Moved!
My blog was moved to:
Thank you!
Windows Phone7 Live SDK Preview Sample
Some days ago, I found an interessting sample about how to manage files with the new Live SDK Developer Preview. I have read many postings on MSDN and I found out, that WP7 developers are really keen on a example, on how to upload and download files from SkyDrive, using WP7. I used the SkyPad sample from MSDN and ported parts of it to WP7.
The main concept and most of the source where taken from the SkyPad sample for Windows Developer Preview and ported tonight to WP7.
Bevore you can use the example, you have to register for an ClientID at the Windows Live Application Management Site. You need this ClientID, to be able to access the Windows Live Services from your applications, not only for mobile devices.
Please download also the Windows Live SDK Developer Preview from Microsoft Connect
Register For a ClientID
Visit the Windows Live Application Mangment Site
Please visit the Windows Live Application Managment Site (be sure to own a Live-Account bevore doing this), and log in:
Create An Application
After successfully logging in – please click on the right side “Create Application”:
Set The Name For Your Application
Set the name and choose the language for your application:
Go To The Application Settings Page
After setting the name, you need to adjust additional API settings for your application. Please click on Application Settings Page. Please copy also the Client ID, you need it later:
Choose The API Settings
On the current screen, click API Settings on the left:
Set The Mobile Client App Flag
To be able to use the WP7 app you need to select yes in the Mobile client app section:
After this torture copy your Client ID (if you have not done it before) and open the project in Visual Studio 2010 or Expression Blend.
Set The Client ID In The Source
Open the file Main.xaml and insert the Client ID:
Now compile the source and run the application.
Here are some screenshots and the main source code snippet:
And here the most important part of the source code, as well as the dowload of the whole project.
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Windows.Navigation; using System.Collections.ObjectModel; using System.IO; using System.Text; using System.Windows.Interop; using System.Windows.Media.Imaging; using Microsoft.Live; using Microsoft.Live.Controls; using SkyPadWindowsPhone; namespace SkyPadWindowsPhone { using System.IO.IsolatedStorage; public partial class MainPage : PhoneApplicationPage { /// <summary> /// The client to connect to windows live. /// </summary> private LiveConnectClient client = null; /// <summary> /// Stack holding the folderIds /// </summary> private Stack<String> folderIds = new Stack<string>(); /// <summary> /// Appsettings /// </summary> private static readonly IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings; /// <summary> /// The folder id, to save the file to. /// </summary> private DirectoryItem _FolderToSaveTo = null; /// <summary> /// List of directories avialable. /// </summary> public ObservableCollection<DirectoryItem> _Directories; /// <summary> /// The document id of the last saved file. /// </summary> private string _DocId = string.Empty; /// <summary> /// Name of the last saved file /// </summary> private string _LastFileName = string.Empty; /// <summary> /// Has the file to be saved? /// </summary> private bool needToSave = false; // Constructor public MainPage() { InitializeComponent(); this.listPicker1.Visibility = Visibility.Collapsed; this.txtbFileName.Visibility = Visibility.Collapsed; this.btnOpenFile.IsEnabled = false; this.btnSaveFile.IsEnabled = false; this.txtbFileText.Visibility = Visibility.Collapsed; } /// <summary> /// Handles the Click event of the button1 control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> private void button1_Click(object sender, RoutedEventArgs e) { //Save Button if (this._FolderToSaveTo != null && this.txtbFileName.Text != string.Empty && this.txtbFileText.Text !=string.Empty) { this.SaveNote(_FolderToSaveTo.DirectoryId); } else { MessageBox.Show("Please check, filename or filext, or folder you want to save to."); } } /// <summary> /// Called when [session changed]. /// </summary> /// <param name="sender">The sender.</param> /// <param name="args">The <see cref="Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs"/> instance containing the event data.</param> private void OnSessionChanged(Object sender, LiveConnectSessionChangedEventArgs args) { if (args != null && args.Session != null && args.Session.Status == LiveConnectSessionStatus.Connected) { this.client = new LiveConnectClient(args.Session); this.SignedInUser(); } else { this.SignedOutUser(); } } /// <summary> /// User state is signed in. /// </summary> private void SignedOutUser() { // User not login, cleanup user data txtbFileText.Text = ""; txtbFileText.Text = ""; tblStatus.Text = ""; imgUserPicture.Source = null; tblUserName.Text = ""; folderIds.Clear(); needToSave = false; txtbFileName.Text = ""; this.listPicker1.Visibility = Visibility.Collapsed; this.txtbFileName.Visibility = Visibility.Collapsed; this.btnOpenFile.IsEnabled = false; this.btnSaveFile.IsEnabled = false; this.txtbFileText.Visibility = Visibility.Collapsed; } /// <summary> /// Called when a page is no longer the active page in a frame. /// </summary> /// <param name="e">An object that contains the event data.</param> protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedFrom(e); } /// <summary> /// Called when a page becomes the active page in a frame. /// </summary> /// <param name="e">An object that contains the event data.</param> protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); } /// <summary> /// User state is signed out. /// </summary> private void SignedInUser() { this.GetUserPicture(); } /// <summary> /// Gets the user picture. /// </summary> private void GetUserPicture() { var memoryStream = new MemoryStream(); client.DownloadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.GetUserPictureCallback); client.DownloadAsync("/me/picture?return_ssl_resources=true", memoryStream, memoryStream); } /// <summary> /// Gets the user picture callback. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="Microsoft.Live.LiveOperationCompletedEventArgs"/> instance containing the event data.</param> private void GetUserPictureCallback(object sender, LiveOperationCompletedEventArgs e) { client.DownloadCompleted -= this.GetUserPictureCallback; if (e.Error == null) { MemoryStream imageStream = e.UserState as MemoryStream; BitmapImage b = new BitmapImage(); b.SetSource(imageStream); if (imageStream != null) { this.imgUserPicture.Source = b; this.imgUserPicture.Visibility = Visibility.Visible; this.tblUserName.Visibility = Visibility.Visible; } else { MessageBox.Show("Unable to find your picture.", "Windows Live Message", MessageBoxButton.OK); } } else { MessageBox.Show(e.Error.Message, "Windows Live Error", MessageBoxButton.OK); } this.GetUserName(); } /// <summary> /// Gets the name of the user. /// </summary> private void GetUserName() { client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.GetUserNameCallback); client.GetAsync("/me"); } /// <summary> /// Gets the user name callback. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="Microsoft.Live.LiveOperationCompletedEventArgs"/> instance containing the event data.</param> private void GetUserNameCallback(object sender, LiveOperationCompletedEventArgs e) { client.GetCompleted -= this.GetUserNameCallback; if (e.Error == null) { var user = e.Result; tblUserName.Text = user["name"].ToString(); } else { tblStatus.Text = e.Error.Message; } GetFiles("/me/skydrive"); } /// <summary> /// Saves the note. /// </summary> /// <param name="path">The path.</param> private void SaveNote(string path) { if (client.Session == null || client.Session.Status != LiveConnectSessionStatus.Connected) { tblStatus.Text = "You need to Sign In"; } else { if (txtbFileName.Text.Length == 0) { tblStatus.Text = "Please provide a Filename"; } else { tblStatus.Text = "Saving " + txtbFileName.Text; System.Text.UTF8Encoding enc = new UTF8Encoding(); var stream = new MemoryStream(enc.GetBytes(txtbFileText.Text)); String filename = txtbFileName.Text + ".txt"; //Disable the textbox this.txtbFileText.Visibility = Visibility.Collapsed; this.txtbFileName.Visibility = Visibility.Collapsed; this.listPicker1.Visibility = Visibility.Collapsed; client.UploadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.SaveNoteCallback); client.UploadAsync(path, filename, true, stream, stream); } } } /// <summary> /// Saves the note callback. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="Microsoft.Live.LiveOperationCompletedEventArgs"/> instance containing the event data.</param> void SaveNoteCallback(object sender, LiveOperationCompletedEventArgs e) { client.UploadCompleted -= this.SaveNoteCallback; if (e.Error == null) { //Get the file-id of the file, theres only one KeyValuePair<string,object> data = e.Result.FirstOrDefault(); this._DocId = data.Value.ToString(); Dispatcher.BeginInvoke(() => { this._LastFileName = txtbFileName.Text + ".txt"; }); //Don't F** with tha WP7 Dispatcha! if (tblStatus.CheckAccess()) { tblStatus.Text = "File saved"; btnSaveFile.IsEnabled = false; btnOpenFile.IsEnabled = true; txtbFileName.Visibility = Visibility.Collapsed; txtbFileText.Visibility = Visibility.Collapsed; ; needToSave = false; } else { Dispatcher.BeginInvoke(() => { tblStatus.Text = "File Saved"; }); Dispatcher.BeginInvoke(() => { btnSaveFile.IsEnabled = false; }); Dispatcher.BeginInvoke(() => { btnOpenFile.IsEnabled = true; }); Dispatcher.BeginInvoke(() => { this.txtbFileText.Visibility = Visibility.Collapsed; }); Dispatcher.BeginInvoke(() => { this.listPicker1.Visibility = Visibility.Collapsed;}); Dispatcher.BeginInvoke(() => { this.txtbFileText.Text = ""; }); Dispatcher.BeginInvoke(() => { this.txtbFileName.Visibility = Visibility.Collapsed;}); needToSave = false; } } else { tblStatus.Text = e.Error.Message; } } /// <summary> /// Saves the BTN click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> private void SaveBtnClick(object sender, RoutedEventArgs e) { if(this._FolderToSaveTo !=null) this.SaveNote(_FolderToSaveTo.Directory); } /// <summary> /// Gets the complete sky drive directory root. /// </summary> private void GetCompleteSkyDriveDirectoryRoot() { this.GetFiles("/me/skydrive"); } /// <summary> /// Gets the files. Here Directories only. /// </summary> /// <param name="folder">The folder.</param> private void GetFiles(string folder) { // check if we are moving to a child folder or just re-enumerating the current folder if (folderIds.Count == 0 || folderIds.Peek() != folder) { folderIds.Push(folder); } client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.GetDirectoriesCallBack); client.GetAsync(folder + "/files"); } /// <summary> /// Gets the directories call back. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="Microsoft.Live.LiveOperationCompletedEventArgs"/> instance containing the event data.</param> private void GetDirectoriesCallBack(object sender, LiveOperationCompletedEventArgs e) { client.GetCompleted -= this.GetDirectoriesCallBack; if (e.Error == null) { _Directories = new ObservableCollection<DirectoryItem>(); List<object> data = (List<object>)e.Result["data"]; // Generate parent folder list entry if (folderIds.Peek() != "/me/skydrive") { _Directories.Add( new DirectoryItem("..",null)); } foreach (IDictionary<string, object> datum in data) { String name = datum["name"].ToString(); String type = datum["type"].ToString(); if (type == "folder") { _Directories.Add(new DirectoryItem(name,datum["id"].ToString())); } else if (name.EndsWith(".txt")) { //name = name.Replace(".txt", null); //createNoteListEntry(name, datum["id"].ToString(), "note"); } } tblStatus.Text = "Found " + _Directories.Count() + " folders"; } else { tblStatus.Text = e.Error.Message; } this.txtbFileName.Visibility = Visibility.Visible; this.txtbFileName.IsEnabled = true; this.txtbFileText.Visibility = Visibility.Visible; this.txtbFileText.IsEnabled = true; this.btnSaveFile.IsEnabled = true; this.listPicker1.Visibility = Visibility.Visible; this.listPicker1.IsEnabled = true; this.listPicker1.DataContext = _Directories; } /// <summary> /// Directories the list selection changed. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.Controls.SelectionChangedEventArgs"/> instance containing the event data.</param> private void DirectoryListSelectionChanged(object sender, SelectionChangedEventArgs e) { this._FolderToSaveTo = (DirectoryItem)(((ListBox)sender).SelectedItem); } /// <summary> /// Downloads the note. /// </summary> /// <param name="noteId">The note id.</param> private void DownloadNote(String noteId) { if (client == null || client.Session == null || client.Session.Status != LiveConnectSessionStatus.Connected) { tblStatus.Text = "You need to Sign In"; } else { var stream = new MemoryStream(); client.DownloadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(this.DownloadNoteCallback); client.DownloadAsync(noteId + "/content?return_ssl_resources=true", stream, stream); } } /// <summary> /// Downloads the note callback. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="Microsoft.Live.LiveOperationCompletedEventArgs"/> instance containing the event data.</param> private void DownloadNoteCallback(object sender, LiveOperationCompletedEventArgs e) { client.DownloadCompleted -= this.DownloadNoteCallback; if (e.Error == null) { // Get the stream with the downloaded file var memoryStream = e.UserState as MemoryStream; // Cursor is at the end of the stream so we need to rewind memoryStream.Seek(0, SeekOrigin.Begin); // Read stream into a byte array byte[] bytes = new byte[1000]; int numbytes = memoryStream.Read(bytes, 0, (int)memoryStream.Length); // Prevent loading textbox from firing a text change event txtbFileText.TextChanged -= this.NotesEditorTextChanged; // Load text into the TextBox decoding it as UTF8 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); txtbFileText.Text = enc.GetString(bytes, 0, numbytes); // Enable editing note content txtbFileText.IsReadOnly = false; // Set Save status to false needToSave = false; btnSaveFile.IsEnabled = false; // Enable detecting changes txtbFileText.TextChanged += this.NotesEditorTextChanged; tblStatus.Text = "Downloaded note (" + numbytes + " bytes)"; } else { tblStatus.Text = e.Error.Message; } this.txtbFileName.Visibility = Visibility.Visible; this.txtbFileText.Visibility = Visibility.Visible; this.listPicker1.Visibility = Visibility.Visible; this.btnSaveFile.IsEnabled = true; this.btnOpenFile.IsEnabled = false; } /// <summary> /// Noteses the editor text changed. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.Controls.TextChangedEventArgs"/> instance containing the event data.</param> private void NotesEditorTextChanged(object sender, TextChangedEventArgs e) { needToSave = true; } /// <summary> /// Datasave for each directory entry. /// </summary> public class DirectoryItem { private string _directory; private string _directoryId; public DirectoryItem(string path,string id) { this._directory = path; this._directoryId = id; } public string Directory { get { return _directory; } set { _directory = value; } } public string DirectoryId { get { return _directoryId; } set { _directoryId = value; } } } /// <summary> /// BTNs the open file click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> private void BtnOpenFileClick(object sender, RoutedEventArgs e) { if(this._DocId != null) { this.txtbFileName.Text = this._LastFileName; this.DownloadNote(this._DocId); } } } }Here the download:
App Hub Registration Is a Pain In The Ass – At Least In Europe
For a couple of days I am now trying to get an App Hub membership. At least i tried it. At this time I am only getting error messages that the transactions could not be performed at this time – but taking – everytime I try to register – one Euro from my credit card account is possible? This where already 5 Euros or more! After calling Microsoft support in Luxemburg (which bills devs in Europe), was not successfull because they don’t feel responsible and let us call the German Support for XBOX-Billing, I was really fed up! So at the end, they told me, that my live-account is tight to 4 accounts, and that I should try to change my email address! My live-account is tight for years to important services like the partner network and others and I am not willed to change my address. The next thing is, that credit card usage as a payment method is not as widely spread as in US and other countries. So paying for XBOX is possible via paypal, why not APP HUB? And why don’t you offer wiretransfers? No – thank you Microsoft! And I hope I will get an App Hub account ASAP! Have you made similar experiences? If so, please comment! Thx.
UPDATE ANOTHER STORY HERE:
Developer Registration Problems with APP HUB
ANOTHER SAD STORY:
Microsoft App Hub issues and their implications
ANOTHER QUITE INTERESTING POST, MABE FOR THE MSFT STAFF:
App Hub Registration issues
ANOTHERONE FROM UK
APP Hub Registration isnt very UK friendly
ANOTHER ONE (SOLVED, AT LEAST)
A tale of two dev accounts
Test SharePoint Services in Isolation
Filed under: SharePoint 2010 Development, Visual Studio 2010
You don’t need live sites anymore to test SharePoint 2010 Servces. How? Check out this Video on Channel9:
HTML 5 capable browser like IE9 ist needed to watch this stream.
Working CAML Query to get all items with ECMA-Script
Filed under: SharePoint 2010 Development, Visual Studio 2010
For a couple of days i was searching for the right composition to query all items from a document library out of SharePoint – even in subfolders – from CAML and ECMA-Script. Then I decided to ask some of the greatest people in the world – the guys on MSDN, how to achieve this thing. Here is the short – but working – answer:
Hi injac,
The following query worked for us:
var query = <View Scope=’RecursiveAll’>
<Query> <Where> </Where> <OrderBy>
<FieldRef Name=’Modified’ Ascending=’False’ />
</OrderBy> </Query> </View>
var camlQuery = new SP.CamlQuery(); camlQuery.set_viewXml(query);
allItems = list.getItems(camlQuery); context.load(allItems); context.executeQueryAsync(Function.createDelegate(this, this.OnSuccess), Function.createDelegate(this, this.OnFailure));
Sketchflow Mockup of SPDCMVnext – Please Participate!
Filed under: SharePoint 2010 Development, Visual Studio 2010, WPF
For the next release of the embDocumentInhalator WebPart I had a new vision, and I want you – my Downloaders and potential users to participate. The plan is to create an stand-alone application, that will be a frontend to your documents and libraries, to work with SharePoint.
This will include four new main features, despite of the structural changes:
- Full CRUD implementation for document and library handling
- Full PDF capabilities – like custom page sizes, and searchable PDF’s
- Full OCR capabilites
- Scanning multiple pages via ADF
The listed features are planned only for the first initial release. More is to come.
So I would like to hear from you, how you like the idea, and what features YOU would like to see in this version.
If like to participate, please download the current archive, unpack and start the app. Browse through the mockup,
and tell me what you think. Please use the codplex site for feedback.
Mr. Steve Jobs – Rest In Peace
I was a shocked today, when I heard the news about his dead. Even knowing that his health was not at its best, I was shocked. When I look back for the last 20 years Mr. Steve Jobs has “impregnated” me in a manner that is not easy to explain in words. My first time I heard about him, was reading one of the books about Apple and all the creativity, blood and sweat he and Woz invested in their dream. The impression could not be greater! So I decided to follow his unbreakable will of iron to swear myself, that one day I will be as successfull as he is, following his principles and to connect the dots in my life. Thank you Steve for my first clients. I have written my first commercial app on a Mac Performa 5200 (check it out here).
I would like to motivate everybody to read about him and his life – and maybe – you will connect the dots in your life.
Never to be forgotten. Rest in peace. I wish all the best for his family, friends and all other people loving this awsome man. You’ll be always in my heart, mind and soul.
Thank you so much.
Windows 8 – Developer Preview is Here! – Part 1 – Installing Windows 8
Yesterday I was really exited installing the Developer Preview of Windows 8! Here are some pictures that show the installtion procedure. More is to come really fast.
- Confirming the License
Confirming the Developer Preview License
- Prepering the System
Taken from Windows 7 - System Preparation
- Taken from Windows 7 - Upgrade or custom install
Custom or Upgrade Install
- Installation is running
Files are being installed.
- Something new ! The "Donat of death" was replaced!
A simple but beautiful metro design wait seqence is displayed.
- Preparing Registry Settings
Registry settings are beeing prepared.
- Preparing The System
Preparing the System.
- Getting the System Ready
Only a few steps away from the all new experience!
- Making the Lawyers Happy
Making the lawyers happy. The licensing Terms.
- Personalize - Set PC Name
Set the name of the PC
- Setting The Network Sharing Options
Settings the sharing options for the network connections.
- Choose Express Settings Or Customize
Choose pre-defined settings or customize the install.
- Settings For Windows Update
This are the possible settings for Windows Update.
- Settings For Smart Screen Filter
Settings for Smart Screen Filtering.
- Helping Making Windows 8 Better
Making Windows 8 better.
- Making Windows 8 Better - Part II
Helping making Windows 8 better - Part II
- Check Online For Solutions And Problems
Check online for solutions and problems.
- Share Informations With Other Applications
Share informations about yourself with other applications.
- Use Windows Live Account For Login
Here you can choose your windows Live Account for logging in to Windows 8
- Enter Password And Email-Address
Entering the password and email-address for your Live Account.
- Finalizing The Settings
Windows 8 is finally finalizing the settings ;-)
- Preparing The PC
Finally preparing the PC for the first start.
- Windows 8 Start Screen After Login
Finally the installation is finished. Yeah!
Added PDF Functionality to SharePoint-Scanner-WebPart embDocumentInhalator
Today I have added the possibility to scan documents, and convert them directly to PDF-documents into a SharePoint 2010 library. Enjoy!
The news:
The WebPart:
SharePoint 2010 Server-Side WIA-Scanning-WebPart
Today I have posted a new video on YouTube regarding a SharePoint 2010 webpart that I have developed. This little webpart (embDocumentInhalator) enables users to scan documents via scanners that are connected to the server. I have seen many postings while surfing the internet, where the people ask how to implement scanning features to use with ASP .NET. So, hopefully, here is the answer.
The video on YouTube shows how the webpart can be used. So take a look at the WebPart in action and watch this video:
And here the main structure of the trusted-proxy-user-solution:
You can download the webpart on codeplex:
Have fun! And thank you for reading.

















































