Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

What's the best way to change port of a web app programmatically?
newahkow
#1 Posted : Tuesday, October 18, 2011 2:36:15 AM(UTC)
Groups: Member
Joined: 10/11/2011(UTC)
Posts: 19

Thanks: 5 times
Was thanked: 1 time(s) in 1 post(s)
I tried the following to change the port of my web app, but it does not work:

Code:

WebAppConfigEntry webAppEntry = UWS.Configuration.Metabase.FindApplication(MyGuid);
ListenAddressList listenAddressList = webAppEntry.ListenAddresses;
foreach (ListenAddress listenAddress in listenAddressList) {
listenAddress.SystemAssignedPort = 99; // doesn't work
}
ListenAddress newAddress = new ListenAddress(100);
listenAddressList.Add(newAddress); // doesn't work too


Should I just re-register the same app with different port using UWS.RegApp.exe or call UWS.Configuration.Metabase.RegisterApplication?

Thank you very much.
Ultidev Team
#2 Posted : Tuesday, October 18, 2011 9:35:53 AM(UTC)
Ultidev Team

Groups: Administration
Joined: 11/3/2005(UTC)
Posts: 2,253

Thanks: 28 times
Was thanked: 60 time(s) in 59 post(s)
Hi there!

Before we start, we'd like to point out that we have found a bug that makes installers using UWS configuration .NET API break after UWS was upgraded on the system where your application is installer. For example, if your application installer is build with UWS.Configuratio API build 11, and the application is getting installed on a system where UWS build 12 is already installed, your installer will fail. Or, if you installed your app and UWS build 11 on a clean machine, then UWS was upgraded, and then your try to uninstall/upgrade your application - the installer will fail when trying to unregister the application. We are working on the fix and hope to make it in time for the release 12 of UWS. Again, this affects only installers using UWS config API, not installers using UWS.AppReg.exe utility.

Here's the sample that illustrates the basics of application registration (see also attached sample project):
Code:
private static void RegTheApp()
{
WebAppConfigEntry app = Metabase.GetWebAppEntry(new Guid("{1C0ACD4F-078C-42af-8357-146F9DEC94DC}"), false);
app.VirtualDirectory = "/";
app.ListenAddresses.Add(new ListenAddress(15843));
app.PhysicalDirectory = @"C:\inetpub\wwwroot";
app.DefaultDocument = "iisstart.htm";
app.ApplicationName = "Port assignment test";

Metabase.RegisterApplication(RuntimeVersion.AspNet_1_2or3x, false, app);
}


The correct way to start is to use Metabase.GetWebAppEntry() method, which will find an existing one, or uninstalled, or if not, will create a new web app etnry. System-assigned port should not be used. Otherwise you were on the right track. Please also note that registering applications requires your registration program to have elevated/administrative privileges.

Please let us know if this information was helpful.

Best regards,
UltiDev Team.
File Attachment(s):
UwsAppPortRegSample.zip (9kb) downloaded 129 time(s).
Please donate at http://www.ultidev.com/products/Donate.aspx to help us improve our products.
1 user thanked Ultidev Team for this useful post.
newahkow on 10/19/2011(UTC)
newahkow
#3 Posted : Wednesday, October 19, 2011 2:02:36 AM(UTC)
Groups: Member
Joined: 10/11/2011(UTC)
Posts: 19

Thanks: 5 times
Was thanked: 1 time(s) in 1 post(s)
Thanks, I assign SystemAssignedPort before registering, so that I can retrieve back the port later without parsing ListenAddress:
Code:

WebAppConfigEntry app = Metabase.GetWebAppEntry(MyGuid, false);
app.ApplicationName = "My Web";
app.DefaultDocument = "default.aspx";
app.VirtualDirectory = "/";
app.PhysicalDirectory = "@c:\\test";
app.AppType = ApplicationType.AspNetOrStaticHtml;
app.ListenAddresses.Clear();
ListenAddress listenAddress = new ListenAddress(port);
listenAddress.SystemAssignedPort = port;
app.ListenAddresses.Add(listenAddress);
Metabase.RegisterApplication(RuntimeVersion.AspNet_4, false, app);


There is a misleading message when Metabase.RegisterApplication is called by a non-administrator though:
Code:

Unable to register application because not all required application settings are specified:
Listen endpoints are not specified

Ultidev Team
#4 Posted : Wednesday, October 19, 2011 8:44:14 AM(UTC)
Ultidev Team

Groups: Administration
Joined: 11/3/2005(UTC)
Posts: 2,253

Thanks: 28 times
Was thanked: 60 time(s) in 59 post(s)
Hi there!

- Assigning SystemAssignedPort is a very bad idea. This property is used for internal purposes which are not what you you are using it for. It's used for when an application is registered on a system-assigned free TCP port when you use "http://*:0/" listen endpoint. Please do not use SystemAssignedPort. Instead if you tell us what you are trying to accomplish, we'll be happy to suggest a better way to do it.

- Thank you for reporting this issue. We have found it too, and starting from build 12 an attempt to run registration from non-admin/elevated account will throw meaningful exception. We have also modified our sample project attached to our previous post to include manifest that requires elevation for the EXE.

Best regards,
UltiDev Team.
Please donate at http://www.ultidev.com/products/Donate.aspx to help us improve our products.
newahkow
#5 Posted : Wednesday, October 19, 2011 7:59:49 PM(UTC)
Groups: Member
Joined: 10/11/2011(UTC)
Posts: 19

Thanks: 5 times
Was thanked: 1 time(s) in 1 post(s)
Ultidev Team;3106 wrote:

