How to move a ClickOnce deployment package - c#

I have a collection of ClickOnce packages in a publish folder on a network drive and need to move them all to another server (our DR machine).
After copy/pasting the whole directory and running the setups on the new machine I get an error message stating that it cannot find the old path:
Activation of
...MyClickOnceApp.application resulted
in exception. Following failure
messages were detected:
+ Downloading file://oldMachine/c$/MyClickOnceApp.application did not succeed.
+ Could not find a part of the path '\\oldMachine\c$\MyClickOnceApp.application'.
Once I change the installation URL to point at my new machine, I get another error:
Manifest XML signature is not valid.
+ The digital signature of the object did not verify.
I've tried using MageUI.exe, to modify the deployment URL, but it asks for a certificate, which I don't have.
What am I doing wrong and how do I successfully move published ClickOnce packages?

I found a solution:
Firstly, using MageUI, I changed the "Start Location" under "Deployment Options". On saving, it prompted me to sign with a key, which I created there and then. I then ran the setup.exe file, and it worked without fail.
After checking which files had changed, I realised it was only the one file: the application manifest file (myAppName.application). The only things that changed in the file were the deployment provider and the signature (which is what I changed in MageUI).
Once I realised this was how to do it, I used the command line version of MageUI called Mage.exe, which comes with the SDK.
Below is the batch file I created to do all of this on the command line:
REM Set the enviroment
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
REM Update the deployment provider URL
mage -Update %1.application -pu %2
REM Sign the manifest with our key
mage -Sign %1.application -CertFile C:\AppKey.pfx -Password myPw
I can now use this to run against all of my published applications in a quick and easy way. I hope this helps.

Without getting into too much detail, this should get you going.
ClickOnce manifests must be signed with a certificate for security reasons. You can purchase a code signing certificate or generate a test one. The main drawback of a test certificate is that your application publisher will appear as "Unknown" rather than your company's name.
In Visual Studio, open your project's properties and go to the "Signing" tab, select "Sign the ClickOnce manifests", and "Create Test Certificate". Next, click "More Details" to bring up a dialog and click "Install Certificate". This will run you through a wizard to get your test cert in your store. Make sure you put it in the "Personal" store.
Now you can use MageUI to edit your manifests. Any time you save it will prompt you to sign the manifests but you should now be able to select the test cert you just stored. Always edit/sign the application manifest before editing/signing the deployment manifest. This is confusing because the application manifest isn't the file with the .application extension.
Good luck!

I would expect to have to do the following:
Copy current folder contents to new location
For each app:-
Change 'Installation folder' to the new location
Publish as a new version
Change 'Publishing folder' to the new location
Publish as a new version
New setups run from the new folder should work and existing ones should update to look in the correct place.
All this is untested, but I'm pretty sure that's what I did previously...
Edit:
Obviously, you'll have to run these in parallel for a certain amount of time, but as it's an internal app the worst that will happen when you finally switch over to the new location is that you'll have to inform the user of the new location to obtain a 'fixed' app

I believe that you do have a certificate. You need one to create a ClickOnce deployment. Visual Studio may have autocreated a self-signed one for you. I'm not too familiar with the process, hopefully someone with a more definitive answer will chip in. Also, have you tried the MageUI tool, maybe it will be more obvious what you need to do using a GUI.

Related

App.Config on Winforms is getting reinstalled

I have a windows application installed and working perfectly fine.
Something weird came up, the test scenario is if I rename the config file from the original name which is:
Model Label PC Client.exe.config
...to:
xxxModel Label PC Client.exe.config
...and click the .EXE file on the application folder / path where i installed it, it works as expected.
But when I clicked the shortcut icon of this application on the desktop, it shows a pop up that installs a new copy of the correct config file name.
please refer to the screenshot , any idea how to prevent this from happening? or is this really the behavior?
OP:
"any idea how to prevent this from happening?"
For installed apps, it is by design. Essentially you have removed an installed file and so the installer tech will kick in to recover it as if nothing happened.
Now technically you could get around that auto-recovery by not using MSI tech to install your app trusting instead on good-ol' XCOPY but then again, renaming/moving/deleting the file may break the app because this time there is no auto-recovery!
Additionally .NET apps expect to find a .config file matching the same name as the executable so you shouldn't go renaming/deleting/moving it in most scenarios.

