Visual Studio 2010 Setup Project marks application as requiring elevation - c#

EDIT: I would still like an answer to this question if anyone can provide one, however I have decided to split out the non-administrative part of this project into another project which will call this project as required.
I have a project which manipulates some registry keys under HKLM - which obviously requires elevation. The application knows when it needs this elevation and will re-launch itself with runas to get elevation.
In the development environment this works fine, and the application also runs fine on intended targets in this form.
When I pump the project through a VS2010 setup project and install the project on the target system, the EXE gets marked as requiring elevation and requests it whenever it gets run before the application logic determines if it needs it.
I have searched for an hour or so and found nothing which relates, though I suspect the power of my search terms is insufficiently strong (or I lack the right ones) to find an appropriate result.
How can I stop the setup project from marking the executable as requiring elevation?
Subsequent to the comment below I added a custom manifest to the project with the same result, the manifest looked right to me:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<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">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
</application>
</compatibility>
</asmv1:assembly>
Here's the output of the project's build (in the obj folder since that's what's being pulled in by the setup project):
http://i.stack.imgur.com/elrQh.png
The outwardly obvious thing is the lack of the UAC shield on the executable. After building the setup project, then installing it via the resultant MSI, the installed executable is like this:
http://i.stack.imgur.com/A33qz.png
Noting the now existing UAC shield.
Before adding the custom manifest, it was set to use a default one (which I suspect has the same content).

Related

How to handle talking to VB6 ActiveX dll that has OCX dependencies from a .NET WPF application

I have a VB6 ActiveX dll that has a dependency on ComDlg32.ocx. This ActiveX dll is called from a .NET application.
The ActiveX dll has a public interface that has 1 method, which opens a form, which opens an Open File dialog (from ComDlg32.ocx). The .NET application has a button which will call this ActiveX dll method.
This all works when the ComDlg32.ocx and the ActiveX dll are both registered (via regsvr32), but I need to get this to work using RegFree COM, at least for the dependencies of the ActiveX dll. I have made a manifest file for this ActiveX dll but it doesn't seem to be getting read. ProcMon had no reference to the manifest file and sxstrace gave me no info (literally a blank text file when I parsed the etl file).
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity name="DeployArchitectureTest" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<file name="COMDLG32.OCX">
<typelib tlbid="{F9043C88-F6F2-101A-A3C9-08002B2F49FB}" version="1.2" flags="control,hasdiskimage" helpdir="" />
<comClass clsid="{F9043C85-F6F2-101A-A3C9-08002B2F49FB}" tlbid="{F9043C88-F6F2-101A-A3C9-08002B2F49FB}" progid="MSComDlg.CommonDialog.1" threadingModel="Apartment" miscStatus="" miscStatusContent="recomposeonresize,onlyiconic,cantlinkinside,insideout,activatewhenvisible,invisibleatruntime,setclientsitefirst">
<progid>MSComDlg.CommonDialog</progid>
</comClass>
</file>
</assembly>
I have tried an external manifest for the dll as well as embedding the manifest but still no luck. I must be missing something but all the information I can find talks about how to create a manifest file for an exe but no info about how to handle an ActiveX dll that has its own dependencies.
If anyone has any information then I would really appreciate it.
After some more research and being pointed in the right direction by #SimonMourier and #HansPassant, I managed to get this working.
I thought that a dll manifest would have been possible if I was using the resource ID #2 as #HansPassant mentioned, but I wasn't able to get it to work that way. No matter what I did, the dll manifest never seemed to be read.
I did however find that including all of the manifest data from what was the dll manifest into the exe manifest and making sure the exe had no embedded manifest allowed RegFree COM to work as expected. I was finding that Visual Studio was building my .NET exe with an embedded manifest, even though there was an app.manifest file as part of the project. I had to set the COM dll as 'isolated=true' in order for the manifest to be built as external.
So thank you both #SimonMourier and #HansPassant, both of your comments led me down the right path to figure it out.

Elevate permissions for exe permanently

I have built an installer for my application with wix. I am also using an automatic updater so the user can update the software. The problem I am having is for the updater to work it needs to run its exe and close my application and restart my application after it has finished. When the updater starts up, it needs elevated permissions to run. I am wondering if there is a way to permanently grant the updater exe elevated permissions on install since it has to be installed by an administrator to begin with, saving the administrator from being present every time an update needs to be done?
It would be nice for the user to click update and not have to bother their IT department to get an updated version of our software.
Without being a member of the windows build team you only have two options
Start your program from another program that was already running that has administrator privileges
Make it so your update process does not require administrative privileges.
The only real way to perform #1 is to have a windows service that runs in the background and executes the downloaded update package as an administrative user, this process is hard to do "right" without leaving security holes in the end users system that malware (or users that want to get around IT's restrictions) could exploit.
Option #2 is the better option, and is what many popular software packages use. The way to accomplish this is to either change the permissions of your folder inside ProgramFiles to allow the Authenticated Users group to have write privileges. This is not the optimal solution but likely the easiest to implement. Another way to accomplish this is install the updateable resources in to a folder that your user has write access to by default, for example the %LocalAppData% folder (which is what Chrome does (I think) and any applications deployed with ClickOnce)
You need to add a manifest to every executable that always needs to run elevated. Here is a sample app.manifest file:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplicationName" />
<description>My application description.</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 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}" />
</application>
</compatibility>
</asmv1:assembly>
The relevant setting for this in the manifest is:
level="requireAdministrator"
You just need to add an app.manifest file to your project, and then set the manifest in the Properties tab for the project to the new file instead of using the default manifest generated by the compiler.
The Windows account running the process still requires administrative privileges however for the process to run with these privileges.

