Archive

Posts Tagged ‘Filesystem’

HowTo: open older Pi SD card via USB multi-reader on Raspberry Pi

After doing

sudo apt-get update

sudo apt-get upgrade

on an older Raspbian installation (at a 4GB SD Card), some corruption occured (probably due to lack of space, since I see newer NOOBS asks for an 8GB SD Card), making it unbootable. Would only show the NOOBS splash screen, but couldn’t boot into Raspbian.

I just needed some audio files from the desktop of that older installation (it was an unattended looping audio player for an art installation).

So I prepared a new SD Card with the free SD Card Formatter utility and put the latest NOOBS files in it. Booted the Raspberry Pi 2 with it and installed the latest Raspbian OS (full) from the menus. This time doing again the above two commands from a terminal and rebooting didn’t cause any problem.

However, I was searching for the files and couldn’t find them. I had gotten a bit confused at first, since when plugging in the reader it would show a dialog asking whether I wanted to open a file explorer, but then it would keep that dialog again and repeat the action till I closed the dialog. Then I read

…in Linux when there are more slots in a card reader, only the one labelled LUN 0 is read unless other tools are installed to read the other luns. If your SD slot is not LUN 0, then the SD card will not be seen.There are a lot of pages on web about this, I will be installing a package called sg3-utils that is supposed to enable reading other card reader slots.

at this thread https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=11397 and just in case I did:

sudo apt-get install sg3-utils

from a terminal and then tried plugging in again the USB card reader with the older SD card.

This time I was patient and instead of closing the action dialog that was shown after executing the suggested action (open with file explorer), I repeated it for three times and respective file explorer windows came up, then the action dialog closed by itself. The three windows were showing different partitions that had been found in the SD card, and one of those windows was showing “/media/pi/” folder. I navigated from there to “root/home/pi/Desktop” subfolder, where I could see the old desktop contents and drag-drop the audio files I was looking for to the new desktop.

Advertisements

HowTo: Drop files onto Silverlight controls

I was recently adding drop-files support to ClipFlair Studio, so I had to do some research on the related API that is available to Silverlight apps.

Silverlight supports a limited set of Drag-and-Drop interaction with the operating system (supposedly for security reasons, but most probably because of the classic cross-platform implementation pains).

For example it allows you to drop a collections of file objects from the operating system’s file explorer (or other similar application) onto a Silverlight drop target, but not the other way around.

Also, it doesn’t allow dropping other flavors of content, like text, images etc., only collections of file objects.

To allow dropping files onto a Silverlight control you set AllowDrop property to true and handle the Drop and optionally the DragEnter/DragOver/DragLeave events to provide visual feedback during the drop operation (mostly when over the drop target, unless you do Mouse Capturing).

<RichTextBox
  x:Name="rtb"
  …
  AllowDrop="True" 
  Drop="rtb_Drop"
  DragEnter="rtb_DragEnter"
  DragOver="rtb_DragOver"
  DragLeave="rtb_DragLeave"

  />

 

  #region DragAndDrop

    private void rtb_Drop(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "Normal", true);

      //the Drop event passes in an array of FileInfo objects for the list of files that were selected and drag-dropped onto the RichTextBox.
      if (e.Data == null)
        return;

     IDataObject f = e.Data as IDataObject;
      if (f != null) //checks if the dropped objects are files

      {
        object data = f.GetData(DataFormats.FileDrop); //Silverlight only supports FileDrop
        FileInfo[] files = data as FileInfo[]; //…GetData returns null if format is not supported

        e.Handled = true;

        if (files != null)

          //Walk through the list of FileInfo objects of the selected and drag-dropped files and parse the .txt and .docx files
          //and insert their content in the RichTextBox.
          foreach (FileInfo file in files)
            Load(file, false);
      }

    }

    private void rtb_DragEnter(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "DragOver", true);
      e.Handled = true;
    }
   
    private void rtb_DragOver(object sender, System.Windows.DragEventArgs e)
    {
      e.Handled = true;
      //NOP
    }

    private void rtb_DragLeave(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "Normal", true);
      e.Handled = true;
    }

    #endregion

 

