Thursday, August 11, 2016

Windows 10 Visual Elements incl Start Menu Tiles for Native Desktop EXEs compiled with Delphi

This is a summary of what is needed to make a native Windows desktop EXE (compiled with Delphi or any compiler other than Visual Studio) appear with scaled logos and icons throughout Windows, especially in the Start Menu and in File Explorer.

1. The ICO file.

This factoid is based on the Main Icon Group in Delphi, bds.exe, which you can examine with XNResourceEditor or Resource Hacker.




Build an ICO file containing your program icon in all these sizes and color depths. Use that icon when you Project > Build by associating it with the project.  In Delphi: menu Project  > Options, Application.  Do this for at least the target platform combined with Release, e.g. Win32 Release and/or Win64 Release.  Load your icon.  Repeat for other targets as necessary.  Project > Build each one.



2. The visualelementsmanifest.xml file

Make a file named ____.visualelementsmanifest.xml file where the ____ is replaced with the name of your EXE.  So for MyGreatApp.exe it would be MyGreatApp.VisualElementsManifest.xml and this XML file MUST be located in the same folder as your EXE.  The filename itself is case insensitive.

The contents of the manifest XML file will be similar to this:

<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <VisualElements
  DisplayName = "My Great App"
Logo="WinAssets\LockScreenLogo.png" 
        SmallLogo="WinAssets\LockScreenLogo.png" 
        Description="Some text here" 
      ShowNameOnSquare150x150Logo='on'
      Square70x70Logo='WinAssets\Square71x71Logo.png'
      Square150x150Logo='WinAssets\Square150x150Logo.png'
      Square310x310Logo='WinAssets\Square310x310Logo.png'
      ForegroundText='light'
      BackgroundColor='darkTurquoise'/>
</Application>

IMPORTANT: when you look for documentation about this, be careful to note that MOST documented features apply only to MetroUI applications.  Wide logos, for example, are only available for MetroUI apps. [ In fact, I am not sure yet whether the square310x310 logo is used or ignored by Windows 10. ]   MSDN links are at the end of this post.

The choice of WinAssets as the name of the subdirectory is arbitrary. 

EXTREMELY NOT OBVIOUS: the filenames referenced are adjusted automatically by Windows according to some rules that make sense and are documented, but are simply not obvious until you know what you are looking for.  Windows 8.1 and 10 will automatically use the scaled version of your file if you follow Microsoft's XAML naming convention.  In other words, if you create your files with names exactly as indicated in the next step, it will all work out. 


3. A set of PNG files

You can use a single PNG file, or a large set.  If you use a single 256x256px PNG file for all the required files, you will end up with a super large icon in the start menu, like Google Chrome.  Whether this is good-dramatic, or bad-ostentatious, is up to you to decide.

If you want to go for the full set to allow for scaling on all sorts of monitors, there is a Photoshop template that makes all the files for you.  

NOTE: as input to this process, you would want the master copy of the logo in one of these formats, in order of priority:

.ai (Illustrator)

else .cdr (Corel Draw)

else .psd (photoshop min 300 dpi)

else .png 2480x2480


Ok -- go get The Photoshop template file and instructions for its use here.

The output of that process will be a large collection of PNG files.  There will be too many; we only need the LockScreenLogo* files and the Square* files.  The rest are relevant for MetroUI apps.

Note: if you want to prefix all the file names with your product name, go for it and just be sure to include the same prefix within the references in your VisualElementsManifest.xml file.


4. File placement

All those PNG files have to be placed in the WinAssets folder below your EXE, or wherever you specified in your VisualElementsManifest.xml file.

Here is a directory listing so you can see exactly:

 Directory of (snip)

08/12/2016  01:23 AM               xxx _____.exe
08/12/2016  01:13 AM               776 _____.VisualElementsManifest.xml

 Directory of  (snip)\WinAssets

