I have a windows forms application that is deployed to two different locations.
Intranet - ClickOnce
Internet - Installed on a citrix farm through Windows installer
I display ClickOnce version number for click-once deployed versionApplicationDeployment.IsNetworkDeployed.
if (ApplicationDeployment.IsNetworkDeployed)
return ApplicationDeployment.CurrentDeployment.CurrentVersion;
But for the non-click application, I am not sure how to retrieve clickonce version unless I hardcode the version number in assembly info.
Is there an automatic way of retrieve ClickOnce version number for non-clickonce deployed version?
Add an assembly reference to System.Deployment to your project.
Import the namespace in your class file:
VB.NET:
Imports System.Deployment.Application
C#:
using System.Deployment.Application;
Retrieve the ClickOnce version from the CurrentVersion property.
You can obtain the current version from the ApplicationDeployment.CurrentDeployment.CurrentVersion property. This returns a System.Version object.
Note (from MSDN):
CurrentVersion will differ from UpdatedVersion if a new update has
been installed but you have not yet called Restart. If the deployment
manifest is configured to perform automatic updates, you can compare
these two values to determine if you should restart the application.
NOTE: The CurrentDeployment static property is only valid when the application has been deployed with ClickOnce. Therefore before you access this property, you should check the ApplicationDeployment.IsNetworkDeployed property first. It will always return a false in the debug environment.
VB.NET:
Dim myVersion as Version
If ApplicationDeployment.IsNetworkDeployed Then
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion
End If
C#:
Version myVersion;
if (ApplicationDeployment.IsNetworkDeployed)
myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
Use the Version object:
From here on you can use the version information in a label, say on an "About" form, in this way:
VB.NET:
versionLabel.Text = String.Concat("ClickOnce published Version: v", myVersion)
C#:
versionLabel.Text = string.Concat("ClickOnce published Version: v", myVersion);
(Version objects are formatted as a four-part number (major.minor.build.revision).)
No I do not believe that there is a way. I believe the ClickOnce information comes from the manifest which will only be available in a ClickOnce deployment. I think that hard coding the version number is your best option.
I would simply make the assembly version of the main assembly the same as the CLickOnce version every time you put out a new version. Then when it runs as a non-clickonce application, just use Reflection to pick up the assembly version.
Try thread verification:
if (ApplicationDeployment.IsNetworkDeployed)
{
if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
{
Application.ExitThread();
Application.Restart();
}
}
not that it matters three years later, but I ended up just parsing the manifest file with xml reader.
To expand on RobinDotNet's solution:
Protip: You can automatically run a program or script to do this for you from inside the .csproj file MSBuild configuration every time you build. I did this for one Web application that I am currently maintaining, executing a Cygwin bash shell script to do some version control h4x to calculate a version number from Git history, then pre-process the assembly information source file compiled into the build output.
A similar thing could be done to parse the ClickOnce version number out of the project file i.e., Project.PropertyGroup.ApplicationRevision and Project.PropertyGroup.ApplicationVersion (albeit I don't know what the version string means, but you can just guess until it breaks and fix it then) and insert that version information into the assembly information.
I don't know when the ClickOnce version is bumped, but probably after the build process so you may need to tinker with this solution to get the new number compiled in. I guess there's always /*h4x*/ +1.
I used Cygwin because *nix scripting is so much better than Windows and interpreted code saves you the trouble of building your pre-build program before building, but you could write the program using whatever technology you wanted (including C#/.NET). The command line for the pre-processor goes inside the PreBuildEvent:
<PropertyGroup>
<PreBuildEvent>
$(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version
</PreBuildEvent>
</PropertyGroup>
As you'd imagine, this happens before the build stage so you can effectively pre-process your source code just before compiling it. I didn't want to be automatically editing the Properties\AssemblyInfo.cs file so to play it safe what I did was create a Properties\VersionInfo.base.cs file that contained a text template of a class with version information and was marked as BuildAction=None in the project settings so that it wasn't compiled with the project:
using System.Reflection;
using EngiCan.Common.Properties;
[assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")]
[assembly: AssemblyRevisionIdentifier("$REVID$")]
(A very dirty, poor-man's placeholder syntax resembling Windows' environment variables with some additional h4x thrown in was used for simplicity's/complexity's sake)
AssemblyRevisionIdentifierAttribute was a custom attribute that I created to hold the Git SHA1 since it is much more meaningful to developers than a.b.c.d.
My refresh-version program would then copy that file to Properties\VersionInfo.cs, and then do the substitution of the version information that it already calculated/parsed (I used sed(1) for the substitution, which was another benefit to using Cygwin). Properties\VersionInfo.cs was compiled into the program. That file can start out empty and you should ignore it by your version control system because it is automatically changing and the information to generate it is already stored elsewhere.
Hard code, or... Keep track on your versions (File, Assembly, Deploy) in a database. Make a call to the database with your Assembly and get the Deploy version.
This assumes that you are incrementing your versions in a logical way such that each version type has a relationship. It's a lot of work for such a minor problem. I'd personally go with Jared's solution; although I hate hard coding anything.
Using a build component, you could read the click-once version from the project file and write it automatically to the assembly info so both of them are in sync.
Solution for .NET (Core) 7 and higher
On .net Core, you can read the version number from the environment variable ClickOnce_CurrentVersion.
string versionString = Environment.GetEnvironmentVariable("ClickOnce_CurrentVersion") ?? "0.0.0.0";
Version version= Version.Parse(versionString);
MessageBox.Show(version.ToString());
See documentation
Related
I have a simple application using a product activation system offered by cryptlex (cryptlex.com).
The program works correctly on my computer, but when I try to run the program on another machine it returns this error:
I've already made sure that the dll is inside the executable folder and everything looks OK.
When I remove all part of cryptlex the program works perfectly on any machine (x86-x64)
I used depencywalker to check for errors and found these two in the executable that uses cryptlex:
Windows 7 64bits,
.NET Version: 4.0
You can use Process Monitor to record all file activities of the program. Set a filter for your executable. After reproducing the error, save the log as XML file.
Then run ProcMon Analyzer (note: I'm the author of it). It will analyze the file and give a list of DLLs that were not found.
You could also do that manually, but note that some DLLs may not be found at first, but later be found when looking in the %PATH% environment variable etc. The tool will remove all those entries which have PATH NOT FOUND first but SUCCESS later.
While the DLL is present, have you checked the bitrate?
Most C# projects default to building against Any CPU - if the DLL is specific to a bitrate (ie x86 or x64) then it might be that the program picks the wrong bitrate on end machines (usually x86) but the right one on your machine (x64). This is usually best resolved by building out different x86 and x64 versions; it's messier, but only .NET itself is good at using the Any CPU paradigm.
The exception should have detail about what DLL in particular was not found - maybe look closer?
GPSVC and IESHIMS missing should not be a problem; as indicated by the hour glass, they're deferred dependencies anyway.
I have .net framework 4.0 (and older versions, i.e. multiple versions) installed, want to use the command line compiler for C#
C:\>csc.exe
Now I found across few forums using the direct path I can use the compiler, also using batch file one can do that,
I need to set environment variables LINK but that is part of visual studio(if VS is installed then only it works) I want to use the compiler from the redistributable .net framework(using command line only) which is free to use and distribute.
Do not want to install Visual Studio in the system where I run the code.
my Current CSC.exe file location PATH is
C:\Windows\Microsoft.NET\Framework\v4.0.30319
This path and compiler file works fine but every time I have written like this and some times I have seen an error related to Library.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe sample.cs
How to avoid writing long path each time while testing the sample codes?
Please provide best available alternate(Batch file or something)
Edit 1: Setting Path:
Paul's answer is works fine with simple program, But the issue with that is if there are any Library files used/added, were not found in this case.
Note: Version is not a constraint actually, we may use any .net redistributable version. Just CSC.exe should accessible from any path without any issue(example library files used).
if you are using a batch file add to the start
set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319\;%PATH%
This will add the .net framework to the start of your path for the current run of the batch file only.
now your batch file can just use
csc.exe sample.cs
Got the working answer from one of the forums, for the complete solution to build with reference added.
We need to use /r option with compilation.
First add path using command below.
Example:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:sample.exe sample.cs /r:ReferenceName.dll
After adding Path:
C:\test>csc /t:exe /out:sample.exe sample.cs /r:ReferenceName.dll
This solved my problem with reference.
Note: if reference is not in same directory as CS file it need to be added with its path.
We have a C# desktop application which we run for clients on various servers on a software as a service model. We are still on dot net framework 2.
The software has a architecture in which we have an independent application to catch external data thrown by some server. Then an application to make calculations based on it. Also one more application on which the client sees the output. The link between the 3 applications is another application which communicates with the DB.
The 4 solutions are on a SVN for sourcecontrol. But the release management is still manual and the patches are made manually by checking the log and including the dlls, pdbs, xml. etc for the projects for which the code has changed.
There is no assembly versioning implemented and the patch or release management is just done in the dark.
I want to know what is the industry practice for generating automatic patches from the code. Also I want a patch for each revision in the SVN. Also is assembly versioning helpful in this?
I have read much about continuous integration but it fails because we do not have unit tests and other fancy code to moniter the correctness of code.
The only thing at this time I would be interested is to implement a way to make patches which can be applied and removed easily. Also I want to know a way to determine the way we can monitor which release is at which level(or what patches have been applied) by some automated way rather than maintaining a log manually.
We use a build script which creates a SvnVersion.cs file containing the last commited revision. This file is placed in the root of the solution, and then added to all projects in the solution (but added as a link, not copied).
The template for the file (SvnVersion.Template.cs) looks like this:
using System.Reflection;
[assembly: AssemblyVersion("1.0.0.$WCREV$")]
[assembly: AssemblyFileVersion("1.0.0.$WCREV$")]
And we simply use TortoiseSVN to fill these placeholders in a batch script:
type "%TRUNKPATH%SvnVersion.Template.cs" > "%TRUNKPATH%\SvnVersion.tmp"
SubWcRev "%TRUNKPATH%\" "%TRUNKPATH%SvnVersion.tmp" "%TRUNKPATH%SvnVersion.cs" -f
IF ERRORLEVEL 1 GOTO ERROR
DEL "%TRUNKPATH%SvnVersion.tmp"
If you don't use TortoiseSVN, there are other ways to get this info in the file.
You will also need to remove this same information from your AssemblyInfo.cs files or you'll get a compile error. Also, to speed up Debug builds, this is only executed in Release builds (and in Debug builds only if the file doesn't initially exists, like after a fresh checkout).
I am running into issues building an existing 32-bit EmguCV (Version 2.3) into 64-bit using .net 4.0 and VS2010 on a W7/x64 OS. I have purchased a commercial license, if that matters and downloaded from the links provided in the receipt.
The error is
System.TypeInitializationException was unhandled
Message=The type initializer for 'Emgu.CV.CvInvoke' threw an exception.
Source=Emgu.CV
TypeName=Emgu.CV.CvInvoke
I followed the instructions provided in this article. In fact I used the samples projects in the article and they build fine with V2.2, but when I replace with V2.3 binaries (both emgu and opencv), run into the error.
Has anyone successfully built an Emgu (Version 2.3.x) x64 project? Please provide some guidance.
The cause of this error (should anyone else run into the same problem) is that the program cannot access opencv_imgproc231.dll or opencv_core231.dll even though they are present in the output "bin" directory.
There are two solutions:
Add them to the project and set their properties to copy always as they are EMGU's two key files.
If step 1 doesn't work, replace the current key files in the bin folder with new copies.
If both methods fail then there may be a problem with the build, so download a new copy of EMGU from Sourceforge and try again. The error will later be incorporated within an technical article in order to provide a clearer explanation of how to solve it.
Cheers,
Chris
No need to add them to the project; VS will not let you. Simply open FaceRecognizer.cs
at public static partial class CvInvoke and change:
[DllImport(CvInvoke.EXTERN_LIBRARY, CallingConvention = CvInvoke.CvCallingConvention)]
to:
[DllImport(Emgu.CV.CvInvoke.EXTERN_LIBRARY, CallingConvention = Emgu.CV.CvInvoke.CvCallingConvention)]
Ensure you change all of them.
First test this way: open a sample project from emgu cv installaiton directory and run it. for example, open hello world example and try to run it. if sample projects run with out problem then the installation is correct.
For emgu cv sample projects, value of Output Path option in Build settings of the project is set to '..\..\
bin'. To fix your project problem, open the project in visual studio and set value of Output Path option to 'C:\Emgu\emgucv 2.9\bin'. Try to run the project. It must run with success.
Now, set back the value of Output Path option to bin\Debug\. Then, add all DLL files in the 'C:\Emgu\emgucv 2.9\bin' folder to your project using ADD -> Existing Item menu. similarly, add all DLL files in the 'C:\Emgu\emgucv 2.9\bin\x64' folder to your project using ADD -> Existing Item menu. Now, go to properties window and set Copy to Output Directory option of all dll files to Copy Always. Finally, in the Configuration Manager window, create a new configuration for x64 platform.
Good Luck
I have a Deployment Project for my VS2008 C# application. When installing a new version of my application I want to make sure that files are updated with the files contained in the installer.
I want my installer to automatically remove any old version of the installed application. To do that I follow this procedure (also described here):
Set RemovePreviousVersions to True
Set DetectNewerInstalledVersion to
True
Increment the Version of the
installer
Choose Yes to change the ProductCode
For the assemblies I make sure the AssemblyVersion is set to a higher version:
[assembly: AssemblyVersion("1.0.*")]
Everything is working as intended except for my configuration files (xml files). Since I cannot find a way to "version" these files I cannot make sure that the files are updated if they have been modified on the target machine.
Is there any way to do this and how?
UPDATE: I have tried the approach/solution/workaround found here
Include the file directly in a
project with the following
properties: "Build Action -> Content
file" and "Copy to Output Directory
-> Copy always"
Then add it to the deployment
project via Project
Output->Database->Content Files
Unfortunately it did not make any difference. The behavior is exactly the same.
Add the following property to the Property table of the MSI:
Property REINSTALLMODE with Value amus
Note: This will cause all the files in the MSI (versioned and nonversioned) to overwrite the files that are on the system.
If you're willing to use Orca (there may be another way to do this method, but it's the only one I know of) you may be able to set up RemoveFile directives.
See here for a typically light-weight MSDN document -- could be a starting point.
http://msdn.microsoft.com/en-us/library/aa371201.aspx
Alternatively you could always create a very simple bootstrapper executable that simply calls "msiexec /i REINSTALLMODE=oums" (or whichever command-line switches are needed). Call it setup.exe if you like...
Better option long-term may be to switch to InstallShield or similar -- VS2010 includes a light version of IS and I believe they're moving away from vdproj projects.
Have you tried the approach/solution/workaround found here?
Include the file directly in a
project with the following
properties: "Build Action -> Content
file" and "Copy to Output Directory
-> Copy always"
Then add it to the deployment
project via Project
Output->Database->Content Files
I may be incorrect here, and therefore I am exposing myself to down votes, but here goes anyway!
I believe it is on purpose that config files do not automatically get overwritten; the principle there being that you would not normally want your application's configuration overwritten when you install the new version of the program... at least not without numerous warnings and/or chances to merge configuration first.
Having your application configuration get overwritten by an updated version of a program could make for a very upset end user (in this case, web site admin).
Further, I know that sometimes, the developer may be the person doing the deployment. In such a case, this behavior might not seem so logical when deploying a single site to a single server; but when roles are split and/or you have multiple servers with different configurations, this can be a life saver.
You need to include the new version of your files in your custom installer and manually install these file during Custom Install routine is called
This must be applied to any file that does not have version that can be tracked by the installer.