Windows installer forbid certain install locations

Have an msi file that is run by the user manually. They need to be able to choose the install directory in most cases however we need to forbid certain install locations. E.g. Installing it to the root directory C:\ will cause all kinds of problems, so we need to either overwrite that decision (i.e. overwrite C:\ with C:\Program Files (x86)\xxx) or pop up with an error. Is there some way I can enforce this?
The msi in question has custom actions already however there doesn't seem to be a way to edit the install location from there.
Alternatively, the msi in this case is wrapped up in a WiX bundle so if we can forbid certain directories from there that would also be good. Cannot find a way to do this either though (only know how to edit the default with <Variable Name="InstallFolder" ...>)
Only other solution I can think of would be rather horrible: make a separate application that selects a directory that then runs the installer with acceptable directory.
Can this be done either through an msi or a WiX Bundle?
I am using the "Visual Studio 2013 Installer Projects" extension to build the msi.
As a contrary view:
In general this is a bad idea. In most cases the correct answer will be to install the application code to the appropriate Program Files folder (64-bit or x86) and the data files to data locations and so on, and the user should get no choice. It is not clear to me that a choice is a good idea when (for example) the Windows Certification rules say that your code must go to the Program Files location, so just do it right. Users simply care that the installed application works correctly, and if it fails when installed to some locations then the answer is to either 1) Fix the application so that it works or 2) use Program Files and give the user no choice.
Also, if you are using Visual Studio Installer projects then you can't write custom actions to do this because they all run too late to change the install location. You seem to have discovered this already. But you CAN hide the browse folder dialog and install to the default correct location.
The other issue is that it's not clear how you would define an "allowed" location. If it's not C:\, then can it be D:\SomeOtherLocation? Can it be an attached USB drive? Can it be a network share such as \\Servername\share? A mapped drive to a network share? There are likely to be any number of chosen locations that will fail the install or the app when it runs, and I don't think there can be a useful list of what's allowed. On top of that, let's say you have a 32-bit install and the user chooses the native Program Files folder on a 64-bit system, then it won't even go there - it will be redirected to the Program Files(x86) location. Finally, it's not clear what you do in silent install mode assuming the user specifies a location on the command line, it fails your test, then the install silently fails (because silent means silent, and the install might be unattended).
In other words, just install to Program Files and have done with it.
Custom Action: This will be short. Will check back later. I can't say I have bothered implementing this recently, but a custom action can certainly inspect the installation location and abort the setup or halt it - if the path selected is found to not be satisfactory. It should also be noted that MSI actively resists installing directly to the root of C:\ and stuff like that due to the way the Directory table is implemented.
GUI: I guess one way would be to run a custom action when the user clicks the Next button in the setup's destination path customization dialog which then does "whatever you want" in terms of checking the path, and then reports any errors. This involves a DoAction event hooked up to the OK or Next button on the path customization dialog.
Silent Mode:You can also hook up the same custom action to run in silent mode (or another custom action calling the same path check function) - to account for the fact that an undesirable path could also be specified for a silent installation. In that case the custom action should abort the setup after writing into the log file, instead of reporting the path problem to the user - which is what you would do from the dialog event mentioned above - obviously.
Github: I do not have WiX code for you to implement this available on this computer. I would hit github.com and search for other projects that use WiX - you will probably find something quickly - no money for nothing and WiX for free.
Based on the users being able to manually install it (and hence using the UI sequence), it might be easier to:
In the InstallUISequence, sequence the LaunchCondition action to just before the ExecuteAction action.
Then in the LaunchCondition table, add a condition like so:
Condition:
TARGETDIR~<<"C:\Program Files\"
Description:
You must install to the Program Files folder
What we're saying in the condition is:
If the TARGETDIR starts with "C:\Program Files\" (therefore the user can install anywhere under this folder) continue with the install. Otherwise throw an error.
Rather then preventing certain locations, I'd probably just enforce the Program Files folder as a best practise.