08/12/2016  12:31 AM    <DIR>          .
08/12/2016  12:31 AM    <DIR>          ..
08/11/2016  02:29 PM             1,709 LockScreenLogo.scale-100.png
08/11/2016  02:29 PM             2,219 LockScreenLogo.scale-125.png
08/11/2016  02:29 PM             2,923 LockScreenLogo.scale-150.png
08/11/2016  02:29 PM             4,265 LockScreenLogo.scale-200.png
08/11/2016  02:29 PM            11,137 LockScreenLogo.scale-400.png
08/11/2016  02:36 PM             3,449 Square150x150Logo.scale-100.png
08/11/2016  02:36 PM             4,721 Square150x150Logo.scale-125.png
08/11/2016  02:36 PM             5,930 Square150x150Logo.scale-150.png
08/11/2016  02:36 PM             8,890 Square150x150Logo.scale-200.png
08/11/2016  02:36 PM            26,019 Square150x150Logo.scale-400.png
08/11/2016  02:36 PM             9,327 Square310x310Logo.scale-100.png
08/11/2016  02:36 PM            12,888 Square310x310Logo.scale-125.png
08/11/2016  02:36 PM            17,262 Square310x310Logo.scale-150.png
08/11/2016  02:36 PM            27,721 Square310x310Logo.scale-200.png
08/11/2016  02:36 PM            79,945 Square310x310Logo.scale-400.png
08/11/2016  02:36 PM             3,157 Square71x71Logo.scale-100.png
08/11/2016  02:36 PM             4,206 Square71x71Logo.scale-125.png
08/11/2016  02:36 PM             5,244 Square71x71Logo.scale-150.png
08/11/2016  02:36 PM             7,481 Square71x71Logo.scale-200.png
08/11/2016  02:36 PM            21,862 Square71x71Logo.scale-400.png
              20 File(s)        260,355 bytes




Testing

1. Install your software, and then "pin to Start Menu" to see the visual elements.

2. In file explorer, look at a directory containing your EXE.  Use the View choices to toggle between "Extra large icons", "Large icons", "Medium icons" and "Small icons".  That picks up on the ICO that was compiled to a resource and linked into your EXE.

3. If you have spare time, experiment with changing the DPI scaling of your monitor display.

There is a trick for updating the timestamp of the program shortcut (LNK file) to avoid trouble with Windows caching the display of the visual elements.  If you can run the PowerShell IDE, use this PowerShell syntax:

(ls "C:\Users\(snip)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\(snip)___your program__.lnk").lastwritetime = get-date

Tip: To find your LNK file, locate your program in the Windows Start Menu, right click, Open Location.  Shortcuts are always LNK files.



Graphics Assistance

If for some reason you do not have PhotoShop or any other easy way to make all the PNG files with the exact required names, you can talk to the people at Lucid Impact in North Carolina for some efficient help.  This is a fairly quick and painless exercise when you have the software.  You will however need a high-res original of your program logo artwork, as indicated above. 



References:

This excellent post ( Custom Tiles for Desktop Apps ) should answer any remaining questions you have.  If you like the dramatic big Chrome tile, use the advice there to simplify all this down to a single 256x256 png file.

The necessary MSDN links follow.






Inspiration

http://www.askvg.com/tip-customize-start-screen-tiles-background-color-text-color-and-logo-in-windows-8-1/


Tuesday, July 26, 2016

Windows 10 upgrade success after error 0x80070070 - 0x2000C

This post documents one way to successfully get past error 0x80070070 - 0x2000C with the Windows 10 upgrade process.  Your mileage may vary.

First, the problem.  I used the Media Creation tool to make an ISO  and cleared enough disk space that the installation from ISO was willing to proceed.  I had started from a Windows 7 Pro system, and I used Virtual Clone Drive to mount the ISO.  I was also running this machine inside VirtualBox and had to uninstall the Guest Additions and change the machine type to Windows 10.  All that worked.  The problem was that after the Win10 upgrade was in process and in fact almost complete, it reverted itself with an error message: 

We couldn't install Windows 10
We've set your PC back to the way it ws right before you started installing Windows 10.


0x80070070 - 0x2000C
The installation failed in the SAFE_OS phase with an error during APPLY_IMAGE operation. 