- Assigning SystemAssignedPort is a very bad idea. This property is used for internal purposes which are not what you you are using it for. It's used for when an application is registered on a system-assigned free TCP port when you use "http://*:0/" listen endpoint. Please do not use SystemAssignedPort. Instead if you tell us what you are trying to accomplish, we'll be happy to suggest a better way to do it.


My application allow users to change their web app port. And I need to show the currently assigned port. I want to avoid parsing ListenAddress.RawAddress (eg: "http://*:1234/") and I noticed that SystemAssignedPort (if I didn't set it to 0) has the currently assigned port.
Ultidev Team
#6 Posted : Wednesday, October 19, 2011 10:24:40 PM(UTC)
Ultidev Team

Groups: Administration
Joined: 11/3/2005(UTC)
Posts: 2,253

Thanks: 28 times
Was thanked: 60 time(s) in 59 post(s)
Hi there!

You can get to the port of ListenAddress using one of the ListenAddress.GetUri() overloads. Returned Uri class has port property you can use. SystemAssignedPort property is not documented and may go away. Using the method above will allow getting current port information regardless whether you used system-assigned port or not.

Also, just to share good news, starting with build 12, programs like yours - that reference earlier versions of UWS.Configuration API assembly, will not be broken by upgrading UWS. Currently if your installer references UWS.Cunfiguration build 10, and user has UWS build 11 installed, your installer will fail when attempting to register or unregister. Starting with build 12 all new versions of config API will seamlessly replace the old one.

Best regards,
UltiDev Team.
Please donate at http://www.ultidev.com/products/Donate.aspx to help us improve our products.
1 user thanked Ultidev Team for this useful post.
newahkow on 10/19/2011(UTC)
newahkow
#7 Posted : Wednesday, October 19, 2011 11:02:42 PM(UTC)
Groups: Member
Joined: 10/11/2011(UTC)
Posts: 19

Thanks: 5 times
Was thanked: 1 time(s) in 1 post(s)
Thanks, just to share my updated code

Registering web app:
Code:

WebAppConfigEntry app = Metabase.GetWebAppEntry(MyGuid, false);
app.ApplicationName = "My Web";
app.DefaultDocument = "default.aspx";
app.VirtualDirectory = "/";
app.PhysicalDirectory = "@c:\\test";
app.AppType = ApplicationType.AspNetOrStaticHtml;
app.ListenAddresses.Clear();
ListenAddress listenAddress = new ListenAddress(port);
app.ListenAddresses.Add(listenAddress);
Metabase.RegisterApplication(RuntimeVersion.AspNet_4, false, app);


Get port of web app:
Code:

public static int GetWebAppPort() {
int defaultPort = 81;
WebAppConfigEntry webAppEntry = Metabase.FindApplication(MyGuid);
if (webAppEntry == null) {
return defaultPort;
}
ListenAddressList listenAddressList = webAppEntry.ListenAddresses;
if (listenAddressList.Count > 0) {
string host;
Uri uri = listenAddressList[0].GetUri(out host);
return uri.Port;
}
return defaultPort;
}


P/S: You really need to fix the "code" BB code.
Ultidev Team
#8 Posted : Thursday, October 20, 2011 8:55:40 AM(UTC)
Ultidev Team

Groups: Administration
Joined: 11/3/2005(UTC)
Posts: 2,253

Thanks: 28 times
Was thanked: 60 time(s) in 59 post(s)
Thank you!

Please be cautious when defaulting to port 80. It's often taken by other web servers; sometimes in port-sharing mode, like IIS 6 and 7, which may preclude UWS from being able to listen at http://*:80/.

Best regards,
UltiDev Team.
Please donate at http://www.ultidev.com/products/Donate.aspx to help us improve our products.
newahkow
#9 Posted : Monday, October 24, 2011 5:19:38 AM(UTC)
Groups: Member
Joined: 10/11/2011(UTC)
Posts: 19

Thanks: 5 times
Was thanked: 1 time(s) in 1 post(s)
Hi, RegisterApplication will throw the same error when port is being used by others or another UltiDev web application:
Code:

Unable to register application because not all required application settings are specified:
Listen endpoints are not specified

Ultidev Team
#10 Posted : Monday, October 24, 2011 10:12:17 AM(UTC)
Ultidev Team

Groups: Administration
Joined: 11/3/2005(UTC)
Posts: 2,253

Thanks: 28 times
Was thanked: 60 time(s) in 59 post(s)
Hi!

There are two situation in which an application may be unable to get to listen at a given endpoint:
1. Desired TCP port is used in exclusive mode by some other application. In this case no other application can do anything with this port.
2. Another HTTP.SYS application in port-sharing mode listens to the same endpoint. For example, a mere presence of IIS 6 or 7 will occupy http://*:80/ endpoint. You can listen to http://*:80/somUniqueVdir/, or on a free port.

The bottom line is that when you are installing your application on customers' machines do not assume that users can correctly say which port is free, and even if port looks free, given endpoint may be not free.

Because of all that we recommend the following:
- Use virtual directory with a name that is likely to be unique. On machines with no web server, or with IIS 6 and 7, you will be able to put it on port 80, although it won't work on boxes with IIS 5 because IIS 5 does not share ports.
- Register the application multiple endpoints.
- The most important one: always use http://*:0/ endpoint regardless whether you have other endpoint or not. UWS redirector, which is accessible at http://localhost:7756/GoToApplication.aspx/<APPGUID>/, will redirect to your application no matter what it's location.

Finally, if there is another UWS application using an endpoint, you cannot take the endpoint away from that application by registering your application on the same endpoint.

Please let us know if this information was helpful.

Best regards,
UltiDev Team.
Please donate at http://www.ultidev.com/products/Donate.aspx to help us improve our products.
Rss Feed  Atom Feed
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You can vote in polls in this forum.