I am desperately trying to deploy an ActiveX for IE developed in C# as a CAB archive. I have read many resources (some of them from StackOverflow) and it appears a lot of people are having the same problems. I have tried 3 solutions: a) creating a CAB VS project, b) manually creating a CAB using CABARC with a COM registration in INF and c) manually creating a CAB with launching msiexec. None of them worked. I even tried d) creating a bootstrapper which launches msiexec to no avail (because some people suggested simply launching msiexec on Vista can't work).
I am running Windows Vista but my project fails to run even on IE6 on XP.
When I install ActiveX using MSI, all is fine on ALL Windows. Apparently CAB thing is not working and I could not find a proper way to debug this whole process yet.
Any help is appreciated.
Update: Note that this old but excellent answer is still a very good outline for how to approach solving this problem, at least as along the evolutionary scale as Win7 and IE11. I just succeeded making it all work using the Answerer's Firebreath.org toolset as a jumping off point. It's not simple but it can be done. I've added a reference to that project to the reference list below since it may make a more logical jumping off point for current developers than this overview is.
Hooray - I have just finished an identical project, so you'll be pleased to know that it's actually possible. I have only tested this on XP - I understand there may be issues where Vista/7 don't allow msiexec to be called.
Given that you have an assembly correctly exposing a COM interface, I did the following:
Strong-named the assembly.
Created an INF file
Created an MSI using the Visual Studio 2008 "Setup Project" template.
Created a CAB file using "iexpress.exe" bundled with Windows XP.
Create INF file
The *.inf file I used looks like:
[version]
signature="$CHICAGO$"
AdvancedINF=2.0
[Setup Hooks]
install=install
[install]
run=msiexec.exe /package """%EXTRACT_DIR%\SampInst.msi""" /qn
The only bit you should need to change is the SampInst.msi. Note I would use an 8.3 filename, as long filenames can cause issues. While testing, I would not use the qn switch either, as that is a silent install.
Create the Installer
The installer has to do only one thing, and that is register the assembly by calling RegAsm on it. Most installers will provide some method to easily do this. For example, an installer created through VS 2008 will simply need to have the “Register” property of the assembly set to “vsdrpCOM”. Note that vsdrpCOM should be chosen as it generates the appropriate registry entries at build-time. The vsdrpCOMSelfRegistration setting is likely to fail as it calls RegAsm at run-time, and will thus not work for non-administrators.
Package the installer into a CAB file
This can be done by any cab archiver. Windows XP contains iexpress.exe, a wizard driven archiver, while Microsoft’s CAB SDK contains cabarc.exe. Other 3rd-party tools are also available.
Note that you will need to reserve space in the CAB file for code-signing if you are going to sign the CAB.
You will need to CAB the INF file, and the MSI file. You will not need to CAB the Setup.Exe file.
Handy hint: The VS2008 Setup Project project type allows you to set a post-build step in the properties, so you can build and CAB in a single step. My post-build step looks like:
cd "$(ProjectDir)"
"%WINDIR%\System32\Makecab.exe" /f "VboCslib.ddf"
The DDF file format is documented.
Sample HTML page
The object tag is used to point to the cab file containing the installer. A very simple HTML page which would deploy an ActiveXControl would be:
<html>
<head></head>
<body>
<!--
ID : The id of the ActiveX control to be used in JavaScript.
CLASSID : The GUID associated with the ActiveX control.
CODEBASE: The location containing the CAB installer for the ActiveX
control. This could be a URL, or a relative path.
-->
<OBJECT ID="MyActiveXControl"
CLASSID="CLSID:FC36FAE1-48E0-4f6b-B469-E1B5A8C6D1AC"
CODEBASE="cabfiles\SampleCabFile.CAB#version=1,0,0,0">
</OBJECT>
<script>
MyActiveXControl.SomeMethod();
</script>
</body>
</html>
Handy hints
Ensure your installer installs on a "per-user" basis, not a "per-machine" basis. This will make it more likely to install if the user does not have admin privileges.
Trouble-shooting
Internet Explorer 6 actually provides a really useful diagnostic aid. Clear your Temporary Internet Files, then navigate to the web-page. If the installation does not work, go to your temporary internet files and you will see a couple of files in there. One of these will be an error log starting ?CodeDownloadErrorLog. Drag it to your desktop and open it in notepad, and it will give details on what it was trying to do when it failed.
References
Microsoft KB247257 – Steps for signing a .cab file
MSDN – About INF File Architecture
SN.EXE - Code Strong Programs with Strong Names
Nikolkos Craft – How To: Deploy .NET ActiveX Control
CodeProject – Create ActiveX .NET Step by Step
CodeProject – Downloading C# ActiveX Components through CAB file
MSDN - ALLUSERS Property (Windows)
MSDN – Non-Admin ActiveX Controls
MSDN – Microsoft Cabinet Format
Update: Firebreath.org has a toolset for generating browser plugins for many platforms. The IE/ActiveX code to solve the problem posed here is just a subset. But as of 6 Nov 2014, I found it easier to start with Firebreath and its instructions than to try to build up my dev environment and roll all my own solutions from scratch.
Related
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
I'm looking for a way to add new pages to installer with its own interface. Ultimately, I would like my installer to do many things in turn, enabling the user to go to the next pages and check or set subsequent configurations.
But at the moment I'm looking for how to add an additional page that would run before installation and check if the computer has the required programs to install the application. I would like to attach my ready code to c # to check if these programs are installed on the given computer.
By using this tutorial:
https://www.youtube.com/watch?v=6Yf-eDsRrnM&t=7195s
I created the basic version of the installer. In the tutorial we create installer by using WixUI_Minimal.
I have looked through the documentation and it is written that you can create your own pages, but I can't find anywhere. For example there
https://wixtoolset.org/documentation/manual/v3/wixui/
is Customizing Built-in WixUI Dialog Sets but they dont show how do that.
Update 21th April 2020
I have created a public GitHub Gist, which explains the steps and even include a customized Dialog PrerequisitesDlg.wxs with up to 5 Prerequisites, which can be configured as WiX Properties (text and condition). The whole sequence is wrapped in WixUI_KargWareFeatureTree.wxs.
Text before 20th April 2020
The element you need is UIRef Element, Wix Toolset v3 Documentation.
Wix Toolset is an open source project, so you can review it on GitHub, Wix Toolset v3.
The dialoges which are embed in Wix Toolset are listed here, Source Code of the Default UI-Dialoges of Wix ToolSet. I would use the WixUI_Advanced one, but you can pick all others or start even from scratch.
Download the WixUI_Advanced.wxs from GitHub
Copy the wxs file to the root of your msi-project (where the *.wixproj os placed) and name it to e.g. MyWixToolsetPages.wxs
Edit the name of the UI xml element inside MyWixToolsetPages.wxs (near to line 50)
Add the MyWixToolsetPages.wxs to your wixproject
Replace or add the UIRef reference element in the product.wxs to <UIRef Id="WixUI_MyWixToolsetPages"/>
Add your new dialog as <DialogRef Id="myNewPage" />
Customize the order of the pages with Control Next / Back and Event NewDialog
Be aware to test your sequence in both directions (next, next, next, end) and (end, back, back, back)
Change <UI Id="WixUI_Advanced"> to <UI Id="WixUI_MyWixToolsetPages"> inside your MyWixToolsetPages.wxs (copied from the original WixUI_Advanced.wxs)
...
<UI Id="WixUI_MyWixToolsetPages">
...
Replace the UIRef inside the product.wxs
...
<UIRef Id="WixUI_MyWixToolsetPages"/>
...
I maintain an open source wix authoring tool that enables you to do this by uncommenting one line of XML. The trick is to insert additional rows into the ControlEvent table causing existing paths to be overridden.
https://github.com/iswix-llc/iswix/blob/master/Application/IsWiXNewAddIn/MSISolutionTemplate/SetupProjectTemplate/UI.wxs
https://github.com/iswix-llc/iswix/blob/master/Application/IsWiXNewAddIn/MSISolutionTemplate/SetupProjectTemplate/UI-CustomDialog.wxs
Overall Advice: It is generally an anti-pattern - as of this IT-epoch - to do too much with your setup GUI. In particular it is
better to do per-user configuration as part of the application launch.
Rule of Thumb: You should limit setup-GUI to genuinely shared settings that need to be written with admin or elevated rights to
per-machine locations (inaccessible for normal users). Set everything else from application launch. This can also help QA personnel with their testing.
Burn: Burn is the WiX toolkit's setup.exe creator. It is a bootstrapper, chainer, downloader, installer, etc... construct. Hello-Burn sampler here. And about replacing Burn's default GUI.
WiX MSI GUI: I have a minimalistic sample here for how to change your MSI installer GUI: https://github.com/glytzhkof/WiXCustomDialog. This is the GUI embedded inside your actual MSI. There are other possibilities with GUI.
GUI: You can replace the GUI inside each MSI with a GUI from a Burn setup.exe. There are some details here. This GUI you can implement as a normal executable with all the bells and whistles that allows. The MSI GUI is rudimentary and old. There is another answer here on how to change installer GUI.
I'm trying to Instrument an ASP.NET web-application with Visual Studio 2012, .NET 4.
The solution contains a web-application and a class library.
The problem is I can't see step into the class library, I get a message stating:
Matching symbols could not be found. Choose the 'Symbol Settings...' link to add the symbol file location and then reload the report.
The output while profiling looks good though:
Preparing web server for profiling.
Profiling started.
Instrumenting C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\\bin\PerformanceTest.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll --> C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll
Original file backed up to C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll.orig
Successfully instrumented file C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll.
Warning VSP2013: Instrumenting this image requires it to run as a 32-bit process. The CLR header flags have been updated to reflect this.
Instrumenting C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll --> C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll
Original file backed up to C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll.orig
Successfully instrumented file C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll.
Warning VSP2013: Instrumenting this image requires it to run as a 32-bit process. The CLR header flags have been updated to reflect this.
Launching web server with profiling.
Launching profilable project.
Warning VSP2355: Some Windows counters will not be collected. Without this data, some performance rules may not fire.
Profiling process ID 68 (iisexpress).
Process ID 68 has exited.
Data written to C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\PerformanceTest_130801(1).vsp.
Profiling finished.
Loaded symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\0329cb19\89f716fc\App_Web_0slsprtu.dll.
Loaded symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\0329cb19\89f716fc\assembly\dl3\62c5c0d2\9777513f_ae8ece01\PerformanceTest.dll.
Profiling complete.
I notice the output doesn't state anything about the class library called 'SomeLibrary' at the end, where it says "Loaded symbols for".
Does anyone know why I can't instrument the class library?
Here's the VS solution: http://www.fileswap.com/dl/C9HPd8uEC/
As far as I can tell from your solution, the .dll that is being instrumented is in the class library's "obj" folder.
Now, this may just be me speaking when I should keep my mouth shut (because I have little insight into the Visual Studio profiler, and I have no idea why/if one would want to instrument "obj" binaries rather than "bin"), and therefore, I guess I'd better describe my train of thought:
VS is looking for the symbol files (the .instr.pdb file specifically) in the "ASP.NET Temporary Files" location, because that's where it loaded the class library dll from. It won't find it, though, because that file is created in obj\Debug in the class library project and not copied over to the web application's "bin" folder - so it never gets shadow copied to "ASP.NET Temporary Files" either.
Removing the targets from the Performance Explorer and selecting "Add Project Target", checking both projects, gives me exactly what you (and I) had before:
PerformanceTest.dll in Web Application project's ...\bin\Debug
SomeLibrary.dll in Class Library project's ...\obj\Debug
So apparently, this is how VS wants it to be, whether it works or not. It instruments the class library in obj\Debug, then forgets all about the newly generated symbols when starting the profiler.
But if, instead, I remove the "SomeLibrary.dll" target again, select "Add Target binary..." and manually pick the one in the web application's ...\bin\Debug... And then start profiling: The report looks about the same, but I can browse into "SomeLibrary" and I get this in the output:
Preparing web server for profiling.
Profiling started.
Instrumenting E:\...\PerformanceTest\\bin\PerformanceTest.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
E:\...\PerformanceTest\bin\PerformanceTest.dll -->
E:\...\PerformanceTest\bin\PerformanceTest.dll
Original file backed up to E:\...\PerformanceTest\bin\PerformanceTest.dll.orig
Successfully instrumented file E:\...\PerformanceTest\bin\PerformanceTest.dll.
Warning VSP2013: Instrumenting this image requires it to run as a
32-bit process. The CLR header flags have been updated to reflect this.
Instrumenting E:\...\PerformanceTest\bin\SomeLibrary.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
E:\...\PerformanceTest\bin\SomeLibrary.dll -->
E:\...\PerformanceTest\bin\SomeLibrary.dll
Original file backed up to E:\...\PerformanceTest\bin\SomeLibrary.dll.orig
Successfully instrumented file E:\...\PerformanceTest\bin\SomeLibrary.dll.
Warning VSP2013: Instrumenting this image requires it to run as a
32-bit process. The CLR header flags have been updated to reflect this.
Launching web server with profiling.
Launching profilable project.
Profiling process ID 14652 (iisexpress).
Process ID 14652 has exited.
Data written to E:\...\PerformanceTest\PerformanceTest_130810(1).vsp.
Profiling finished.
Loaded symbols for
C:\...\App_Web_yzwcgfbx.dll.
Loaded symbols for
C:\...\assembly\dl3\928eb82e\75dbb6f1_5695ce01\PerformanceTest.dll.
Loaded symbols for
C:\...\assembly\dl3\6c0d460d\5208c7f1_5695ce01\SomeLibrary.dll.
Profiling complete.
Is this the correct way to fix it? Again, I have no idea. If not, there may be a way to get the profiler to look for symbols in the class library's obj folder when it doesn't find them where it expects to - or a way of copying the .instr.pdb file to the bin folder pre-profiling so that it gets included in the shadow copy to ASP.NET Temporary Files.
I had this problem in VS2014 with an exe which was built for "Any CPU" with "Prefer 32 bit" set, whereas the referenced libraries did not have "Prefer 32 bit" (ie. 32-bit exe, 64-bit libraries).
Changing the exe to not "prefer 32 bit" fixed the problem with symbols, I think it's because the libraries are modified to match the bitness of the exe (during instrumentation) and the symbols no longer match.
This solution worked for me:
http://www.brothersincode.com/post/Matching-symbols-could-not-be-found-Performance-Profiler.aspx
You could also try it the other way around, meaning removing your dll as it is and trying to put the one from bin cause that can might as well be the other way around.
I have successfully managed to profile my class library - but only from within a console application. I have not been able to profile the class library during an ASP.NET app performance profiling session.
Some assorted links - which alas didn't solve my problem, but may give you some leads:
Run the Developer Command Prompt for VS2012
Then you can use this to VSPerfReport <yourreport.vsp> /debugsympath to figure out where SomeLibrary.dll should be loaded from
Troubleshooting tips http://msdn.microsoft.com/en-us/library/bb385766.aspx
The currently accepted answer helped me to get there, but I'll try to humbly give a little more straightforward instructions to those who are trying to accomplish exactly the same thing that I am, just in case I would save a couple of hard googling hours for somebody.
I was unsuccessfully trying to profile a WCF service that uses external assemblies, which are loaded by reflection at runtime and have this service to be triggered by my custom client. I had 2 problems: my WCF service just didn't start at all during profiling session (but while debugging it would always do it), and then when it did for some reason - Visual Studio coulndn't load the symbols for external assemblies.
So to get both things to work I needed to create an instrumentation performance session with the target set to my main WCF service along with the custom external assemblies and set the launch mode - Internet Explorer (otherwise the service wouldn't start). No exes or pointing to client from solution. Then I didn't start the profiler immediately, but modified it's properties in "Performance Explorer" window and added a binary of my custom client to the "Launch" tab to be launched 2-nd (right after the service inself). It also helped to have a proper "Service reference" right in the client (I don't really use it, I use shared assembly and generate channels using ChannelFactory) and launch the client in debug mode first (but without actually ever accessing a service). Maybe that's not the right way to do it, but it does the trick and I finally can profile my service after 2 days of googling - not very much docs available on this topic, and the accepted answer to this stackoverflow question is the best resource I found.
I'm using Visual Studio 2019 and stumbles the same issue while instrument profiling an ASP.NET web site.
Heavily inspired by the above JimmiTh solution, I added the [ProjectPath]/obj/Debug paths of the missing project to VS Options->Debugging->Symbols. After profiling again I could easily access the source code and get more accurate profiling diagnosis.
In our company we have a software program that operates the machines that we produce. The application (HMI) that is running on a WES7 OS is programmed in C#. Because our machines are shipped all over the world, the language of the HMI can be adjusted by clicking on a language button.
The HMI software is written by a third company but we have it in our own control now. The machine's we deliver might have project specific "fault" messages and must be added to the HMI. This means that these specific "fault messages" must be added to the resources.resx file. But for as far as I know, this can only be done from Visual Studio, do a build and a new file ExternalResources.xap file is created with all translations (Multilanguage).
We don't want a specific application for each customer or do a build on the project for only creating the ExternalResources.xap file. So I'm wondering if there are tools available that run standalone (no Visual Studio needed) and that can create the ExternalResources.xap file.
We don't need to add sources to the resources file, but only change the value of a source on project wish. I hope I made my point clear and someone knows a solution.
Edit:
I need to generatoe the ExternalResources.xap file. When you open this file, all locations available are shown in folders, and within this folders, there are *.recourses.dll files. Those files do I need to generate!
You may use Resgen.exe
Or develop some tool for that, here is a useful sample Extended Strongly Typed Resource Generator
Hope this helps.
I am making software setup package, and previously I am using Inno Setup, and it works very good.
The current issue I met with Inno setup is, it does not support all languages for the setup UI, for example Simplified Chinese.
The setup project of VSTS 2008 supports almost all languages, but it does not support invoke another installer from the current installer to let end user install dependent software packages.
My program to publish is for Windows platform (Vista and XP), written in C# + VSTS 2008 + .Net 2.0.
Any advice for my problem?
thanks in advance,
George
As one of the comments to your question suggests, you may want to simply integrate the required language into your Inno Setup. You do that by adding the Languages section:
[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
This allows the UI to be displayed both in Englisch and Dutch. Other translations can be added accordingly.
The fact that Windows Installer does not allow "nested installations" (running an MSI from an MSI) can be annoying. You might, however, consider packaging the MSI installers into an UI-less (= silent) Inno Setup and have Inno Setup run the MSIs one by one.
EDIT
This shows you how you may run the EXE files to install your dependencies. Please note that they might be installed after your software. If it is required that they are installed before your software, you may need to code a little Pascal Script - this is explained in the help files.
[Files]
DestDir: {tmp}; Source: .\Files\sample.exe; Flags: deleteafterinstall;
[Run]
Filename: {tmp}\sample.exe; StatusMsg: Installing prerequisite
This includes file .\Files\sample.exe into the setup, copies it to the TEMP folder upon installation and removes it after the setup is done. Then, after copying your files, it runs TEMP\sample.exe and waits for it to finish.
EDIT 2
Regarding the OP's comment on the order of the items in the [Run] section:
There are two possible cases:
You're using Inno Setup to perform the actual installation of your software (copying files, registry entries, etc.) and additionally need to run the installers for the prerequisites.
You've got a separate installer for your software as well, and just need Inno Setup to run the installers for the prerequisites AND your software.
For case 1:
You do not need to put the your EXE file into the [Run] section at all, except you'd like to allow the user to start your application after setup as seen in many setups using a checkbox ("Run XYZ now?"). In that case, use the following line for your EXE:
Filename: {app}\yourprogram.exe; StatusMsg: Run the application; Flags: postinstall skipifsilent unchecked; Description: Run the application now
For case 2:
I'd order the entries in the [Run] section according to their dependencies. That is: first entry is the one that some others depend upon, last entry is your application setup. But I'm not sure about the order in which the entries are handled.
This might be answered in the docs for the [Run] section. When in doubt, try asking Jordan Russel (Inno Setup's author) for advice - he's a nice guy and when I last mailed him he was pretty quick replying.