[Slim-Checkins] r11852 - in /branches/6.5: platforms/win32/SlimTray.pl server/Slim/Utils/Prefs.pm
adrian at svn.slimdevices.com
adrian at svn.slimdevices.com
Sat Apr 28 10:16:35 PDT 2007
Author: adrian
Date: Sat Apr 28 10:16:34 2007
New Revision: 11852
URL: http://svn.slimdevices.com?rev=11852&view=rev
Log:
Bug: 4748, 4898, 4899, 4905 potential improvements
Description: Hopefully improve operation on Vista when running UAC
- prefs and server url moved to location which is not virtualised by
Vista (as per r11828)
- modify options available in SlimTray when run as a user - don't show
options which require installing/starting/stopping a service, start
manually as an app rather than service
- add info menu option that SlimTray can be started with "run as admin" to
enable all previous options
Note this version will not stop mysqld when run as a user and the
server is stopped. To do this would require killing a process called
'mysqld' without knowing whether this is the slim mysqld!
Modified:
branches/6.5/platforms/win32/SlimTray.pl
branches/6.5/server/Slim/Utils/Prefs.pm
Modified: branches/6.5/platforms/win32/SlimTray.pl
URL: http://svn.slimdevices.com/branches/6.5/platforms/win32/SlimTray.pl?rev=11852&r1=11851&r2=11852&view=diff
==============================================================================
--- branches/6.5/platforms/win32/SlimTray.pl (original)
+++ branches/6.5/platforms/win32/SlimTray.pl Sat Apr 28 10:16:34 2007
@@ -31,6 +31,19 @@
use Win32::TieRegistry ('Delimiter' => '/');
use Win32::Service;
+
+# Vista only:
+#
+# When running on Vista SlimTray may be run as a normal user or as administrator depending on how it is started
+# With the default install it will run as admin the first time when launched from the installer, all subsequent times it will
+# run as a normal user. Vista UAC means that we can only install windows services and start/stop them when running as admin.
+# To avoid user confusion we therefore disable all options which are not available when running as a normal user.
+#
+# prefs and the Slimserver url are stored in a different location on Vista to avoid Vista file virtualisation.
+
+my $vista = ((Win32::GetOSName())[0] =~ /Vista/); # running on Vista
+my $vistaUser = $vista && !Win32::IsAdminUser(); # running on Vista as a user (not admin) - reduce menu options
+
my $timerSecs = 10;
my $ssActive = 0;
my $starting = 0;
@@ -46,7 +59,8 @@
my $serviceName = 'slimsvc';
my $sqlServiceName = 'SlimServerMySQL';
-my $appExe = File::Spec->catdir(baseDir(), 'server', 'slim.exe');
+my $appExe = File::Spec->catdir(installDir(), 'server', 'slim.exe');
+my $serverUrl = File::Spec->catdir(writableDir(), "SlimServer Web Interface.url");
my $errString = 'SlimServer Failed. Please see the Event Viewer & Contact Support';
@@ -56,16 +70,22 @@
sub PopupMenu {
my @menu = ();
+ my $type = startupType(); # = none, login, manual or auto
+
+ # As a user on Vista we only allow the following as these are all a user can perform:
+ # - starting/stopping of the server if type is none, login
+ # - toggling of startup type between login and none
+
if ($ssActive) {
push @menu, ["*Open SlimServer",\&openSlimServer];
push @menu, ["--------"];
- push @menu, ["Stop SlimServer", \&stopSlimServerMySQL];
+ push @menu, ["Stop SlimServer", \&stopSlimServerMySQL] if (!$vistaUser || $type =~ /none|login/);
}
elsif ($starting) {
push @menu, ["Starting SlimServer...", ""];
}
else {
- push @menu, ["*Start SlimServer", \&startSlimServer];
+ push @menu, ["*Start SlimServer", \&startSlimServer] if (!$vistaUser || $type =~ /none|login/);
}
my $serviceString = 'Automatically run at system start';
@@ -84,31 +104,35 @@
$setLogin = sub { setStartupType('login') };
}
- # Startup can be in one of three states: At boot (service), at login
- # (app), or Off, which leaves the service installed in a manual state.
- my $type = startupType();
-
if ($type eq 'login') {
- push @menu, ["_ $serviceString", $setAuto, undef];
+ push @menu, ["_ $serviceString", $setAuto, undef] unless $vistaUser;
push @menu, ["v $appString", $setManual, 1];
} elsif ($type eq 'auto') {
- push @menu, ["v $serviceString", $setManual, 1];
+ push @menu, ["v $serviceString", $setManual, 1] unless $vistaUser;
+ push @menu, ["_ $appString", $setLogin, undef] unless $vistaUser;
+
+ } else {
+
+ push @menu, ["_ $serviceString", $setAuto, undef] unless $vistaUser;
push @menu, ["_ $appString", $setLogin, undef];
-
- } else {
-
- push @menu, ["_ $serviceString", $setAuto, undef];
- push @menu, ["_ $appString", $setLogin, undef];
- }
+ }
+
+ push @menu, ["Additional Options", \&vistaHelp] if $vistaUser;
push @menu, ["--------"];
push @menu, ["Go to Web Site", "Execute 'http://www.slimdevices.com'"];
push @menu, ["E&xit", "exit"];
-
+
return \@menu;
+}
+
+sub vistaHelp {
+ my $msg = "As you are running on Windows Vista some menu options are disabled.\nRestart with 'Run as administrator' to access all options.";
+
+ MessageBox($msg, "SlimServer", MB_OK | MB_ICONINFORMATION);
}
# Called when the tray application is invoked again. This can handle
@@ -158,7 +182,7 @@
# If we were waiting for SS to start before this check, show the SS home page.
if (checkForHTTP()) {
- Execute("SlimServer Web Interface.url");
+ Execute($serverUrl);
} else {
@@ -169,7 +193,7 @@
$checkHTTP = 0;
- Execute("SlimServer Web Interface.url");
+ Execute($serverUrl);
}
# Check if user has requested to stop SlimServer And MySQL
@@ -181,19 +205,17 @@
if (scalar keys %status != 0) {
- # Service already stopped
if ($status{'CurrentState'} == 1) {
- $stopMySQL = 0;
- return;
- }
-
- if (Win32::Service::StopService('', $sqlServiceName)) {
-
- $stopMySQL = 0;
- return;
+ # Service already stopped
+
+ } elsif (Win32::Service::StopService('', $sqlServiceName)) {
+
+ # Sucessfully stopped service
} else {
+
+ # Service running which we can't stop
my $t = 'GetStatus Failed';
@@ -208,7 +230,6 @@
}
}
- # MySQL service is not running - perhaps slimserver is started at system level.
$stopMySQL = 0;
}
}
@@ -237,19 +258,22 @@
# Add paths if they don't exist.
my $startupType = startupType();
- if ($startupType eq 'none') {
+ if (!$startupType) {
+
+ # NB running Vista as a user means we can't read this - we hope the first run is as admin
+ my $serviceStart = $Registry->{"LMachine/SYSTEM/CurrentControlSet/Services/$serviceName/Start"};
my $cKey = $Registry->{'CUser/Software/'};
my $lKey = $Registry->{'LMachine/Software/'};
$cKey->{'SlimDevices/'} = {
'SlimServer/' => {
- '/StartAtBoot' => 0,
+ '/StartAtBoot' => ($serviceStart && oct($serviceStart) == 2) ? 1 : 0,
'/StartAtLogin' => 0,
},
};
- $lKey->{'SlimDevices/'} = { 'SlimServer/' => { '/Path' => baseDir() } };
+ $lKey->{'SlimDevices/'} = { 'SlimServer/' => { '/Path' => installDir() } };
}
# If we're set to Start at Login, do it, but only if the process isn't
@@ -281,10 +305,15 @@
} else {
# Don't launch the browser if we start at login time.
- Execute("SlimServer Web Interface.url");
+ Execute($serverUrl);
}
$cliStart = 0;
+ }
+
+ if ($vistaUser && !$ssActive && $startupType eq 'auto') {
+ # running as a user on Vista so we can't start a service, fallback to running as an app
+ setStartupType('none');
}
}
@@ -329,8 +358,12 @@
if (!Win32::Service::StartService('', $serviceName)) {
- # can't start as a service - try starting as a process
- runBackground($appExe);
+ showErrorMessage("Starting $errString");
+
+ $starting = 0;
+ $ssActive = 0;
+
+ return;
}
} else {
@@ -349,11 +382,16 @@
sub stopSlimServer {
- if (startupTypeIsService() && Win32::Service::StopService('', $serviceName)) {
-
- # service stopped
-
- } else {
+ if (startupTypeIsService()) {
+
+ if (!Win32::Service::StopService('', $serviceName)) {
+
+ showErrorMessage("Stopping $errString");
+
+ return;
+ }
+
+ } else {
my $pid = processID();
@@ -380,7 +418,7 @@
# Check HTTP first in case slimserver has changed the HTTP port while running
checkForHTTP ();
- Execute("SlimServer Web Interface.url");
+ Execute($serverUrl);
}
sub stopSlimServerMySQL {
@@ -414,6 +452,10 @@
my $atBoot = $Registry->{"$registryKey/StartAtBoot"};
my $atLogin = $Registry->{"$registryKey/StartAtLogin"};
+ if (!defined $atBoot || !defined $atLogin) {
+ return undef;
+ }
+
if ($atLogin) {
return 'login';
}
@@ -427,6 +469,11 @@
# Start of 2 is auto, 3 is manual.
return oct($serviceStart) == 2 ? 'auto' : 'manual';
}
+
+ if ($vistaUser) {
+ # Vista users can't read the registry key for $serviceStart - assume auto [we can't manually start the service]
+ return 'auto';
+ }
}
return 'none';
@@ -472,7 +519,7 @@
}
# Return the SlimServer install directory.
-sub baseDir {
+sub installDir {
# Try and find it in the registry.
# This is a system-wide registry key.
@@ -483,20 +530,31 @@
}
# Otherwise look in the standard location.
- my $baseDir = File::Spec->catdir('C:\Program Files', 'SlimServer');
+ my $installDir = File::Spec->catdir('C:\Program Files', 'SlimServer');
# If it's not there, use the current working directory.
- if (!-d $baseDir) {
-
- $baseDir = cwd();
- }
-
- return $baseDir;
+ if (!-d $installDir) {
+
+ $installDir = cwd();
+ }
+
+ return $installDir;
+}
+
+# Return directory for files which Slimserver can save - i.e. location of prefs file
+# This is the server dir unless we are running on Vista when it is %ALLUSERSPROFILE%\SlimServer
+sub writableDir {
+
+ if ($vista) {
+ return File::Spec->catdir($ENV{'ALLUSERSPROFILE'}, 'SlimServer');
+ }
+
+ return File::Spec->catdir(installDir(), 'server');
}
sub checkForHTTP {
- my $prefFile = File::Spec->catdir(baseDir(), 'server', 'slimserver.pref');
+ my $prefFile = File::Spec->catdir(writableDir(), 'slimserver.pref');
my $httpPort = 9000;
# Quick and dirty finding of the httpport. Faster than loading YAML.
@@ -608,18 +666,16 @@
# One parameter the new port number
sub updateSlimServerWebInterface {
- my $port = shift;
-
- my $urlfile = File::Spec->catfile(baseDir(), "SlimServer Web Interface.url");
-
- if (open(URLFILE, ">:crlf", $urlfile)) {
+ my $port = shift;
+
+ if (open(URLFILE, ">:crlf", $serverUrl)) {
print URLFILE "[InternetShortcut]\nURL=http://127.0.0.1:$port\n";
close URLFILE;
} else {
- showErrorMessage("Can't open to write to $urlfile: $!");
+ showErrorMessage("Can't open to write to $serverUrl: $!");
}
}
Modified: branches/6.5/server/Slim/Utils/Prefs.pm
URL: http://svn.slimdevices.com/branches/6.5/server/Slim/Utils/Prefs.pm?rev=11852&r1=11851&r2=11852&view=diff
==============================================================================
--- branches/6.5/server/Slim/Utils/Prefs.pm (original)
+++ branches/6.5/server/Slim/Utils/Prefs.pm Sat Apr 28 10:16:34 2007
@@ -1048,6 +1048,18 @@
if (Slim::Utils::OSDetect::OS() eq 'win') {
$prefsFile = catdir($pref_path, 'slimserver.pref');
+
+ # copy over old prefs file to new location on Vista, excluding cachedir (which is moved too)
+ if (!-r $prefsFile && Slim::Utils::OSDetect::details->{'osName'} =~ /Vista/ && -r catdir($Bin, 'slimserver.pref')) {
+ open OLD, catdir($Bin, 'slimserver.pref');
+ open NEW, ">$prefsFile";
+ while (my $line = <OLD>) {
+ print NEW $line unless $line =~ /cachedir/;
+ }
+ close OLD;
+ close NEW;
+ }
+
} elsif (Slim::Utils::OSDetect::OS() eq 'mac') {
$prefsFile = catdir($pref_path, 'slimserver.pref');
} else {
More information about the checkins
mailing list