HowTo: Fix DVD/CD with Live filesystem (Packet/UDF) on Windows

The other day I found how easy it is to use a Live CD/DVD (where packet writing occurs when adding stuff) instead of a Mastered one (where all is kept to be written when you close the disk) on Windows.

It feels more like using a USB flash disk and should be more safe regarding losing data in the long run if you want to keep some file archive. In theory at least, since there are cases the live disk last write operation may fail and it may appear as an unreadable disk after one, making funny noises when you insert it and freezing for long time periods Windows Explorer when you try to access it.

However, the UDF filesystem that it uses keeps multiple VAT tables for the blocks written to the disk, which means it can be restored to the last workable state of the disk (you might still lose data from the last block I guess, but you’ll have access to the rest of the files you had written to the disk). For any files you find missing, you can try file recovery software with deep search option, like ISOBuster.

To restore such a disk back to working state, on Windows 10 you can right click the Start menu button and from the context (popup) menu shown, you can select to run PowerShell as Administrator. Then you can write CMD and press ENTER. The classic command-line shell (DOS syntax) will open up, where you should type-in chkdsk /f e: (replacing e: with the letter of the drive where the problematic disk has been inserted – can find that one easily from Windows Explorer / My Computer) and press ENTER again.

The disk should be detected as being of UDF format and the disk checking (chkdsk) command will check for a valid VAT on the last written block and if it can’t will try to revert the media to a previous state, before the corruption occurred by placing at the the end of the disk the last valid VAT.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\WINDOWS\system32> cmd
Microsoft Windows [Version 10.0.17134.165]
(c) 2018 Microsoft Corporation. Με επιφύλαξη κάθε νόμιμου δικαιώματος.

C:\WINDOWS\system32>chkdsk /f e:
The type of the file system is UDF.
Volume Μουσική is UDF version 2.01.

Chkdsk is running on media that does not support writes in place.
On such media chkdsk operation is limited to verifying the presence
of a valid VAT on the last written block and if necessary searching
for the last valid VAT and placing it at the end of the disk.
This could revert the media to a previous state before the corruption
occured.

Chkdsk could not find a valid VAT at the end of the volume.

CHKDSK is searching for a valid VAT …

And after some ages (stayed at 0% for some time and then took around a day progressing slowly on my machine for a DVD) you’ll hopefully see something like:

Search for VAT completed.
Chkdsk is copying last valid VAT at block 1722719 to the end of the
volume. This will revert the volume to its state at 01:13 on
10/09/2018.

Windows has made corrections to the file system.
No further action is required.

   4595200 KB total disk space.
    222240 KB available on disk.

      2048 bytes in each allocation unit.
   2297600 total allocation units on disk.
    111120 allocation units available on disk.

Then type exit followed by ENTER key twice to exit the command processor (cmd) and PowerShell. This will close the console window.

C:\WINDOWS\system32>exit
PS C:\WINDOWS\system32> exit

Enjoy your disk with its files again, hopefully all of them… Plus you’ll be able to add more files to the disk, which could have even been near to empty when the corruption had occurred. Note that when you’re finished and don’t want to write anymore files to the disk, you can right click it and close the session, so that it can be readable on more systems.

Advertisements

HowTo: include MVC model property Display name in Required validation message

Just came across this validation error display in an MVC app I’ve recently started maintaining. The required input field validation seemed to not be localized, resulting in a mixed English and Greek (from the field’s Display name) message:

image

Looking at the MVC model I noticed they were using [Required] attributes for the userName and password properties, together with [Display(Name = "…")] for the displayed property title