After some research, I found two potentially valid reasons for the trouble.  1, possibly corrupt system image and 2, pending Windows updates.  

To address the possible system corruption, I ran sfc /scannow  



To address the pending updates, I rebooted until there were no more Windows 7 updates pending.

Then I retried the Windows 10 upgrade: no joy. Same error.

Then I contacted Microsoft support via their U.S. Answer Desk chat system and to my complete and total surprise, they ended  up giving me the required answer, after some delays and suitable banter.  

Extra Solution Step 1. Turn off the Windows Update service by running services.msc, finding Windows Update, and setting it to Manual.  This blocks updates until you are ready for them.

Extra Solution Step 2. Download a different, more special Windows 10 ISO from TechBench and use it to upgrade Windows 10.  This yields a 4gb ISO and THAT WORKED

Wednesday, June 1, 2016

Using OpenSSL on Windows to Sign a File Upload Policy for AWS S3

Docs

The authoritative reference for uploading files directly from a web browser to an Amazon S3 bucket is here on Amazon and a nice example with further tips is here, since 2008.  

This post concerns the steps 1-2-3-4 for signing the policy, and doing it with OpenSSL.exe at a Windows cmd prompt.


1. Encode the policy by using UTF-8.  
If you are lucky enough to be able to express your policy in English, then you can use notepad to save your JSON code to a simple Ansi file.  Nothing further required.

Match your utf8 filename to the one you specify in the BAT for step 2 below (inputfilespec).


2. Encode those UTF-8 bytes by using Base64.
A sample BAT file for doing this follows. Please adjust paths and filenames to something reasonable on your own system.  All filenames are arbitrary except that you need to make sure that the output from step 2 ends up as the input to step 3 below. 

setlocal

set  inputfilespec=showcase-upload.policy.utf8.json
set outputfilespec=showcase-viaopenssl.base64.txt

:: change to the folder containing this BAT file
CD /D %~dp0

type %inputfilespec% | D:\Apps\OpenSSL\OpenSSL-Win64\bin\openssl.exe base64 -A > %outputfilespec%

type %outputfilespec%

pause

( Thanks to wiki.openssl.org for the -A flag which prevents \n within the base64 output!!!!!!! )


3. Sign the policy with your secret access key by using HMAC SHA-1.
4. Encode the SHA-1 signature by using Base64.

Steps 3 and 4 are best done together.  A sample BAT follows.  You will be prompted to paste in your secret key, which will be used to sign the policy.

Note that the output from step 2 must become the input for steps 3 and 4.  Coordinate the filenames accordingly.


setlocal

set opensslpath=D:\Apps\OpenSSL\OpenSSL-Win64\bin\

set  inputfilespec=showcase-viaopenssl.base64.txt
set outputfilespec=showcase-viaopenssl.signed.base64.txt

set /P secretkey=Enter secret key :

CD /D %~dp0

@del %outputfilespec%

%opensslpath%openssl.exe dgst -sha1 -hmac "%secretkey%" -binary %inputfilespec% | %opensslpath%openssl.exe base64 -A > %outputfilespec% 

if errorlevel 1 pause
type %outputfilespec%

pause


Happy Uploading.


Wednesday, May 25, 2016

How to Set Up and Serve Private Content using Amazon S3 and CloudFront

Here are my notes regarding an excellent post by Mark S. Rasmussen about Serving Private Content using Amazon S3 and CloudFront.  He uses Dot Net and C# for the steps.  By now, the browser-based AWS console has sufficient features to let us do this without compiling anything in C#.  These notes follow his sequence and tell you how to do each step without C#.


"Why you don’t want to rely on third party GUIs"

I agree with Rasmussen that none of this will make much sense unless you have already learned a great deal about AWS, S3, CloudFront and SHA1 signing.  He is right; using the AWS command line tools or the AWS API is the ultimate way to mastery.  

Beginners, do not cross this line, sorry.

Creating the private bucket