Open C:\windows\assembly\gac_msil from C#

How can I open C:\windows\assembly\gac_msil in a Windows Explorer window using C#?
Explanation: When I deploy an assembly to the GAC in my development environment, I like deploying the .pdb symbol file to the same directory as the assembly located at C:\Windows\assembly\GAC_MSIL\AssemblyName\Version__PublicKeyToken\. That way if I want to attach the Visual Studio debugger, it automatically finds the symbol file.
I've built a little utility that detects when I add one of my assemblies to the GAC and I want it to show a button that pops open the directory for me. I have the button and the path, but starting a process that launches explorer.exe with the path doesn't work. The only way I know of to open this directory in Windows is through the Run dialog.
You can't get to it within explorer or using the command line command: explorer.exe "C:\Windows\assembly\GAC_MSIL...". Only if you type the path into the Run dialog. So how do I do what the Run dialog is doing?
As Hans Passant at one time had answered, the old GAC is displayed by a shell extension which masks the directory structure. This is to make sure the assemblies in the GAC are managed properly. Opening the directory structure is intentionally not supported. In .NET 4, that is no longer the case so if you can upgrade, that's the way to go.
To programmatically open the old GAC there are a few options but again, it is normally masked for a reason. Options:
Remove the shell extension. You can unregister Shfusion.dll, open the directory, then re-register it. This, of course, could go wrong and leave you with Shfusion.dll permanently unregistered. This would allow other users to freely mess with the GAC directory structure and files which would cause it to become invalid and fall out of sync with the registry = bad.
Disable the shell extension. The HKLM Fusion registry key can have a DisableCacheViewer DWORD value. When set to 1, it will disable the view. The key can be set to 1, the window opened, then the key can be set back to 0. This approach has the same risks as option 1. Additionally, as a user (Damien) whose comment seems to have been deleted pointed out, other processes may also use this global key causing a race condition = bad.
Use a 3rd party application like Total Commander (thanks to Csaba Toth) or Far Manager to view the directory structure instead of Explorer. The downside here is, assuming they can even accept arguments to allow them to open to the GAC directory, it would require installing that software everywhere I want to run my app.
If you are considering using options 1 or 2, be aware that in most scenarios they are a bad idea and should be avoided unless you are messing around with your own machine. This directory structure is synchronized with the registry and should not be directly edited. Use Gacutil.exe to manage the assemblies in the GAC.

Request for the permission of type 'System.Web.AspNetHostingPermission"