For the visual feedback you can use VisualStateManager and respective VisualStates at say a Grid that wraps the drop target in the XAML layout.

<Grid x:Name="LayoutRoot">
   <VisualStateManager.VisualStateGroups>
     <VisualStateGroup x:Name="DragStates">
       <VisualStateGroup.Transitions>
         <VisualTransition GeneratedDuration="0:0:0.3">
           <VisualTransition.GeneratedEasingFunction>
             <CircleEase EasingMode="EaseIn"/>
           </VisualTransition.GeneratedEasingFunction>
         </VisualTransition>
       </VisualStateGroup.Transitions>
       <VisualState x:Name="Normal"/>
       <VisualState x:Name="DragOver">
         <Storyboard>
           <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" Storyboard.TargetName="rtb">
             <EasingColorKeyFrame KeyTime="0" Value="#FFFFF7D1"/>
           </ColorAnimationUsingKeyFrames>
         </Storyboard>
       </VisualState>
     </VisualStateGroup>
   </VisualStateManager.VisualStateGroups>

 

Note that on MacOS-X Safari doesn’t pass drop events automatically to plugins and you have to catch them via Javascript and pass them to Silverlight, plus I’ve read that in MacOS-X Firefox doesn’t support this at all.

Even worse, Microsoft’s workaround article has a typo in the Javascript (should call dragDrop instead of drop) and there is a chance it doesn’t work in latest version of Safari. For more see:

http://msdn.microsoft.com/en-us/library/ee670998%28v=vs.95%29.aspx

http://social.msdn.microsoft.com/Forums/silverlight/en-US/42a6b672-7d26-4690-be80-2149da755020/silverlight-4-detect-file-drop-event-on-mac?forum=silverlightarchieve&prof=required

http://community.rightpoint.com/blogs/viewpoint/archive/2011/03/27/silverlight-4-file-drag-and-drop-on-firefox-on-mac.aspx

http://www.telerik.com/forums/dropping-files-using-safari-on-mac (this says one can use HTML5 events and the Silverlight HTML/Javascript Bridge to notify Silverlight)

http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/

HowTo: Bind ASP.net control to list of files or folders

At ClipFlair Gallery metadata input pages for Activities and Clips I had to bind an ASP.net control to a list of files and folders respectively and although I found a Folder Contents DataSource control, it didn’t cover my needs (like filtering of a folder contents).

I just contributed my solution using .NET Anonymous Types and LINQ (assumes a using System.Linq clause) to:

http://stackoverflow.com/questions/1331793/bind-repeater-to-a-list-of-files-and-or-folders