Do NOT use a period ('.') in your bucket name if you (ever) want to use the AWS feature for accelerated upload.  And you really should enable the acceleration feature.  This can be done inside the aws browser-based console, after the bucket exists.  Transfer acceleration one of the S3 bucket properties. 

I used CloudBerry Explorer to make a new AWS S3 bucket.   If you are not using USA-East aka US-Standard aka Virginia, be especially careful to control your bucket region.

( Beginners: CloudBerry Explorer: get started with S3   You need your own credentials to get this all started. )

Creating a CloudFront Origin Access Identity

Login to aws.

Services > CloudFront
On the left-side menu, Private Content > Origin Access Identity
Click [Create OAI]
Enter comment, e.g. OAI used for private distribution access to ___ bucket in ___ region

Be sure to jot down the OAI ID and OAI S3 canonical user ID, or just open the next step in a separate browser window so you can clipboard those details when needed.

Creating the private CloudFront distribution

Services > CloudFront
On the left-side menu, Distributions
Click [Create Distribution]
You will probably be making a "Web" distribution, not Adobe RTMP.  Click the appropriate [Get Started] button.

Answer the questions on the form:

Origin Domain Name: select the private bucket you just made.  Note that the ending of the bucket name SHOULD be .s3.amazonaws.com

Origin Path: leave blank
Origin ID: accept default provided
Restrict Bucket Access: Yes !!  If you leave the default, No, you will not end up with a secure solution.  Click the (i) info-help button for details.
Origin Access Identity:  Use an Existing Identity
Your Identities: select the one you just created. Look for the comment you specified.
Grant Read Permissions on Bucket: Yes
Origin Custom Headers: leave blank

Default Cache Behavior Settings: leave all defaults except
Restrict Viewer Access: Yes
  Trusted Signers: Self
Compress Objects Automatically: Yes  (optional - your decision)

Distribution Settings
Price Class: leave default
AWS WAF Web ACL: None
Alternate Domain Names: optional; I entered a CNAME here
SSL: optional, I used the default CloudFront cert for now

Default Root Object: index.html
leave defaults for remaining questions
Click [Create Distribution]


Setting up a bucket policy to grant our OAI access to the S3 bucket

This will have happened automatically if you selected Grant Read Permissions on Bucket = Yes.  To verify, go to Services > S3, look at Properties of your bucket, open Permissions, click into Edit bucket policy.  Look, do not touch.  Close that without saving any changes.

CORS policy on the bucket

For added security, customize the CORS policy to restrict uploads to a limited set of domain names. If you have the WebHubDemos handy, you can see a sample file: webhubdemos\Source\WHApps\Lite Examples\AWS\showcase-005-cors-on-bucket.xml

Uploading a test object

I used CloudBerry Explorer to upload a jpg file to the top of my protected bucket.

Creating a time limited signed URL for a given object

( wait, make the key pair first )

Creating CloudFront key pairs

If you are using Firefox on a desktop computer with a reasonably wide screen, the drop-down menu is in the top-right corner and has your account name showing. Drop that down and go into Security Credentials.  From there, under the heading Your Security Credentials, click into + CloudFront Key Pairs.  Click [Create New Key Pair].

Note that for .Net and Java, the private key must be changed from the default .pem format to one suitable to the platform.



Creating a time limited signed URL for a given object

CloudBerry Explorer helps with this as well.  Right-click the test jpg file, Generate Web URL. 

You should see an alert as part of the "Generate Web URL" dialog, "...You need to specify a polity to generate a valid signed url. To manage policies click [this link].  Click [this link] ! and then [Add Policy] and fill out the form. 

Once you have a policy, you can select it and then click [Generate] to have CloudBerry Explorer create the signed URL. 

Then [Open Link] to test it.

If you used a policy on a CloudFront domain, the generated URL will look like this:

http://sub.cloudfront.net/path/filename.jpg?Policy=...&Signature=...&Key-Pair-Id=...

The Key-Pair-Id will be the Access Key ID picked up from the earlier step where you created the CloudFront Key Pair. 

If you Base64 Decode the Policy parameter, you will get the policy json as plain-text.


