This is my first post, so please be gentle with me :)
I have created a Mobile application, using Visual Studio 2008 Professional. I used VB.NET as the language.
The App works OK, so I'm now looking to deploy it neatly. I've created a custom installer, and this works fine. The stuff that is working fine is described here, to give you a picture of where I've got to:
User will run a Setup.exe file on a desktop, which calls the MSI file, which deploys my cab file and resource files onto the Mobile device. The MSI file then uses a custom action to call a custom installer to invoke the ceappmgr to install the cab file on the device. This is all perfect.
However, I need to have two parameters specified at the point of installing the MSI onto the Desktop PC, and the Mobile application needs to reference those, so I need to ideally get these parameters to be present on the Mobile device as a parameter file. Any file would be fine, but XML makes most sense.
I have been able to collect these parameters by adding a new form in the user interface options of the MSI file. I think I am passing these correctly to my custom installer, but am struggling to work out how to debug this.
However, how do I take these parameters that have arrived in my custom installer class, and write them to a config file, which will find it's way onto the Mobile device?
I can find lots of tutorials on parts of this, but nothing that puts it all together. I'd be very grateful if someone could look at the 'ProblemPart' marked in the custom installer script below, and let me know where I'm going wrong !
<System.ComponentModel.RunInstaller(True)> Public Class SetupApp Inherits System.Configuration.Install.Installer
Private Const INI_FILE As String = "\setup.ini"
Private Sub Installer_AfterInstall(ByVal sender As Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles MyBase.AfterInstall
' ========== PROBLEM PART =============== Dim path As String = Context.Parameters("path") Dim Webservices As String = Context.Parameters("Webservices") Dim SoiWebservices As String = Context.Parameters("SoiWebservices") 'Now create an object writer to send the file to Dim objWriter As XmlTextWriter objWriter = New XmlTextWriter(path, System.Text.Encoding.Default) 'start writing the XML document objWriter.WriteStartDocument() 'starting with the root element objWriter.WriteStartElement("Parameters") objWriter.WriteElementString("WebServices", Webservices) objWriter.WriteElementString("SoiWebServices", SoiWebservices) objWriter.WriteEndElement() 'flush and write XML data to the file objWriter.Flush() objWriter.Close() objWriter = Nothing ' ========== PROBLEM PART ===============
'---to be executed when the application is installed--- Dim ceAppPath As String = GetWindowsCeApplicationManager() If ceAppPath = String.Empty Then Return End If Dim iniPath As String = GetIniPath() Process.Start(ceAppPath, iniPath)
End Sub
Private Sub Installer_AfterUninstall(ByVal sender As Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles MyBase.AfterUninstall '---to be executed when the application is uninstalled--- Dim ceAppPath As String = GetWindowsCeApplicationManager() If ceAppPath = String.Empty Then Return End If Dim iniPath As String = GetIniPath() Process.Start(ceAppPath, String.Empty) End Sub
Public Shared Function GetWindowsCeApplicationManager() As String '---check if the Windows CE Application Manager is installed--- Dim ceAppPath As String = KeyExists() If ceAppPath = String.Empty Then MessageBox.Show("Windows CE App Manager not installed", "Setup", MessageBoxButtons.OK, MessageBoxIcon.Error) Return String.Empty Else Return ceAppPath End If End Function
Public Shared Function GetIniPath() As String '---get the path of the .ini file--- Return """" & _ Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly. GetExecutingAssembly().Location), "Setup.ini") & """" End Function
Private Shared Function KeyExists() As String '---get the path to the Windows CE App Manager from the registry--- Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\ Microsoft\Windows\CurrentVersion\App Paths\CEAPPMGR.EXE") If key Is Nothing Then Return String.Empty Else Return key.GetValue(String.Empty, String.Empty) End If End Function End Class
[/Code]
Thanks in advance, and sorry for the ultra long post :)
path is the variable which is essentially: "[TARGETFILE]/Configfile.xml" from the MSI installer.
sysprowebservices and soiwebservices are the two variables entered during the installation onto the Desktop PC. These are the two strings of data that I somehow need to access from within the application.
Thanks again, and hope this isn't all as confusing for you as it is for me ;)
On Thu, 05 Nov 2009 01:58:35 GMT, "ian_morgan" <u55969@uwe> wrote: >Hi Forum,
>This is my first post, so please be gentle with me :)
>I have created a Mobile application, using Visual Studio 2008 Professional. I >used VB.NET as the language.
>The App works OK, so I'm now looking to deploy it neatly. I've created a >custom installer, and this works fine. The stuff that is working fine is >described here, to give you a picture of where I've got to:
>User will run a Setup.exe file on a desktop, which calls the MSI file, which >deploys my cab file and resource files onto the Mobile device. The MSI file >then uses a custom action to call a custom installer to invoke the ceappmgr >to install the cab file on the device. This is all perfect.
>However, I need to have two parameters specified at the point of installing >the MSI onto the Desktop PC, and the Mobile application needs to reference >those, so I need to ideally get these parameters to be present on the Mobile >device as a parameter file. Any file would be fine, but XML makes most sense.
>I have been able to collect these parameters by adding a new form in the user >interface options of the MSI file. I think I am passing these correctly to my >custom installer, but am struggling to work out how to debug this.
>However, how do I take these parameters that have arrived in my custom >installer class, and write them to a config file, which will find it's way >onto the Mobile device?
You could use RAPI (Remote API) to modify your setup program or write a new one that runs on the "desktop" and creates the file on the attached device. For native code, the relevant functions are CeCreateFile, CeWriteFile, and related. I don't use .NET, but assume at least one wrapper class exists.
----------------------------------------- To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
Robert E. Zaret, eMVP PenFact, Inc. 20 Park Plaza, Suite 400 Boston, MA 02116 www.penfact.com
>You could use RAPI (Remote API) to modify your setup program or write >a new one that runs on the "desktop" and creates the file on the >attached device. For native code, the relevant functions are >CeCreateFile, CeWriteFile, and related. I don't use .NET, but assume >at least one wrapper class exists.
Many thanks for this suggestion. I have been trying to do this all day, but haven't had much joy. I can only find examples that use c#, and I just can't seem to translate them to VB.NET at all.
I'm currently attempting another approach, to use CERegEditor in a 'command line' mode to post the parameters into the Mobile Devices Registry instead. Nearly got this working, but it will rely on the device being cradled when the software is installed.
Do you think the RAPI method would be better than this alternative method, and does anyone have any ideas how to make the RAPI method work in VB.NET?
>>You could use RAPI (Remote API) to modify your setup program or write >>a new one that runs on the "desktop" and creates the file on the >>attached device. For native code, the relevant functions are >>CeCreateFile, CeWriteFile, and related. I don't use .NET, but assume >>at least one wrapper class exists.
> Many thanks for this suggestion. I have been trying to do this all day, > but > haven't had much joy. I can only find examples that use c#, and I just > can't > seem to translate them to VB.NET at all.
> I'm currently attempting another approach, to use CERegEditor in a > 'command > line' mode to post the parameters into the Mobile Devices Registry > instead. > Nearly got this working, but it will rely on the device being cradled when > the software is installed.
> Do you think the RAPI method would be better than this alternative method, > and does anyone have any ideas how to make the RAPI method work in VB.NET?
Using the RAPI2 managed wrapper would certainly be easier in a .NET project. http://rapi2.codeplex.com.
Are you aware of the Visual Studio 2008 Smart Device CAB Project and CeAppMgr.exe ? CeAppMgr.exe would perform the installation for you from a desktop running ActiveSync/Windows Mobile Device Center. The CAB Project could contain your configuration files and EXE files. This solution does not require any programming.
Thanks for the suggestions. I am using the VS 2008 Smart Device CAB project to create the main CAB file, and this all works perfectly.
However, the configuration settings I mention need to be entered at the point of transferring the CAB onto the device, NOT at the point of creating the CAB in the first place. There don't seem to be any ways to do this using the standard VS 2008 installer.
As far as I can tell, RAPI requires the Mobile Device to be connected at the point of running the install. I'd much prefer it if the user can do the install offline, and sync up the device some time later. Is that true, or did I misunderstand that? Also, this seemed a bit complex for my brain, so I tried another method:
So far, my best option seems to be:
* Collect the parameters as part of the installer to load the installer app onto the host desktop. Include the 'cabwiz.exe' and 'cabwiz.ddf' files as files in the MSI installer package. * Pass the parameters into the cab custom installer. In the 'Custom Installer', have it write a '.inf' file to configure the creation of a second CAB file. This file should also contain the parameters formatted in a way to load them to registry settings on the device. Then have the custom installer write a cmd file which will call CABWIZ with the details of the .inf file. Then call the cmd file. * The cmd file runs, creates a CAB file with the registry settings in it. Then, a final part tells CEAPPMGR to install both the original Main CAB file, as well as the secondary config file. This imports the original CAB file with the man parameters, and then the secondary CAB file with the registry settings.
Works with the device in the cradle, or out.
Simples....
Must be a better way, but this does mean the install can be done without the device being cradled.
Or am I missing an obvious setting in VS 2008 ?
Any other suggestions?
Ian.
Trevor wrote: >>>You could use RAPI (Remote API) to modify your setup program or write >>>a new one that runs on the "desktop" and creates the file on the >[quoted text clipped - 21 lines]
>> Ian.
>Using the RAPI2 managed wrapper would certainly be easier in a .NET project. >http://rapi2.codeplex.com.
On Sun, 08 Nov 2009 23:14:57 GMT, "ian_morgan via PocketPCJunkies.com"
<u55969@uwe> wrote: >Hi Trevor,
>Thanks for the suggestions. I am using the VS 2008 Smart Device CAB project >to create the main CAB file, and this all works perfectly.
>However, the configuration settings I mention need to be entered at the point >of transferring the CAB onto the device, NOT at the point of creating the CAB >in the first place. There don't seem to be any ways to do this using the >standard VS 2008 installer.
>As far as I can tell, RAPI requires the Mobile Device to be connected at the >point of running the install.
Yep. RAPI runs on a desktop and manipulates files, registry, etc. on _attached_ device.
> I'd much prefer it if the user can do the >install offline,
How does the user get the installation file? When does the installer that calls CeAppMgr run? When does your installer prompt the user for info?
> and sync up the device some time later. Is that true, or did >I misunderstand that? Also, this seemed a bit complex for my brain, so I >tried another method:
>So far, my best option seems to be:
>* Collect the parameters as part of the installer to load the installer app >onto the host desktop. > Include the 'cabwiz.exe' and 'cabwiz.ddf' files as files in the MSI >installer package. >* Pass the parameters into the cab custom installer. > In the 'Custom Installer', have it write a '.inf' file to configure the >creation of a second CAB file. > This file should also contain the parameters formatted in a way to load >them to registry settings on the device. > Then have the custom installer write a cmd file which will call CABWIZ with >the details of the .inf file. > Then call the cmd file. >* The cmd file runs, creates a CAB file with the registry settings in it. > Then, a final part tells CEAPPMGR to install both the original Main CAB >file, as well as the secondary config file. > This imports the original CAB file with the man parameters, and then the >secondary CAB file with the registry settings.
>Works with the device in the cradle, or out.
>Simples....
>Must be a better way, but this does mean the install can be done without the >device being cradled.
>Or am I missing an obvious setting in VS 2008 ?
>Any other suggestions?
>Ian.
>Trevor wrote: >>>>You could use RAPI (Remote API) to modify your setup program or write >>>>a new one that runs on the "desktop" and creates the file on the >>[quoted text clipped - 21 lines]
>>> Ian.
>>Using the RAPI2 managed wrapper would certainly be easier in a .NET project. >>http://rapi2.codeplex.com.
----------------------------------------- To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
Robert E. Zaret, eMVP PenFact, Inc. 20 Park Plaza, Suite 400 Boston, MA 02116 www.penfact.com
Thanks for sticking with me :) The current method is now working, though it's a bit convoluted.
The ideal situation is: 1. Activesync, and my MSI installer would be installed initially by a system administrator at the point of configuring a new mobile device. (From disk, or over internet). Device does not have to be attached at this point. 2. The parameters are entered at the point of running my MSI for the main CAB installation onto the Desktop. (The parameters tell the application the URL of the main application server, so they are constant for all devices on one customer site). In the current method, CeAppMgr is called at this point, with a setup.ini file to tell ActiveSync to install the CAB's at the next Sync. 3. A device can then be docked (Now or later on) and the application will automatically be installed by Activesync (CeAppMgr), along with the parameters. 4. At any later point, if more mobile devices are docked, then the application would be installed to that device also.
The method I mention is doing this, and the only negative at the moment is the fact that the CMD script causes a DOS box to appear in the background, which looks a bit ugly.
It would be very interesting to know if there's a better way, as this does seem quite longwinded, but since it is working now, this is less critical than it was.
>[quoted text clipped - 8 lines] >>As far as I can tell, RAPI requires the Mobile Device to be connected at the >>point of running the install.
>Yep. RAPI runs on a desktop and manipulates files, registry, etc. on >_attached_ device.
>> I'd much prefer it if the user can do the >>install offline,
>How does the user get the installation file? When does the installer >that calls CeAppMgr run? When does your installer prompt the user for >info?
>> and sync up the device some time later. Is that true, or did >>I misunderstand that? Also, this seemed a bit complex for my brain, so I >[quoted text clipped - 41 lines] >>>Using the RAPI2 managed wrapper would certainly be easier in a .NET project. >>>http://rapi2.codeplex.com.
>----------------------------------------- >To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
>Robert E. Zaret, eMVP >PenFact, Inc. >20 Park Plaza, Suite 400 >Boston, MA 02116 >www.penfact.com
You could write a RAPI application that installs the CAB and the configuration file, and you can get that application to run whenever a user connects. So someone can install that RAPI program, the CAB file, and the configuration file on a customer's "desktop", and then when someone connects a device to that "desktop", the RAPI program will run and install the program and config file to the device. For info about triggering a RAPI program this way, see my 25 February 2003 contribution to a thread called "ActiveSync Module" in this newsgroup.
On Mon, 09 Nov 2009 19:39:01 GMT, "ian_morgan via PocketPCJunkies.com"
>Thanks for sticking with me :) The current method is now working, though it's >a bit convoluted.
>The ideal situation is: >1. Activesync, and my MSI installer would be installed initially by a system >administrator at the point of configuring a new mobile device. (From disk, or >over internet). Device does not have to be attached at this point. >2. The parameters are entered at the point of running my MSI for the main CAB >installation onto the Desktop. (The parameters tell the application the URL >of the main application server, so they are constant for all devices on one >customer site). In the current method, CeAppMgr is called at this point, with >a setup.ini file to tell ActiveSync to install the CAB's at the next Sync. >3. A device can then be docked (Now or later on) and the application will >automatically be installed by Activesync (CeAppMgr), along with the >parameters. >4. At any later point, if more mobile devices are docked, then the >application would be installed to that device also.
>The method I mention is doing this, and the only negative at the moment is >the fact that the CMD script causes a DOS box to appear in the background, >which looks a bit ugly.
>It would be very interesting to know if there's a better way, as this does >seem quite longwinded, but since it is working now, this is less critical >than it was.
>Thanks for following the thread :)
>Ian.
>r_z_aret@pen_fact.com wrote: >>>Hi Trevor,
>>[quoted text clipped - 8 lines] >>>As far as I can tell, RAPI requires the Mobile Device to be connected at the >>>point of running the install.
>>Yep. RAPI runs on a desktop and manipulates files, registry, etc. on >>_attached_ device.
>>> I'd much prefer it if the user can do the >>>install offline,
>>How does the user get the installation file? When does the installer >>that calls CeAppMgr run? When does your installer prompt the user for >>info?
>>> and sync up the device some time later. Is that true, or did >>>I misunderstand that? Also, this seemed a bit complex for my brain, so I >>[quoted text clipped - 41 lines] >>>>Using the RAPI2 managed wrapper would certainly be easier in a .NET project. >>>>http://rapi2.codeplex.com.
>>----------------------------------------- >>To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
>>Robert E. Zaret, eMVP >>PenFact, Inc. >>20 Park Plaza, Suite 400 >>Boston, MA 02116 >>www.penfact.com
----------------------------------------- To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
Robert E. Zaret, eMVP PenFact, Inc. 20 Park Plaza, Suite 400 Boston, MA 02116 www.penfact.com
I developed an app that utilizes a WCF service, I needed a config file to point to the WCF service. My mobile device is connecting to the WCF via coporate Wifi network.
-I created a config file within my mobile app and marked the file property "Copy to output directory" as 'Copy Always'
my TFS custom build script changes the WCF endpoint url based on which Client location I am building it out to.
-Within my Cab generator project I point to the mobileapp.config file from the build output location so that it will be included in the CAB.
When the CAB is installed on the device, the appropriate mobileapp.cofig is copied to the app folder on the device
- I also use a similar desktop setup project that you use and some custom actions to install the cab to the device.
Is this what you are trying to do?
r_z_are wrote:
I think I understand your description now. 10-Nov-09
I think I understand your description now.
You could write a RAPI application that installs the CAB and the configuration file, and you can get that application to run whenever a user connects. So someone can install that RAPI program, the CAB file, and the configuration file on a customer's "desktop", and then when someone connects a device to that "desktop", the RAPI program will run and install the program and config file to the device. For info about triggering a RAPI program this way, see my 25 February 2003 contribution to a thread called "ActiveSync Module" in this newsgroup.
----------------------------------------- To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
Robert E. Zaret, eMVP PenFact, Inc. 20 Park Plaza, Suite 400 Boston, MA 02116 www.penfact.com
It sounds similar, but I was confused about the line:
>my TFS custom build script changes the WCF endpoint url based on which Client location I am building it out to.
Are you entering the configuration file parameters at the point of installing the MSI on the Desktop, or at the point of creating the CAB?
It sounds like you're specifying the customer specific parameters at the point of creating the cab in Visual Studio, as opposed to this being a parameter entered by the user when installing the MSI.
To clarify how yours works, do you have to create different MSI files for different customers, or can you use one compiled MSI installer for all customers? (I'm looking for one MSI installer for everyone).
As I said though, the method above works, so it's really now an academic question to see what the best way is.
Yogesh Ramakrishnan wrote: >I developed an app that utilizes a WCF service, I needed a config file to point to the WCF service. My mobile device is connecting to the WCF via coporate Wifi network.
>-I created a config file within my mobile app and marked the file property "Copy to output directory" as 'Copy Always'
>my TFS custom build script changes the WCF endpoint url based on which Client location I am building it out to.
>-Within my Cab generator project I point to the mobileapp.config file from the build output location so that it will be included in the CAB.
>When the CAB is installed on the device, the appropriate mobileapp.cofig is copied to the app folder on the device
>- I also use a similar desktop setup project that you use and some custom actions to install the cab to the device.
>Is this what you are trying to do?
>r_z_are wrote:
>I think I understand your description now. >10-Nov-09
>I think I understand your description now.
>You could write a RAPI application that installs the CAB and the >configuration file, and you can get that application to run whenever a >user connects. So someone can install that RAPI program, the CAB file, >and the configuration file on a customer's "desktop", and then when >someone connects a device to that "desktop", the RAPI program will run >and install the program and config file to the device. For info about >triggering a RAPI program this way, see my 25 February 2003 >contribution to a thread called "ActiveSync Module" in this newsgroup.
>----------------------------------------- >To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).
>Robert E. Zaret, eMVP >PenFact, Inc. >20 Park Plaza, Suite 400 >Boston, MA 02116 >www.penfact.com