private string path = HttpContext.Current.Server.MapPath("~/activity");

   protected void Page_Load(object sender, EventArgs e)
   {      
if (!IsPostBack) { //only at page 1st load
listItems.DataSource = Directory.EnumerateFiles(path, "*.clipflair") .Select(f => new { Filename=Path.GetFileName(f) });
listItems.DataBind(); //must call this } }

The above snippet gets all *.clipflair files from ~/activity folder of a web project

Update: using EnumerateFiles (availabe since .NET 4.0) instead of GetFiles since this is more efficient with LINQ queries. GetFiles would return a whole array of filenames in memory before LINQ had a chance to filter it.

The following snippet shows how to use multiple filters, which GetFiles/EnumerateFiles don’t support themselves:

private string path = HttpContext.Current.Server.MapPath("~/image");
private string filter = "*.png|*.jpg";

protected void Page_Load(object sender, EventArgs e)
{
  _listItems = listItems; 
  
  if (!IsPostBack)
  {
    listItems.DataSource =
      filter.Split('|').SelectMany(
oneFilter => Directory.EnumerateFiles(path, oneFilter)
.Select(f => new { Filename = Path.GetFileName(f) })
); listItems.DataBind(); //must call this if (Request.QueryString["item"] != null) listItems.SelectedValue = Request.QueryString["item"];
//must do after listItems.DataBind } }


The snippet below shows how to get all directories from /~video folder and also filters them to select only directories that contain a .ism file (Smooth Streaming content) with the same name as the directory (e.g. someVideo/someVideo.ism)

using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;

namespace ClipFlair.Gallery
{
 public partial class VideoMetadataPage : System.Web.UI.Page
 {

  private string path = HttpContext.Current.Server.MapPath("~/video");

  protected void Page_Load(object sender, EventArgs e)
  {
    if (!IsPostBack) { //only at page 1st load
listItems.DataSource = Directory.GetDirectories(path) .Where(f =>(Directory.EnumerateFiles(f,
Path.GetFileName(f)+".ism").Count()!=0)) .Select(f => new { Foldername = Path.GetFileName(f) }); //when having a full path to a directory don't use Path.GetDirectoryName //(gives parent directory), //use Path.GetFileName instead to extract the name of the directory listItems.DataBind(); //must call this } }

 

The examples above are from a DropDownList, but it’s the same logic with any ASP.net control that supports Data Binding (note I’m calling Foldername the data field at the 2nd snippet and Filename at the 1st one, but could use any name, need to set that in the markup):

        <asp:DropDownList ID="listItems" runat="server" AutoPostBack="True" 
          DataTextField="Foldername" DataValueField="Foldername" 
          OnSelectedIndexChanged="listItems_SelectedIndexChanged"
          />

HowTo: Remove invalid filename characters in .NET

In ClipFlair Studio I use DotNetZip (Ionic.Zip) library for storing components (like the activity and its nested child components) to ZIP archives (.clipflair or .clipflair.zip files). Inside the ZIP archive its child components have their own .clipflair.zip file and so on (so that you could even nest activities at any depth) which construct their filename based on the component’s Title and ID (a GUID)

However, when the component Title used characters like " (double-quote) which are not allowed in filenames, then although Ionic.Zip created the archive with the double-quotes in the nested .clipflair.zip filenames, when trying to load those ZipEntries into a memory stream it failed. Obviously I had to filter those invalid filename characters (I opted to remove them to make those ZipEntry filenames a bit more readable/smaller).

So I added one more extension method for string type at StringExtensions static class (Utils.Silverlight project), based on info gathered from the links from related stackoverflow question. To calculated version of a string s without invalid file name characters, one can do s.ReplaceInvalidFileNameChars() or optionally pass a replacement token parameter (a string) to insert at the position of each char removed.

public static string ReplaceInvalidFileNameChars(this string s,
string replacement = "") { return Regex.Replace(s, "[" + Regex.Escape(new String(System.IO.Path.GetInvalidPathChars())) + "]", replacement, //can even use a replacement string of any length RegexOptions.IgnoreCase); //not using System.IO.Path.InvalidPathChars (deprecated insecure API) }

For more info on Regular Expressions see http://www.regular-expressions.info/ and http://msdn.microsoft.com/en-us/library/hs600312.aspx


BTW, note that to convert the char[] returned by System.IO.Path.GetInvalidPathChars() to string we use new String(System.IO.Path.GetInvalidPathChars()).

It’s unfortunate that one can’t use ToString() method of char[] (using Visual Studio to go to definition of char[].ToString() takes us to Object.ToString() which means the array types don’t overload the virtual ToString() method of Object class to return something useful).


Another thing to note is that we don’t use System.IO.Path.InvalidPathChars field which is deprecated for security reasons, but use System.IO.Path.GetInvalidPathChars() method instead. MSDN explains the security issue, so better avoid that insecure API to be safe:

Do not use InvalidPathChars if you think your code might execute in the same application domain as untrusted code. InvalidPathChars is an array, so its elements can be overwritten. If untrusted code overwrites elements of InvalidPathChars, it might cause your code to malfunction in ways that could be exploited.

Can’t step-through Silverlight file dialogs with Visual Studio debugger

While stepping through “ShowDialog()” method of OpenFileDialog with Visual Studio 2010 debugger, at the Silverlight code pictured below (for loading a ClipFlair window’s stored options), I got a “Dialogs must be user-initiated” exception. Same behaviour will be shown with SaveFileDialog too, every time you try to step through the “ShowDialog()” method.

This is because of Silverlight’s security model, which doesn’t allow source code to programmatically show a file dialog when an app is running in its default security sandbox (app is not signed with certificate and user hasn’t given consent for it to run in elevated rights mode), unless that code is called from an event handler that handles some user action on the UI (e.g. some button has been clicked by the user).

Obviously, when stepping through with the debugger it loses the user-initiated-action context somehow and considers the debugger as the initiator of the action, thus not allowing the file dialog to be shown when you try to step-through the “ShowDialog()” method of OpenFileDialog or SaveFileDialog.

The only solution I can suggest is to put a breakpoint right after the “ShowDialog()” returns (e.g. at “using” statement in the code below). If you place a breakpoint at any source code row above or at the “ShowDialog” inside the event handler method (“btnLoad_Click” in the code below) it will fail when the debugger tries to go through the “ShowDialog” method, even if you press “Run” after that breakpoint fires to continue.

image

broken .LNK files assignment (or how to destroy and fix Windows 7)

A friend just called me this morning that their notebook with Windows 7 Starter started today showing the same icon for every Start menu item and for shortcuts (e.g. on the desktop) and when trying to open them the same program would always try to open them.

Seems he had right-clicked and done “Open With…” on a “.lnk” (Windows shortcut) file that was pointing to a missing (deleted) video file. Not knowing what .lnk files really are (filesystem shortcuts), he tried to open it with Windows Media Player.

There are several issues here that Microsoft should fix:

  1. Somebody at Microsoft changed Windows (think this happened at Windows Vista) to have “Always open with this program” option checked by default and this means users can easily damage file assignments that way.
  2. Windows doesn’t seem to protect such critical file extensions from getting reassigned by accident or by malicious code. In fact System File Protection (SFP) should take care to restore this automatically
  3. The Open With dialog shouldn’t allow one to check “Always open with this program” for critical file extensions like “.lnk”.

For older Windows versions (not Vista or Windows 7) I found a solution listed at:
http://support.microsoft.com/kb/172053/en-us?fr=1

but for Windows Vista and Windows 7 the correct solution is discussed at:

http://www.makeuseof.com/answers/change-fix-file-associations-windows-7/

There a Microsoft MVP (admin of http://winhelponline.com/) points to

http://www.winhelponline.com/fileasso/lnkfix_vista.zip

  1. You download this file and unpack/execute the .reg (registry) file that is included in the ZIP archive.
  2. Then Windows will warn you that the changes will occur to Windows Registry, you accept that
  3. Then you get a message the merge was completed.
  4. From Start menu, LOG OFF (from Shutdown submenu select Logoff/Disconnect from system) and LOG ON again.
  5. If everything isn’t fine at the new log-on session, you can also try rebooting the machine.

Windows 7 issue: can’t copy filename of files on read-only media

Just came across one more case of trying to over-protect users and in the way losing functionality (maybe originally unforeseen functionality, but which is nevertheless useful to many end-users).

At Windows 7, Microsoft doesn’t allow you anymore to press F2 or click on a filename to enter edit more for it when the file resides on a read-only media (like a DVD-ROM).

Moreover when you right click the file and select Properties, the filename field at the properties dialog is at a disabled editbox and somebody from the Windows UI team must have taken “disabling” an editbox literally, making the action disable even selecting and copying text from it instead of just making it read-only.

So one would think they would be able to right-click the file, select Copy and then Paste the filepath onto an editbox. No, again no one thought of also putting a text flavor with the full file path on the clipboard so that user could paste it to a textbox (Clipboard supports multiple data flavours for copied items and when you paste an app can select which flavours it knows and might care to use). Think I have suggested that to Microsoft long time ago, but still not implemented.

 

image

%d bloggers like this: