How to detect windows 7 in NSIS - c#

Right now we are using windows form. NSIS is using for windows form installation. But i need to block installation in windows 7 o.s. How to do that? I am using the below code.
; Script generated by the HM NIS Edit Script Wizard.
; HM NIS Edit Wizard helper defines
!define PRODUCT_TYPE "Home" ; Home/Clinic ------
!define CONFIG_TYPE "Prod" ; Release/Local/Devl/Devl_Test/Demo/Test/Prod ------
!define PRODUCT_NAME "nQ Medical ${PRODUCT_TYPE} Keyboard"
!define PRODUCT_VERSION "1.2.0"
!define PRODUCT_PUBLISHER "nQ Medical Inc."
!define PRODUCT_WEB_SITE "https://platform.nq-medical.com"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${APP_NAME}"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define APP_NAME "nQKeyboard.exe"
; MUI 1.67 compatible ------
!include "MUI.nsh"
; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "nQKeyboard\iconNQ.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
RequestExecutionLevel admin
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; License page
!insertmacro MUI_PAGE_LICENSE "nQKeyboard\bin\${CONFIG_TYPE}\EULA.txt"
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_RUN "$INSTDIR\${APP_NAME}"
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES
; Language files
!insertmacro MUI_LANGUAGE "English"
; MUI end ------
Name "${PRODUCT_NAME}"
;Currently deploys the installer file to a 'Published' sub-directory in the 'Solution' directory
OutFile "Published\nQ Medical ${PRODUCT_TYPE} Keyboard.exe"
InstallDir "$PROGRAMFILES\nQ Medical Keyboard"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show
Section "MainSection" SEC01
; Kill the running application
ExecWait "TaskKill /IM ${APP_NAME} /F"
SetOutPath "$INSTDIR"
SetOverwrite try
File "nQKeyboard\bin\${CONFIG_TYPE}\iconNQ.ico"
File "nQKeyboard\bin\${CONFIG_TYPE}\Newtonsoft.Json.dll"
File "nQKeyboard\bin\${CONFIG_TYPE}\RestSharp.dll"
File "nQKeyboard\bin\${CONFIG_TYPE}\RestSharp.Serializers.NewtonsoftJson.dll"
File "nQKeyboard\bin\${CONFIG_TYPE}\GraphQL.Client.dll"
File "nQKeyboard\bin\${CONFIG_TYPE}\GraphQL.Common.dll"
File "nQKeyboard\bin\${CONFIG_TYPE}\EULA.txt"
File "nQKeyboard\bin\${CONFIG_TYPE}\${APP_NAME}"
CreateDirectory "$SMPROGRAMS\nQ Medical Keyboard"
CreateShortCut "$SMPROGRAMS\nQ Medical Keyboard\nQ Medical Keyboard.lnk" "$INSTDIR\${APP_NAME}"
CreateShortCut "$DESKTOP\nQ Medical Keyboard.lnk" "$INSTDIR\${APP_NAME}"
File "nQKeyboard\bin\${CONFIG_TYPE}\${APP_NAME}.config"
SectionEnd.
So How to add code section? ie; if windows 7 is o.s. then installation not takes place. show error message when execute script. how to do that?

NSIS provides the WinVer.nsh header file that helps you detect various Windows versions.
Version detection might seem simple at first but it is easy to make mistakes and your question does not really provide enough information to write a definitive answer!
The naïve answer to your question is
!include WinVer.nsh
Function .onInit
${If} ${IsWin7}
MessageBox MB_ICONSTOP "Windows version blah blah!"
SetErrorLevel 1150 ; ERROR_OLD_WIN_VERSION
Quit
${EndIf}
FunctionEnd
This seems fine at first but assuming there is some technical reason why your application cannot run on Windows 7 then you probably also need to block Server 2008 R2 because it is basically the same version of Windows:
${If} ${IsWin7}
${OrIf} ${IsWin2008R2}
...
Most of the time you have some minimum version of Windows that you support and you really should block anything older. The best way to do this is to make sure that you are on a version you support:
!include WinVer.nsh
Function .onInit
${IfNot} ${AtLeastWin8}
MessageBox MB_ICONSTOP "Windows version blah blah!"
SetErrorLevel 1150 ; ERROR_OLD_WIN_VERSION
Quit
${EndIf}
FunctionEnd
If you are really familiar with the various Windows build numbers you can also check that directly:
${IfNot} ${AtLeastBuild} 9200
...