"Run as administrator" option doesn't shows up in the context menu in Explorer

I'm using VS2012 WPF Application & Install-shield 2013 LE to generate the installer.
After the installation I noticed that "Run as administrator" option doesn't shows up in the context menu in Explorer of the desktop icon.
Some of the user couldn't run the application but they can run the application by getting into the installed dir and right click on the icon, Run as administrator.
I checked in this link :http://msdn.microsoft.com/en-us/library/ms247046.aspx then I added the option: "Embed manifest with default settings" and regenerated the installer. But it didn't make any change.
I'm making a test on Win 7 OS 32bit.
How can i enable the option "Run as administrator" when i right click on application icon in the context menu in Explorer?
Same problem like this question: VS 2010 setup shortcut file not shows Run as Administrator option
app.manifest:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<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 node will disable file and registry virtualization.
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of all Windows versions that this application is designed to work with.
Windows will automatically select the most compatible environment.-->
<!-- If your application is designed to work with Windows Vista, uncomment the following supportedOS node-->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- If your application is designed to work with Windows 8, uncomment the following supportedOS node-->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>
</application>
</compatibility>
<!-- 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>
</asmv1:assembly>
Edited:
I figured it out that the InstallShield 2013 LE(Limited Edition) is not allowing me to put the target directioy like this : "C:\ProgramFiles\TestUtility.exe". If the target refer to exe, then the 'Run as Administrator' will be enabled automatically.
Original:
It should be like this:
So, InstallShield LE is doesn't allow me to change that.
I have to find another way to generate the installer. Any suggestion please?
I finally found why the 'Run as Administrator' is not enabled. When an installed icon is not referred to .exe it won't be available.
On top of this InstalShield 2013 LE version doesn't allow to change the "Target Directory" value.
Link: http://community.flexerasoftware.com/showthread.php?206542-Permissions-setting-to-edit-within-directory
It's important to refer the .exe; why? the user can run the application as an Administrator through Windows Explorer Context Menu.
I decided to go with WIX installer.
Please give me your FB.
I found this after I posted this answer.
Essentially, you need to disable "advertised links" in the msi. My answer is a composite answer from other sources that does this in the msi build schema thus making it a single fix for all your projects.
It's tested and works on Windows Pro 64bit.

Program not asking for administrator rights, while already using a manifest

My program is not asking for administrator privileges while I do have a manifest file included in my project, I loaded it correctly, it just simply doesnt want to fix the error I have in my code. I'll post the manifest file, but I'm almost sure its fine:
<?xml version="1.0" encoding="utf-8"?>
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
</application>
</dependentAssembly>
</dependency>-->
These are the settings I am using in my project:
The error I am getting:
Translated it says:
"Win32 Exception was unhandled, Not all privileges or groups referenced are assigned to the caller."
Can I have any help, so I can make my program ask for administrator privileges so it can run correctly?
You'll need to modify <requestedExecutionLevel>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
See here: How do I force my .NET application to run as administrator?

How to detect if a DLL is installed/available

What's the most effective way to detect if a DLL is installed in C#?
I'm interessed in this one: msvcr80.dll. I tried to call LoadLibrary interop API call from a C# program, but it didn't work. I just need to detect it, and not make use of it.
Pinvoking msvcr80.dll is difficult. It is a special DLL, it is stored in the Windows side-by-side cache (c:\windows\winsxs) and there are usually many versions installed on a machine. I've got 16 of them on this machine. The side-by-side cache is the equivalent of the GAC for unmanaged DLLs. Using such a DLL in your code requires a manifest that states what specific version of msvcr80.dll you want to use.
So the first thing you have to do is add the entry to your own program's manifest. Project + Add New Item, select the Application Manifest item template. You will have to edit it to include the dependency on msvcr80.dll. Your manifest ought to look like this:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<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">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.6195" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</asmv1:assembly>
Note the version attribute, 8.0.50727.6195 is the latest right now. Other common revisions out in the wild are 42 (the original RTM version) and 762 (the SP1 version) and a raft of security updates. You can typically use .42 in your manifest, publisher policy files deployed by the updates will redirect to the latest installed version on the machine.
Also note the processorArchitecture attribute, you'll need "amd64" if you want to use the 64-bit version of the DLL. It is best to stick with x86 and ensure your program runs in 32-bit mode. Right-click your EXE project, Properties, Build tab, Platform target = x86.
You can now use a [DllImport] to call a function from the DLL. Like:
[DllImport("msvcr80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr _errno();
I intentionally picked an innocent function that doesn't do anything useful. So that you can pinvoke it to test if the DLL with the required version number is installed. Catch the exception to know that it isn't there. If you want to do it without the exception then pinvoke LoadLibrary().
I'm going to guess that you didn't quite count on these complications. An entirely different approach is to use the equivalent DLL that's used by Windows code. Which is fine as long as you don't try to pinvoke "unusual" functions. Every install of Windows has msvcrt.dll, no need to check it for its presence and no need for the manifest. Just change the DLL name in the [DllImport] attribute. But do beware that you take the risk that your program might break someday when Microsoft significantly alters this private copy of the CRT.
You need to check both the directories under the PATH environment variable, and the Global Assembly Cache, which is best done using this API.

Categories