Making Signed URLs under Program Control

Now you JUST need to use your favorite programming language and call a function to create those signed URLs yourself.  Make sure you read Amazon Docs: Serving Private Content  especially  Sample Code and Third-Party Tools and AWS Docs: Creating a Signed URL Using a Custom Policy.  


OpenSSL syntax to sign the policy JSON


type input.policy.utf8.json | bin\openssl.exe sha1   -sign private.key.pem | bin\openssl.exe  base64 > policy.signed.viaopenssl.base64.txt


Links for Delphi Coders

December 2009: Reading, writing and converting RSA keys in PEM, DER, PUBLICKEYBLOB and PRIVATEKEYBLOB formats
Jan 2011: Use the Windows Crypto API to get a Hash of a file


Mar 2003: Wrapper for Crypto API 2.0 functions

TurboPower Lockbox v3.6.3.0


Friday, May 22, 2015

CentOS7 VNC server notes

CentOS 7: VNC Server Cheat Sheet

This is for tigervnc-server
Your port number might not be 1.  1 is used as an example only.


# systemctl enable vncserver@:1.service

# systemctl start vncserver@:1.service

Docs:
https://www.howtoforge.com/vnc-server-installation-on-centos-7

CentOS 7 Firewalld Cheat Sheet

CentOS7 Firewalld Cheat Sheet

# systemctl status firewalld


# cd /etc/firewalld/zones


firewall-cmd --reload

Links:
http://www.certdepot.net/rhel7-get-started-firewalld/
http://www.tecmint.com/configure-firewalld-in-centos-7/

Saturday, April 4, 2015

VboxManage: steps to create a headless Win2012 guest on CentOS7 host

VirtualBox syntax for creating a headless Win2012 guest on a CentOS7 host

The virtual machine name is "Cindarella".  The user owning the files is vboxadmin.

To check your possible operating system types:
vboxmanage list ostypes


Make a VDI drive, 120gb



VBoxManage createhd --filename /home/vboxadmin/vboxes/Cindarella/Cindarella_OS.vdi --size 120480 
(repeat as needed; this example used some VDI files that were already available)


Create the machine, then adjust settings

vboxmanage createvm --name Cindarella  --ostype Win2012_64  --register   --basefolder /home/vboxadmin/vboxes

VBoxManage modifyvm Cindarella  --memory 2000 --acpi on --nic1 bridged --bridgeadapter1 enp2s4

Enable the remote desktop "VRDE" feature (after having controlled the firewall for the selected port)
VBoxManage modifyvm Cindarella  --vrde on  --vrdeport 4321

vboxmanage storagectl Cindarella  --name "SATA Controller" --add sata --portcount 3 --bootable on



Make use of some existing VDI images

Note port changes from 0 to 1 to 2 for each of these hard disks.

VBoxManage storageattach Cindarella --storagectl "SATA Controller" --device 0 --port 0 --type hdd --medium /home/vboxadmin/vboxes/Cindarella/Cindarella_OS.vdi

VBoxManage storageattach Cindarella --storagectl "SATA Controller" --device 0 --port 1 --type hdd --medium /home/vboxadmin/vboxes/Cindarella/Data_DriveD.vdi


VBoxManage storageattach Cindarella --storagectl "SATA Controller" --device 0 --port 2 --type hdd --medium /home/vboxadmin/vboxes/Cindarella/Scratch_DriveE.vdi




Put an ISO in the CD drive

VBoxManage storagectl Cindarella --name "IDE Controller" --add ide

VBoxManage storageattach Cindarella --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium /home/vboxadmin/vboxes/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_SOLUTION_EN-US-IRM_SSSO_X64FRE_EN-US_DV5.ISO


VBoxManage modifyvm Cindarella --boot1 dvd 


Start VirtualBox in Headless mode

vboxmanage startvm Cindarella --type headless


Reset the VirtualBox 

vboxmanage controlvm Cindarella reset

Power off the VirtualBox 

vboxmanage controlvm Cindarella poweroff