Related

How to enumerate the real Windows File Explorer windows

I'm trying to enumerates all open File Explorer windows in a PowerShell script.
I have already found on other posts how to enumerate all explorer.exe windows instances, for example using the Shell.Application COM API:
(New-Object -com "Shell.Application").windows()
But this actually returns more than I want:
I want only the "real" File Explorer windows showing actual files on my disk or network, not the "fake" explorer.exe instances that are just containers for various Control Panel windows, etc.
So basically the list of instances shown when hovering the mouse over the File Explorer icon on the Taskbar.
How can this be done reliably, and preferably in a way that works in Windows 7 to 11?
Comparing the window title to known strings like "Control Panel" or "Windows Update" has limited value. This would only eliminate the most common cases, and on English versions of Windows only.
I tried looking at the File Explorer window class, but it's "CabinetWClass" in all cases, even for Control Panels.
I noticed that real instances have a child window of class "UIRibbonWorkPane", whereas the Control Panel does not. But the ribbon can be disabled, so this is not a reliable marker.
My script already contains C# declarations encapsulating WIN32 API calls, so C# code snippets would also do.
2021-10-10 update:
The best algorithm I've found so far, building on #simon-mourier's answer, can summarized this way:
$self = $window.Document.Folder.Self
$ClassID = $Self.ExtendedProperty("System.NamespaceCLSID")
$BaseClassID = $Self.Path.Substring(2,38) # With proper tests to clear it if it's not a UUID
$FileExplorerIDs = ( # The few known types which are file systems, but don't set $Self.IsFileSystem
# Windows 10
"f02c1a0d-be21-4350-88b0-7367fc96ef3c", # Network
"679f85cb-0220-4080-b29b-5540cc05aab6", # Quick Access
"20d04fe0-3aea-1069-a2d8-08002b30309d", # This PC
# Windows 7
"031e4825-7b94-4dc3-b131-e946b44c8dd5" # Libraries
)
if ($Self.IsFileSystem) {
$AppType = "File Explorer"
} elseif ($FileExplorerIDs -contains "$ClassID") {
$AppType = "File Explorer"
} elseif ($BaseClassID -eq "{26EE0668-A00A-44D7-9371-BEB064C98683}") {
$AppType = "Control Panel"
} elseif ("{$ClassID}" -eq "{D20EA4E1-3957-11D2-A40B-0C5020524153}") {
$AppType = "Control Panel" # Windows 7 Administrative Tools
} elseif ($Self.Name -eq $Self.Path) { # TODO: Improve this test, which is very weak
$AppType = "Search Results" # Ex: "Search Results in Indexed Locations"
} else {
$AppType = "Unknown"
}
The full algorithm, with the proper precautions to eliminate undefined fields, or invalid values, etc, is implemented in this script:
https://github.com/JFLarvoire/SysToolsLib/blob/master/PowerShell/ShellApp.ps1
One solution is to test whether the Shell Folder (IShellFolder) beneath the Shell View that Windows sends back is handled by the Windows file system or by some custom folder.
For that, you can use the System.NamespaceCLSID Windows property. If the folder associated with the view is handled by the file system, this property value will be the ShellFSFolder GUID value which equal to f3364ba0-65b9-11ce-a9ba-00aa004ae837 (from Windows SDK shobjidl_core.h).
You can test it with something like this in PowerShell:
$ShellFSFolder = [System.Guid]::New("f3364ba0-65b9-11ce-a9ba-00aa004ae837")
foreach($win in (New-Object -com "Shell.Application").Windows()) {
$clsid = $win.Document.Folder.Self.ExtendedProperty("System.NamespaceCLSID")
if ($clsid -ne $null) {
$clsid = [System.Guid]::New($clsid)
if ($clsid -eq $ShellFSFolder) {
Write-Host $win.Document.Folder.Self.Path
}
}
}
And like this in C#:
var ShellFSFolder = new Guid("f3364ba0-65b9-11ce-a9ba-00aa004ae837");
dynamic shell = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
foreach (var win in shell.Windows)
{
var clsid = win.Document.Folder.Self.ExtendedProperty("System.NamespaceCLSID");
if (clsid != null)
{
Guid guid;
if (clsid is byte[] bytes)
{
guid = new Guid(bytes);
}
else
{
guid = new Guid((string)clsid);
}
if (guid == ShellFSFolder)
{
Console.WriteLine(win.Document.Folder.Title); // for example
}
}
}
It seems that only file-path-based File Explorer windows have a non-$null .LocationUrl property value, so you can filter by that:
Caveat: Jean-François reports that this approach doesn't work for Explorer windows that are open to a file-system folder located on a connected smartphone, in which case .LocationUrl is apparently $null too.
$explorerWinsWithFilePaths =
(New-Object -com "Shell.Application").Windows() | Where-Object LocationUrl
To extract the file paths that these windows are displaying (the technique also works with non-file locations such as Quick Access, which translate into ::-prefixed GUIDs):
$explorerWinsWithFilePaths.Document.Folder.Self.Path
See Jean-François' comment below for examples of what windows showing folders on a connected smartphone report.

Jenkins build blocks because of a windows form

We have a .net application where it checks whether the build is on release mode and open up a simple windows form to input the version as a pre build event. I made this form to automatically close in 10 seconds if the user does not give an input. But unfortunately, in Jenkins, the build gets stuck on this step without going forward. So my guess was since Jenkins runs on command line it waits until the user input for continue. But even when I add automatically close the form it does not continue. Is there a way to build this job without UI blocking Jenkins?
You are not using Jenkins in the optimal way. Here are a few tips to help you out:
Get rid of your windows form to increment version
Add a CommonAssemblyInfo.cs in your visual studio solution with an initial version number
Force Jenkins to increment the version automatically [described below]
Commit the file by jenkins using git publisher or using svn.exe with commit flag
Reading Version number using powershell:
param([string]$assemblyInfoPath, [string]$workSpace)
$contents = [System.IO.File]::ReadAllText($assemblyInfoPath)
$versionString = [RegEx]::Match($contents,"(AssemblyFileVersion\("")(?:\d+\.\d+\.\d+\.\d+)(""\))")
Write-Host ("AssemblyFileVersion: " +$versionString)
$version = gc $assemblyInfoPath | select-string -pattern "AssemblyVersion"
$version -match '^\[assembly: AssemblyVersion\(\"(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<revision>[0-9]+)\.(?<build>[0-9]+)\"\)\]'
$BuildVersionNumber = $matches["major"]+"."+$matches["minor"]+"."+$matches["revision"]+"."+$matches["build"]
Write-Host ("WorkSpace: " + $env:WORKSPACE.ToString()+"\version.txt")
#[Environment]::SetEnvironmentVariable("BUILD_NUMBER", $BuildVersionNumber, "Machine")
$path = $env:WORKSPACE.ToString() + "\version.txt"
$BuildVersionNumber | out-file -encoding ASCII -filepath $path
Increment Version using powershell:
#
# This script will increment the build number in an AssemblyInfo.cs file
#
param([string]$assemblyInfoPath, [string]$workSpace)
$contents = [System.IO.File]::ReadAllText($assemblyInfoPath)
$versionString = [RegEx]::Match($contents,"(AssemblyFileVersion\("")(?:\d+\.\d+\.\d+\.\d+)(""\))")
Write-Host ("AssemblyFileVersion: " +$versionString)
#Parse out the current build number from the AssemblyFileVersion
$currentBuild = [RegEx]::Match($versionString,"(\.)(\d+)(""\))").Groups[2]
Write-Host ("Current Build: " + $currentBuild.Value)
#Increment the build number
$newBuild= [int]$currentBuild.Value + 1
Write-Host ("New Build: " + $newBuild)
#update AssemblyFileVersion and AssemblyVersion, then write to file
Write-Host ("Setting version in assembly info file ")
$contents = [RegEx]::Replace($contents, "(AssemblyVersion\(""\d+\.\d+\.\d+\.)(?:\d+)(""\))", ("`${1}" + $newBuild.ToString() + "`${2}"))
$contents = [RegEx]::Replace($contents, "(AssemblyFileVersion\(""\d+\.\d+\.\d+\.)(?:\d+)(""\))", ("`${1}" + $newBuild.ToString() + "`${2}"))
[System.IO.File]::WriteAllText($assemblyInfoPath, $contents)
$version = gc $assemblyInfoPath | select-string -pattern "AssemblyVersion"
$version -match '^\[assembly: AssemblyVersion\(\"(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<revision>[0-9]+)\.(?<build>[0-9]+)\"\)\]'
$BuildVersionNumber = $matches["major"]+"."+$matches["minor"]+"."+$matches["revision"]+"."+$matches["build"]
Write-Host ("WorkSpace: " + $env:WORKSPACE.ToString()+"\version.txt")
#[Environment]::SetEnvironmentVariable("BUILD_NUMBER", $BuildVersionNumber, "Machine")
$path = $env:WORKSPACE.ToString() + "\version.txt"
$BuildVersionNumber | out-file -encoding ASCII -filepath $path
Usage in Jenkins:
Version Format in CommonAssembly: 1.0.0.0
After incrementing: 1.0.0.1
As Tom mentioned in the comments, you should look add the option to start your forms application with a parameter that indicates that the main form should not be shown and some magic should happen. For example, check for a "/s" and let the application run silently if it is present:
MyWinformsApplication.exe /s
Also, as Tom mentioned, a console application can still open a window and this is really useful to have in Jenkins as you can then write insightful messages to the console which will be logged by Jenkins. You can always use these at a later stage to check if something went wrong.
As an additional note - if you add Console.WriteLine() to your WinForms application, Jenkins will pick the string up and add it to the console log.

How to create a .RC file to include version information & icons?

Im a bit new to this stuff. I Want to generate a .rc file that would include Version Information & Also contain Icons in it..
Version Information:
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
{
BLOCK "StringFileInfo"
{
BLOCK "040904b0"
{
VALUE "CompanyName", "JACK Inc.\0"
VALUE "FileDescription", "MyApp\0"
VALUE "FileVersion", "1.0.0.0\0"
VALUE "LegalCopyright", "© 2017 JACK Inc. All Rights Reserved\0"
VALUE "OriginalFilename", "MyApp\0"
VALUE "ProductName", "MyApp\0"
VALUE "ProductVersion", "1.0.0.0\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}
The icons Portion:
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_MYAPP_ICON ICON "icon1.ico"
IDI_MYAPP_ICON_SMALL ICON "icon2.ico"
I already have windows sdk wherein i will use the rc.exe to compile it to a .res file to be used as a Win32Resource in a csproj file . Im only confused on how to correctly script the .rc file to include both of the above contents.. Please Help...
Probably you can generate this.
-------VB6-------
"%ProgramFiles%\Microsoft Visual Studio\VB98\Wizards\rc.exe" /r /fo "Resources.res" "Resources.rc"
-------project.vbp-------
ResFile32="Resources.res"

how debug application using .wer files

I recently submitted application on windows marketplace and got the crashing report in .wer format. but I dont know how to understand the report to find out the problem.I am opening it into notepad but not able to understand anything and I am unable to open it in visual studio 2012.Kindly help
Here is the report content:
Version=1
EventType=MoAppCrash
EventTime=130416971751387322
ReportType=2
Consent=1
UploadTime=130416971751699856
ReportIdentifier=b78d10da-c17e-11e3-8252-2cd05aaed19e
IntegratorReportIdentifier=b78d10d9-c17e-11e3-8252-2cd05aaed19e
WOW64=1
NsAppName=praid:App
Response.BucketId=TestBucket
Response.BucketTable=4
Response.LegacyBucketId=TestBucket
Response.type=4
Sig[0].Name=Package Full Name
Sig[0].Value=14665AAQ.AAQ_1.0.3.11_neutral__mqjtjzf78eaaj
Sig[1].Name=Application Name
Sig[1].Value=praid:App
Sig[2].Name=Application Version
Sig[2].Value=1.0.0.0
Sig[3].Name=Application Timestamp
Sig[3].Value=5347e402
Sig[4].Name=Fault Module Name
Sig[4].Value=combase.dll
Sig[5].Name=Fault Module Version
Sig[5].Value=6.3.9600.16520
Sig[6].Name=Fault Module Timestamp
Sig[6].Value=52e6927e
Sig[7].Name=Exception Code
Sig[7].Value=800f1000
Sig[8].Name=Exception Offset
Sig[8].Value=0007fd17
DynamicSig[1].Name=OS Version
DynamicSig[1].Value=6.3.9600.2.0.0.256.48
DynamicSig[2].Name=Locale ID
DynamicSig[2].Value=1033
DynamicSig[22].Name=Additional Information 1
DynamicSig[22].Value=896a
DynamicSig[23].Name=Additional Information 2
DynamicSig[23].Value=896a5d446a93e35895a2b8d22860148e
DynamicSig[24].Name=Additional Information 3
DynamicSig[24].Value=0488
DynamicSig[25].Name=Additional Information 4
DynamicSig[25].Value=04885d6165bbbf9c1e9404f1069bd19d
UI[2]=C:\Program Files\WindowsApps\14665AAQ.AAQ_1.0.3.11_neutral__mqjtjzf78eaaj\AskAQuestion.exe
LoadedModule[0]=C:\Program Files\WindowsApps\14665AAQ.AAQ_1.0.3.11_neutral__mqjtjzf78eaaj\AskAQuestion.exe
LoadedModule[1]=C:\Windows\SYSTEM32\ntdll.dll
LoadedModule[2]=C:\Windows\SYSTEM32\MSCOREE.DLL
LoadedModule[3]=C:\Windows\SYSTEM32\KERNEL32.dll
LoadedModule[4]=C:\Windows\SYSTEM32\KERNELBASE.dll
LoadedModule[5]=C:\Windows\SYSTEM32\ADVAPI32.dll
LoadedModule[6]=C:\Windows\SYSTEM32\msvcrt.dll
LoadedModule[7]=C:\Windows\SYSTEM32\sechost.dll
LoadedModule[8]=C:\Windows\SYSTEM32\RPCRT4.dll
LoadedModule[9]=C:\Windows\SYSTEM32\SspiCli.dll
LoadedModule[10]=C:\Windows\SYSTEM32\CRYPTBASE.dll
LoadedModule[11]=C:\Windows\SYSTEM32\bcryptPrimitives.dll
LoadedModule[12]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
LoadedModule[13]=C:\Windows\SYSTEM32\SHLWAPI.dll
LoadedModule[14]=C:\Windows\SYSTEM32\combase.dll
LoadedModule[15]=C:\Windows\SYSTEM32\USER32.dll
LoadedModule[16]=C:\Windows\SYSTEM32\GDI32.dll
LoadedModule[17]=C:\Windows\system32\IMM32.DLL
LoadedModule[18]=C:\Windows\SYSTEM32\MSCTF.dll
LoadedModule[19]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
LoadedModule[20]=C:\Windows\SYSTEM32\MSVCR120_CLR0400.dll
LoadedModule[21]=C:\Windows\SYSTEM32\kernel.appcore.dll
LoadedModule[22]=C:\Windows\SYSTEM32\ole32.dll
LoadedModule[23]=C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\ebdd49343f711b2029293f8e621b28a2\mscorlib.ni.dll
LoadedModule[24]=C:\Windows\System32\twinapi.appcore.dll
LoadedModule[25]=C:\Windows\System32\WinTypes.dll
LoadedModule[26]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
LoadedModule[27]=C:\Windows\SYSTEM32\OLEAUT32.dll
LoadedModule[28]=C:\Windows\System32\Windows.UI.Xaml.dll
LoadedModule[29]=C:\Windows\SYSTEM32\UIAutomationCore.DLL
LoadedModule[30]=C:\Windows\SYSTEM32\NInput.dll
LoadedModule[31]=C:\Windows\SYSTEM32\WININET.dll
LoadedModule[32]=C:\Windows\SYSTEM32\d3d11.dll
LoadedModule[33]=C:\Windows\SYSTEM32\dwmapi.dll
LoadedModule[34]=C:\Windows\SYSTEM32\UxTheme.dll
LoadedModule[35]=C:\Windows\SYSTEM32\XmlLite.dll
LoadedModule[36]=C:\Windows\SYSTEM32\SHELL32.dll
LoadedModule[37]=C:\Windows\SYSTEM32\urlmon.dll
LoadedModule[38]=C:\Windows\SYSTEM32\TWINAPI.dll
LoadedModule[39]=C:\Windows\SYSTEM32\iertutil.dll
LoadedModule[40]=C:\Windows\SYSTEM32\dxgi.dll
LoadedModule[41]=C:\Windows\SYSTEM32\shcore.dll
LoadedModule[42]=C:\Windows\SYSTEM32\CRYPTSP.dll
LoadedModule[43]=C:\Windows\system32\rsaenh.dll
LoadedModule[44]=C:\Windows\SYSTEM32\bcrypt.dll
LoadedModule[45]=C:\Windows\SYSTEM32\actxprxy.dll
LoadedModule[46]=C:\Program Files (x86)\Common Files\microsoft shared\ink\tiptsf.dll
LoadedModule[47]=C:\Windows\SYSTEM32\dwrite.dll
LoadedModule[48]=C:\Windows\SYSTEM32\igd10iumd32.dll
LoadedModule[49]=C:\Windows\SYSTEM32\ncrypt.dll
LoadedModule[50]=C:\Windows\SYSTEM32\NTASN1.dll
LoadedModule[51]=C:\Windows\SYSTEM32\igdusc32.dll
LoadedModule[52]=C:\Windows\SYSTEM32\d2d1.dll
LoadedModule[53]=C:\Windows\SYSTEM32\dcomp.dll
LoadedModule[54]=C:\Windows\SYSTEM32\MrmCoreR.dll
LoadedModule[55]=C:\Windows\SYSTEM32\Bcp47Langs.dll
LoadedModule[56]=C:\Windows\SYSTEM32\profapi.dll
LoadedModule[57]=C:\Windows\System32\Windows.UI.dll
LoadedModule[58]=C:\Windows\assembly\NativeImages_v4.0.30319_32\System\8455c031f8ffe82a0109c563873260e8\System.ni.dll
LoadedModule[59]=C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Runt0d283adf#\e209e80a78aee1367c92f1dd884d8f58\System.Runtime.WindowsRuntime.ni.dll
LoadedModule[60]=C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Runtc259d85b#\00fd6b9fc7353b024079f65164bdc73f\System.Runtime.WindowsRuntime.UI.Xaml.ni.dll
LoadedModule[61]=C:\Windows\System32\Windows.ApplicationModel.dll
LoadedModule[62]=C:\Windows\system32\windowscodecs.dll
LoadedModule[63]=C:\Windows\SYSTEM32\PhotoMetadataHandler.dll
LoadedModule[64]=C:\Windows\SYSTEM32\PROPSYS.dll
LoadedModule[65]=C:\Windows\SYSTEM32\oleacc.dll
LoadedModule[66]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\diasymreader.dll
State[0].Key=Transport.DoneStage1
State[0].Value=1
FriendlyEventName=Stopped working
ConsentKey=MoAppCrash
AppName=14665AAQ.AAQ_mqjtjzf78eaaj!App
AppPath=C:\Program Files\WindowsApps\14665AAQ.AAQ_1.0.3.11_neutral__mqjtjzf78eaaj\AskAQuestion.exe
NsPartner=windows
NsGroup=windows8
ApplicationIdentity=254467B9963B346A2B88CAE91E846F7F
You can't debug application crashes with this .wer files.
The only useful information is the error code 800f1000:
C:\Users\André>err 800f1000
# for hex 0x800f1000 / decimal -2146496512
SPAPI_E_ERROR_NOT_INSTALLED winerror.h
# No installed components were detected.
# 1 matches found for "800f1000"
You need a dmp file which you can get from the Quality Reports page and debug it.

Powershell change taskbar icon of running console application

I'm using code from this post over at Microsoft's TechNet to change the icon of my running PowerShell application. This works great for the icon that is displayed in the Powershell window itself, but it doesn't change the Taskbar's icon. I changed the function a bit an hoped that it would also change the icon displayed in the Taskbar.
# Set the icon of the current console window to the specified icon.
#
# AUTHOR: Aaron Lerch <http://www.aaronlerch.com/blog>
# COPYRIGHT: © 2009 Aaron Lerch
# LINK: http://gallery.technet.microsoft.com/scriptcenter/9d476461-899f-4c98-9d63-03b99596c2c3
#
# PARAM:
# -IconFile
# Absolute path to the icon file.
# RETURN:
# $null
function Set-ConsoleIcon {
Param(
[parameter(Mandatory = $true)] [string] $IconFile
)
[System.Reflection.Assembly]::LoadWithPartialName('System.Drawing') | Out-Null
# Verify the file exists
if ([System.IO.File]::Exists($iconFile) -eq $true) {
$ch = Invoke-Win32 'kernel32' ([IntPtr]) 'GetConsoleWindow'
$i = 0;
$size = 16;
while ($i -ne 4) {
$ico = New-Object System.Drawing.Icon($iconFile, $size, $size)
if ($ico -ne $null) {
Send-Message $ch 0x80 $i $ico.Handle | Out-Null
}
if ($i -eq 4) {
break
}
$i += 1
$size += 16
}
}
else {
Write-Host 'Icon file not found' -ForegroundColor 'Red'
}
}
I'm providing the icon in the sizes 16 (wParam 1), 32 (wParam 2), 48 (wParam 3), and 64 (wParam 4).
I also tried to change the Icon from my launching C# application (based on this Stackoverflow discussion) but that didn't work at all.
If you'd like to see the complete code have a look at the following:
the C# class that starts the Powershell process
the Powershell PS1 script
This might not be possible. Here are more details about the "group icon" in the taskbar:
Change icon of group in taskbar (Win7)
Update:
You can change the application ID of your window. Since the icon primarily comes from the application ID, by changing it Explorer doesn't know the default icon anymore and will use the actual window icon. This also ungroups the window from other CMD windows to make the individual icon visible at all. (There's a taskbar animation like for closed/new windows when you do this in an existing console window.) There's an MSDN article, look for "application ID" in it:
https://msdn.microsoft.com/en-us/magazine/dd942846.aspx
Here's the relevant code from it (C++):
#define WINVER 0x601
#define _WIN32_WINNT 0x601
#include <Propvarutil.h>
#include <propkey.h>
#include <Shellapi.h>
PROPVARIANT pv;
InitPropVariantFromString(L"MyAppID", &pv);
IPropertyStore* pps;
VERIFY(SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps)));
VERIFY(pps->SetValue(PKEY_AppUserModel_ID, pv));
VERIFY(pps->Commit());
(Linked libs: shlwapi.lib)
The Windows API Code Pack should also have managed wrapper code for this. Didn't look it up because I currently use this function in a C++ application. But I found other questions about it here.
For your PowerShell script that probably won't help much either. Since it's all native code wrapped with more complex managed code, I think your best bet would be a little native helper tool. I am currently integrating this function into my FlashConsoleWindow tool that can do some more things to console windows like flashing or displaying a taskbar progress state.
An easy alternative is to create a shortcut to the powershell exe. Change the icon of the shortcut to whatever you want.
Then whenever you call your script, use the shortcut instead of the PS exe. So instead of
powershell.exe -ExecutionPolicy Bypass -File D:\scripts\whatever.ps1
Use
D:\scripts\powershell.lnk -ExecutionPolicy Bypass -File D:\scripts\whatever.ps1
The shortcut powershell.lnk can be "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" or just powershell.exe without the full path (as long as PATH var is set properly for PS on the system)
You can put the PS shortcut anywhere really, but I would recommend you put it with the script for portability.
Now when you launch the script via the shortcut, the taskbar icon will be whatever you defined it as via the shortcut file.
The only caveat is that your window settings in the shortcut will override the PS window, so you should define how you want it to look in the shortcut properties.

Categories

Resources