I am facing a problem for running my website.
I have developed the website and when i hit F5 to view the results i am presented with this error
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
How can i solve this problem.
This error usually happens if you Map your application folder on Network Drive or open Solution file from UNC Path. somthing like this:
Invalid Example: \\my-server\my-project
Try to open your solution from direct path
Valid Example: C:\Project\MyProject
You can also make change to your privilege of App Pool Identity but it's not recommanded:
Web Server (IIS) > App Pool Identity > Advance Settings > Set Identity as Network Service
the one shot solution worked for me was to set the App Pool Identity(Advance Settings) to Network Service
Try to set "Load User Profile" value of your application pool to "True".
It worked for me.
For what its worth, I found that the AjaxControlKit.dll on the deployed server was blocked. To resolve this, I copied over the dll to a new folder then copied and pasted in the bin folder. I guess .net doesn't like a dll being copied over directly to the web folder
you can run the following command to Grant FullTrust to remote share:
C:\Windows\Microsoft.NET\Framework\v2.0.50727>caspol.exe -m -ag 1 -url
"file:////\yourcomputername\yoursharename*" FullTrust -exclusive on
Hope this helps.
I tried all of the solutions posted here and a number of other places and nothing worked for me. I had my project located on a network drive which worked until I tried to use the AjaxControlToolkit 2.0 in my project. Apparently, something about permissions on the network drive would not allow the controls in the toolkit to run. I moved my project back to my local hard drive and it all started working.
I had this problem as well but have not seen this particular solution mentioned anywhere.
After checking permissions for the IIS user, the user for Impersonation, and granting Full Trust to the application, and still getting the error, I installed Procmon.exe on the server running IIS and noticed that IIS was attempting to access some Framework64 files for the offending website. I inspected the application pool advanced settings and discovered that "enable 32-bit applications" was set to false. Changing this setting to true proved to be the correct action. Life is good.
I face the same problem, then I realised that I was running the solution from a remote folder. Copy the necessary file to the local folder will solve the issue. But make sure that your folder have the full permission
While all of the other answers on this page may be the cause of anyone's problem, the most common one is due to OS security changes in Windows Server 2012 and above. Any file downloaded from the internet is flagged as suspicious by Windows and needs to be manually unblocked before using it in IIS. So if you FTP your code, email it, or transfer it through a cloud provider, it will be flagged and blocked.
The best solution is to use the web publishing facilities built in to Visual Studio or transfer through a network share if you're on a domain, each of which avoid this problem. However, if you must copy your code to another server by one of the means I described above, you should zip everything prior to transfer so you are only left with a single file to unblock. If you unzip before you unblock, then each file will be blocked and multi-selection will not give you the option to unblock.
So finally... to unblock: Right click the file and select Properties. Right there on the first page near the bottom you'll see an Unblock button along with the warning that the file was downloaded from the internet!
If the dll is compiled using this option (Do not merge. Create a separate assembly for each page and control), please make sure the dll is up to date. I faced the error due to aspx file is new one, but dll still using old one.
I found a potential solution that worked on my system and did not require changing to Network Service.
Go to Application Pool -> Advanced Settings -> Process Model -> Load User Profile: True
Source of this answer.
The best way to resolve this issue is Run the Visual Studio as "Administator". Right click on the Visual Studio icon and select "Run as Administrator".
Once you open Visual Studio with Full admin rights, you will be able access the page without any issues.
I have had this error and it seems to be a generic error. As there are several answers to this issue, I am going to add mine. Republishing the website on the remote server seems to fix it for me.

How to manually set password for MSBuild sign target?

We are building an Outlook plugin in C#. It is built without problems in VS and signed with a temporary pfx certificate. We want to put the build process in Jenkins and have it run automatically.
We tried to run the VS solution with MSBuild. It works great on the development machine but in Jenkins there is an error:
Cannot import the following key file: OutlookPlugin_TemporaryKey.pfx. The key file
may be password protected. To correct this, try to import the certificate again or manually
install the certificate to the Strong Name CSP with the following key container name:
VS_KEY_A688DC31A30F3EF1
We don't know how to specify the pfx password for the automated build. Or otherwise automate the sign process.
One solution we found was to open the project in VS on the same machine and as the same user as for the automated process and type the password. This doesn't work, probably because Jenkins wipes out the workspace every time.
If we try to compile without signing and then sign it afterwards, it complains that a ClickOnce assembly must be signed. It seems that Office plugins must use ClickOnce.
So, how to specify the pfx password somewhere in the build file ?
We use VS 2010 with Office Tools.
Create a file (either local or on a well known network share) containing the password as a property and reference that from the MSBuild script. Set permissions on the file such that only the build account can read that file. Note that anyone with admin access to the build machine or that knows the build account password will be able to read the password. Ultimately, there is no silver bullet here. If MSBuild can find/decrypt/whatever the password, a human will be able to, too.
If you are concerned about the security of the private key, consider separating the signing to a separate step and store the private key on a smartcard. It may be overkill but it is one of the best, commonly available protections available.
Otherwise, just add the password as a property. As you know the project files are just MSBuild scripts. For example:
<PropertyGroup>
<PfxPassword>password</PfxPassword>
</PropertyGroup>
<!-- Sample sign task -->
<SignTask>
<File>MyOutlookPlugin.dll</File>
<KeyFile>OutlookPlugin_TemporaryKey.pfx</KeyFile>
<Password>$(PfxPassword)</Password>
</SignTask>
See http://msdn.microsoft.com/en-us/library/ms171458(v=vs.80).aspx for more information about MSBuild properties.
We were having issues building the project with MSBuild and Bamboo. The fix for us was to remove the following line from the .csproj file.
<AssemblyOriginatorKeyFile>applicationcert.pfx</AssemblyOriginatorKeyFile>

Categories

Resources