public class LoginModel
  {
     [Required]
     [Display(Name = "Όνομα Χρήστη")]
     public string userName { get; set; }

     [Required]
     [DataType(DataType.Password)]
     [Display(Name = "Κωδικός")]
     public string password { get; set; }

     //…

That was changed to:

public class LoginModel
  {
     [Required(ErrorMessage = "Το {0} είναι απαραίτητο.")]
     [Display(Name = "Όνομα Χρήστη")]
     public string userName { get; set; }

     [Required(ErrorMessage = "Το {0} είναι απαραίτητο.")]
     [DataType(DataType.Password)]
     [Display(Name = "Κωδικός")]
     public string password { get; set; }

resulting in a fully localized validation error message with the respective property’s Display name auto-inserted in the validation ErrorMessage, thanks to the {0} used in the message string:

image

Note there’s also the lazy route like in this property:

[Display(Name = "Περίοδος Εγγύησης(Έτη):")]
[Required(ErrorMessage = "Απαραίτητο πεδίο")]
public int warrantyPeriod { get; set; }

where you just say something like “Required field” in the localized error message. This however will work only when you always show the error message next to the input field that fails to pass validation.

If you want to also show a validation summary say at the beginning and/or the end of the page (depending on where your submit button is), you’ll end up with an error summary that may just contain multiple entries of “Required field” text without any indication on what field it was (which would be practically useless that is).

Note that sometimes due to lack of space in a webpage (say if you have lots of input fields in a grid) you can only show say red “*” near input fields that have validation errors and explain them more in the tooltips and in an error summary control.

Even better you can use resource strings to avoid error message string duplication. That approach, though a bit more verbose as implemented in ASP.net means easier centralized maintenance and localization from a per locale/language resource file and less typos or slightly different error messages for the same thing. See example and related screenshots at https://stackoverflow.com/a/22849638

Fix: jQuery’s jqGrid search UI custom styling

Lately, I’ve got the task of maintaining/extending an ASP.net MVC web application that is using jQuery’s jqGrid for data grids on its UI. First thing I noticed was how confusing the search UI on the grid’s header was:

image

Those symbols on the left-side of each column’s searchbox are for the type of search (e.g. contains, doesn’t contain, equals, starts with, doesn’t start with, ends with, doesn’t end with).

Bit too many options and using programming-related symbols that probably intimidate several users in my opinion:

image

But the worse is the “x” button (that clears the searchbox) on the right of each searchbox, that combined with the search-type symbols makes the whole search bar look like some strange mathematical expression.

So using the browser dev tools (F12) and some CSS rules I quickly restyled that search bar to make it more appealing UI/UX wise:

image

Added a border around the “x” button that clears the searchbox and offseted using a negative margin so that the searchbox and it fuse together visually on their sides. Also made the search-type symbol (that opens the search-type selection popup when clicked) of lighter color. It may look a bit-like some disabled thing like that, but at least it should confuse average users less with its use of technical symbols like that.

Just need to add the rules above at the ASP.net MVC app’s Site.css (probably to be found at the Content subfolder of the webapp) and remember to press F5/Refresh in one’s browser in case the old styling still appears due to caching.

Update:

I noticed on older versions of Windows (other than Windows 10 that is) that bevels were showing at the text inputs, leading to this ugly effect:

image

So I had to add some more rules to remove the bevel borders and use a consistent border color.

Removing the bevels seemed to also remove the inner padding of the text inputs, so added a padding of 2px and some box-sizing rules to make sure the padding doesn’t affect the input’s size.

/* OS-independent styling for input and textarea borders */
textarea,
input[type="text"],
input[type="password"] {
    border-style: solid;
    border-width: 1px;
    border-color: gray;
    padding: 2px;
    -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box; /* Firefox, other Gecko */
    box-sizing: border-box; /* Opera/IE 8+ */
}

Categories: Posts Tags: , , , , , , , , ,

Getting resulting SQL string from parametric ADO.net SqlCommand

Microsoft is suggesting to always use Named parameters with SqlCommands for security reasons (to avoid SQL injection exploits), but they haven’t thought of providing a property at SqlCommand to give you back the result SQL so that you can have your app log it without resorting to SQL Server for that logging.

Found a solution at CommandAsSQL project on GitHub and the discussion that brought it to life at https://stackoverflow.com/questions/265192/get-the-generated-sql-statement-from-a-sqlcommand-object/

That solution was only for the case where the type of the SqlCommand was StoredProcedure, but needed to cover non-Stored procedures too (aka type Text of SqlCommand), so I augmented that library with this logic:

    private static void CommandAsSql_Text(this SqlCommand command, 
System.Text.StringBuilder sql) { string query = command.CommandText; foreach (SqlParameter p in command.Parameters) query = Regex.Replace(query,
"\\B" + p.ParameterName + "\\b", p.ParameterValueForSQL());
sql.AppendLine(query); }

The pull request is at: https://github.com/jphellemons/CommandAsSql/pull/3/commits/527d696dc6055c5bcf858b9700b83dc863f04896

The Regex idea was based on @stambikk’s and EvZ’s comments at that StackOverflow thread and the "Update:" section of https://stackoverflow.com/a/2544661/903783 that mentions "negative look-behind assertion".

The use of \B instead of \b for word boundary detection at the start of the regular expression is because the p.parameterName will always start with a "@" which is not a word character.

Note that ParameterValueForSQL() is an extension method defined at the CommandAsSql library to handle issues like single-quoting string parameter values etc. It may have a bug with its date handling currently though, will submit an issue on that

Btw, other promising piece of code is at https://github.com/jeroenpot/SqlHelper/blob/master/Source/Mirabeau.MsSql.Library/SqlGenerator.cs (mentioned at an answer in this thread). Probably could merge code from CommandAsSql and SqlGenerator if one finds something not working at one or the other.

Gotcha: VBScript DropHandler doesn’t support Unicode filenames

It seems VBScript (.vbs) script file’s DropHandler on Windows is broken regarding Unicode filenames, as described at https://stackoverflow.com/a/4366906/903783

A workaround suggested by user DG there (https://stackoverflow.com/a/13587850/903783) was to use a batch file to accept the dropped file, then pass the filename(s) to the VBScript script file (.vbs) as command-line parameters. If you just care about a single instead of multiple dropped files, there’s a simpler version of a batch file one can use, as I suggested at https://stackoverflow.com/a/52239049/903783. Copying below:


Based on DG’s answer, if you just want to accept one file as drop target then you can write a batch file (if you have it named as "x.bat" place VBscript with filename "x.bat.vbs" at same folder) that just contains:

@"%0.vbs" %1

the @ means to not output the row on the display (I found it to show garbage text even if you use chcp 1250 as first command)

don’t use double-quotes around %1, it won’t work if your VBScript uses logic like the following (code I was using below was from http://jeffkinzer.blogspot.com/2012/06/vbscript-to-convert-excel-to-csv.html). Tested it and it works fine with spaces in the file and folder names:

  Dim strExcelFileName
  strExcelFileName = WScript.Arguments.Item(0) 'file name to parse

  ' get path where script is running
  strScript = WScript.ScriptFullName
  Dim fso
  Set fso = CreateObject ("Scripting.FileSystemObject") 
  strScriptPath = fso.GetAbsolutePathName(strScript & "\..")
  Set fso = Nothing

  ' If the Input file is NOT qualified with a path, default the current path
  LPosition = InStrRev(strExcelFileName, "\")
  if LPosition = 0 Then 'no folder path
    strExcelFileName = strScriptPath & "\" & strExcelFileName
    strScriptPath = strScriptPath & "\"
  else 'there is a folder path, use it for the output folder path also
    strScriptPath = Mid(strExcelFileName, 1, LPosition)
  End If
  ' msgbox LPosition & " - " & strExcelFileName & " - " & strScriptPath

Gotcha: use parentheses around ternary op conditional expressions

Just came across the following case in C# that puzzled me momentarily, especially since the strings involved were long enough and the expression was broken on multiple lines:

bool flag = true;
string test1 = flag? "xa" : "xb";
string test2 = "x" + (flag? "a" : "b");
string test3 = "x" + flag? "a" : "b";

The test3 case fails since the compiler tries to evaluate the "x" + flag expression at the left side of the operator ?, complaining that it cannot implicitly convert string to bool.

e.g I accidentally produced the following wrong code while I was trying to refactor some third-party code to make it more readable:

string test3 = “some long string here” +

                     (someFlag)?

                     “some other long string”

                     :

                     “some alternative long string”;

whereas the correct was:

string test3 = “some long string here” +

                     ( (someFlag)?

                     “some other long string”

                     :

                     “some alternative long string” );

The correct one needs the whole conditional expression enclosed in parentheses. In fact, the parentheses around (someFlag) can be skipped. In usually prefer them visually, even when I use just a boolean variable instead of a more complex boolean expression, but in case like this one the x + (someFlag)? a : b can be confusing to the reader of the code, not seeing x + (someFlag) will be treated as the conditional instead of someFlag.

Luckily the C# compiler is deterministic enough and not trying to imply meaning from one’s wrong syntax. Had it been some futuristic AI-based interpreter, well, it might have gotten confused there too.

To avoid this confusion in the first place, probably one could have designed a (bool)?x:y operator instead with parentheses being required around the boolean expression, but people coming from other languages (say C++) might then end up writing bool && (bool)?x:y and expect the condition to be bool && (bool) instead of just (bool), so even that syntax would be problematic.

Speaking of other languages, quoting from Wikipedia article on ternary operator:

C++

Unlike in C, the precedence of the ?: operator in C++ is the same as that of the assignment operator (= or OP=), and it can return an lvalue. This means that expressions like q ? a : b = c and (q ? a : b) = c are both legal and are parsed differently, the former being equivalent to q ? a : (b = c).

So confusion even between languages that share a C-style syntax might not be avoided.

Fix: Temporary or Local roaming profile message after Windows login

  Researching how to solve a “You have been logged on with a temporary profile” message on a system set up to use a roaming profile (and after I had first checked/fixed the filesystem for errors which is the classic cause for that when using local profiles) I came across this article:

http://www.grouppolicy.biz/2011/07/how-to-reset-a-roaming-profile-in-windows-7

Near the end of the article they mentioned a registry trick from

https://social.technet.microsoft.com/Forums/windows/en-US/5ec0b949-effa-4e30-ba09-dc948a4c7a8b/windows-7-starting-with-a-temporary-profile?forum=w7itprogeneral

So I tried just the registry trick without even logging into an other admin account (it was an admin account that had the problem, although I know people suggest to avoid roaming for those), that is I renamed the account’s profile key under HKLM\Windows NT\Current Version\ProfileList with an appended .bak extension (instead of backing it up externally and then deleting it) and then did log off and log on again.

To find the correct child key to rename, just check each one there and see which one has the ProfileImagePath value for the profile you’re interested in. If for the login you’re using a Microsoft account instead of a local or ActiveDirectory based one and you’re not sure which name it uses underneath, then you can type the text %userprofile% at Search on the taskbar and press ENTER to see which folder path it opens.

  All was then fine on that machine, but then the rest of the computers that were fine before started complaining that due to some problem with loading the roaming profile they loaded a local copy of it instead.

The fix I devised for that issue was to log into those computers with the problematic account, rename the key for the profile again there (adding the .bak extension), log off and log on again, then rename the key back to normal and log off and log on again. That stopped the complaining (simple log off/log on without that renaming wouldn’t fix it).

Στιγμιότυπο οθόνης (4237)

Guess what that did was to not load the roaming profile, but keep referencing it while using the local copy instead and the log off after the renaming of the key to correct value again uploaded the correct profile (from the local copy) to the server.

Note that to open regedit and restore that key’s name after logging in the 2nd time (start menu and taskbar’s search wasn’t working anymore) I had to use CTRL+SHIFT+ESC (was on a remote desktop session) and at the task manager select to see more details, then use its File/Run… menu and give regedit as the command to execute.

Στιγμιότυπο οθόνης (4238)

Στιγμιότυπο οθόνης (4239)

  Btw, I’ve also seen the Reprofiler tool being mentioned, probably it can copy the roaming profile over a local copy or vice-versa if needed – https://iwrconsultancy.co.uk/reprofilerhttps://sourceforge.net/projects/reprofiler/ without having to resort to registry hacks to trick the respective service into copying in the direction one wants.

Categories: Posts Tags: , , , , , ,
%d bloggers like this: