Change property (msi) in managed bootstrapper (wpf)? - c#

A have a WPF Setup Application. I Have TextBox that binds to a Property ProductCode in my ViewModel.
How can I make the packages to be set "DEF" property in .msi project?
My code:
WPF:
private void InstallExecute()
{
InstallEnabled = false;
Bootstrapper.Engine.StringVariables["ABC"] = "zyx";
MainWindowViewModel.PlanAction(LaunchAction.Install);
}
Bootstrapper:
<Variable Name="ABC" bal:Overridable="yes" />
<MsiProperty Name="DEF" Value="[ABC]"/>
.MSI:
<Property Id="DEF" />
Project with Action:
var test = session["DEF"].ToString(); //always gives empty string

You need to specify the MsiProperty like this inside your bundle:
<MsiPackage Id='MyApp' Description='My Application' SourceFile="$(var.SetupMyApp.TargetPath)">
<MsiProperty Name="INSTALLFOLDER" Value="[MyAppInstallLocation]"/>
</MsiPackage>
Add a burn variable for it, also in the bundle:
<Variable bal:Overridable="yes" Name="MyAppInstallLocation" Value=""/>
And then
Bootstrapper.Engine.StringVariables["MyAppInstallLocation"] = "C:\MyApp";
somewhere in your bootstrapper, obviously before you start the install.

Related

Add external font failed but for all fonts

So i try to add external font int my application using this post
Steps:
Add a /Fonts folder to your solution.
Add the True Type Fonts (*.ttf) files to that folder
Include the files to the project
Select the fonts and add them to the solution
Set BuildAction: Resource and Copy To Output Directory: Do not copy. Your .csproj file should now should have a section like this one:
<ItemGroup>
<Resource Include="Fonts\NotoSans-Bold.ttf" />
<Resource Include="Fonts\NotoSans-BoldItalic.ttf" />
<Resource Include="Fonts\NotoSans-Italic.ttf" />
<Resource Include="Fonts\NotoSans-Regular.ttf" />
<Resource Include="Fonts\NotoSansSymbols-Regular.ttf" />
</ItemGroup>
In App.xaml add Resources. It should look like in the following code sample. Note that the URI doesn't contain the filename when packing with the application.
<Applicaton ...>
<Application.Resources>
<FontFamily x:Key="NotoSans">pack://application:,,,/Fonts/#Noto Sans</FontFamily>
<FontFamily x:Key="NotoSansSymbols">pack://application:,,,/Fonts/#Noto Sans Symbols</FontFamily>
</Application.Resources>
</Application>
Apply your Fonts like this:
<TextBlock x:Name="myTextBlock" Text="foobar" FontFamily="{StaticResource NotoSans}"
FontSize="10.0" FontStyle="Normal" FontWeight="Regular" />
So i download several fonts but this works only for some of them.
Any ideas?

How to update a windows form app (via LAN) using c#?

I have a simple windows form application which I want to enable auto update feature (without using any third party app), so I add this code to the Form Load event of the app (the form has a label called label1 and its text is in the form v1.1)
XDocument doc=XDocument.Load(#"\\PC-10\TEST Update\share\checkver.xml");
double chkver=Convert.ToDouble(doc.Descendants("version").First().Value);
double currver=Convert.ToDouble(label1.Text.Substring(1,3));
if (chkver>currver) {
string exePath = Application.ExecutablePath;
string x=exePath.Substring(0,exePath.Length-10)+"\\updater.exe";
Process.Start(x);
this.Close();
}
The checkver.xml is a xml file located on the same folder as the updated myapp.exe and the updater.exe is located on the folder where the actual running app myapp.exe is i.e. Program Files
checkver.xml:
<?xml version="1.0"?>
<myapp>
<version>1.2</version>
</myapp>
updater.exe:
Console.WriteLine("Updating the app...please wait!");
string exePath = System.Reflection.Assembly.GetEntryAssembly().Location;
string x=exePath.Substring(0,exePath.Length-12);
File.Copy(#"\\PC-10\TEST Update\share\myapp.exe", x+"\\myapp.exe",true);
Console.WriteLine("Update completed!");
Process.Start(x+"\\myapp.exe");
When I run this from the actual projects bin folder it runs fine but when I create a setup file and install it on Program Files I get an error
System.UnauthorizedAccessException: Access to the path ...
and a message updater has stopped working.
Why is this happening?
Also is there a way to make this process faster(specially the update checking part)?
First thing I would do is check if myapp.exe is running with elevated privileges or not:
private static bool IsAdministrator()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
Run updater.exe.
if(IsAdministrator())
{
//.......
if (chkver>currver)
{
string exePath = Application.ExecutablePath;
string x=exePath.Substring(0,exePath.Length-10)+"\\updater.exe";
ProcessStartInfo info = new ProcessStartInfo(x);
info.UseShellExecute = true;
info.Verb = "runas";
Process.Start(info);
Environment.Exit(1); //Use .Exit(1) instead of this.Close();
}
}
I simply added a app.manifest file to my project like below
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
-->
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>
It seems to solve the issue I had...but not 100% sure whether it is the right solution....

Visual Studio Extensions: Adding element to the Code Editor ContextMenu

I'm trying to add a new element to the Visual Studio 2017 Context Menu. I managed to add an element to the TOOLS menu with the following code:
<Button guid="guidRandomCommandPackageCmdSet" id="RandomCommandId" priority="0x0100" type="Button">
<Parent guid="guidSHLMainMenu" id="IDG_VS_TOOLS_EXT_TOOLS" />
<Icon guid="exclamationIcon" id="exclamationIcon1" />
<Strings>
<ButtonText>Random Text</ButtonText>
</Strings>
</Button>
which is registered in
<GuidSymbol name="guidRandomCommandPackageCmdSet" value="{47122772-c66f-48f3-b10b-dbbb66da120d}">
.
.
<IDSymbol name="RandomCommandId" value="0x0100" />
</GuidSymbol>
I tried to follow a similar fashion, so I defined a new Button in Buttons:
<Button guid="guidRandomCommandPackageCmdSet" id="ToDoList" priority="0x0100" type="Button">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/>
<Icon guid="exclamationIcon" id="exclamationIcon1" />
<Strings>
<ButtonText>Add TODO list</ButtonText>
</Strings>
</Button>with the ID symbol
with the ID registerd in GuidSymbols
<IDSymbol name="ToDoList" value="0x106" />
But the button does not show up in the context menu, when I run the project. I tried to follow the suggestions of VSIX: Adding a Menu Item to the Visual Studio Editor Context Menu but none of the suggestions seems to work for me.
I never tried to create a VS add-on before, so I welcome any suggestions. Is it possible that the method changed in VS 2017?
Eventually, I managed to get it working. It seems that while for MENU items that show up either as a separate menu or belonging to a menu like TOOLS, it is enough to have only a Button with the parent set to the appropriate constant menu element string as defined at GUIDs and IDs of Visual Studio Menus.
For ContextMenu elements, however, I needed to have an element in Groups:
<Group guid="guidRandomCommandPackageCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" />
</Group>
This has the ContextMenu as its Parent. Then, I created a CustomCommand that auto-generates a Button with it and I modified this Button to have the Group element as itsParent:
`
Add TODO list
This is the result with the added button hovered over:

Outllook 2016 - VSTO plugin - clicking on Ribbon controls causes outlook crash

Clicking on custom ribbon control causes outlook to crash.
The Event listener for the control never gets invoked.
Reproducible for all types of Ribbon controls - RibbonButton, RibbonCheckbox.
RibbonType - "Microsoft.Outlook.Mail.Read" reproducible for others too.
Problem specific to Outlook 2016, not reproducible for 2013.
Outlook version number: 16.0.7167.2040 (latest - part of Office 365)
Steps to reproduce:
Create New project - "Outlook 2013 and 2016 VSTO add-in".
Add New Ribbon using designer. (default type is mail read ribbon).
Add new button - "Important Button" and register listener.
Run -> Outlook -> Home -> Add-Ins -> click "Important Button"
Have checked offCat confing and live loggin - nothing there.
Any pointers on what I am missing here? Any pointers on how to find what exactly is going wrong.
Edit:
Found this in Event Log under Windows Logs -> Applications
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Application Error" />
<EventID Qualifiers="0">1000</EventID>
<Level>2</Level>
<Task>100</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2016-09-06T04:51:22.000000000Z" />
<EventRecordID>247449</EventRecordID>
<Channel>Application</Channel>
<Computer>USER</Computer>
<Security />
</System>
- <EventData>
<Data>OUTLOOK.EXE</Data>
<Data>16.0.7167.2040</Data>
<Data>57ad490b</Data>
<Data>mso40uiwin32client.dll</Data>
<Data>0.0.0.0</Data>
<Data>57ab7885</Data>
<Data>c0000005</Data>
<Data>000ce501</Data>
<Data>107c</Data>
<Data>01d207f98604f7ee</Data>
<Data>C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLOOK.EXE</Data>
<Data>C:\Program Files (x86)\Common Files\Microsoft Shared\Office16\mso40uiwin32client.dll</Data>
<Data>8e19d2e5-73ed-11e6-8343-34e6d7290fdd</Data>
<Data />
<Data />
</EventData>
</Event>
I am agree with Shyam sundar shah.It will be better to use Ribbon(xml).
you can modify the ribbon.xml like this.
<?xml version="1.0" encoding="UTF-8"?>
<customUI onLoad="Ribbon_Load" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tab idMso="TabNewMailMessage">
<group id="ImportantGroup" label="Important Group" insertAfterMso="GroupIncludeMainTab">
<button id="ImportantButton" label="Important Button" onAction="ImportantButton_Click"/>
</group>
</tab>
</ribbon>
</customUI>

Custom section in App.Config: How to realize this structure in C#?

I have created a custom configuration section for my App.Config file, right now it looks like this:
<mySection>
<myCollection>
<element name="1" />
<element name="2" />
</myCollection>
</mySection>
As the naming suggests, I have classes inherited from ConfigurationSection (MySection), ConfigurationElementCollection (MyCollection with AddItemName="element" set in the attributes of MySection), and ConfigurationElement. But I wonder how I can realize a structure similar to the following:
<mySection>
<myElements>
<element name="1" />
<element name="2" />
<additionalInfo>"..."</additionalInfo>
</myElements>
<someOtherSetting option="blub" />
</mySection>
Can I still use ConfigurationElementCollection for MyElements or do I have to use something else, as there is not just the element tag (specified by AddItemName="element" in the MySection class), but also another one? If not, what is the class to use here?
And I guess having something between the tags has to just correspond to a property of some AdditionalInfo class, so that it'd be equivalent to the following?
<additionalInfo content="..." />
As for someOtherSetting I guess I could just add another property to MySection corresponding to this, but I didn't get to testing that yet.

Categories