Closed mphill closed 10 months ago
A quick update, this is working on master now.
However, iOS and MacOS apps are not supported.
if (_configuration == null)
{
#if NETSTANDARD
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
_configuration = new RegistryConfiguration(_appReferenceAssembly);
}
else
{
_configuration = new JSONConfiguration(_appReferenceAssembly);
}
#else
_configuration = new RegistryConfiguration(_appReferenceAssembly);
#endif
}
Are you Ok if I do a pull request to add an InfoPlistConfiguration?
On iOS and MacOS Info.plist is the analog to AssemblyInfo in some respects.
protected Configuration(string referenceAssembly, bool isReflectionBasedAssemblyAccessorUsed)
{
// set default values
InitWithDefaultValues();
// set the value
UseReflectionBasedAssemblyAccessor = isReflectionBasedAssemblyAccessorUsed;
// save the reference assembly
ReferenceAssembly = referenceAssembly;
try
{
// set some value from the binary
AssemblyAccessor accessor = new AssemblyAccessor(referenceAssembly, UseReflectionBasedAssemblyAccessor);
ApplicationName = accessor.AssemblyProduct;
InstalledVersion = accessor.AssemblyVersion;
}
catch
{
CheckForUpdate = false;
}
}
This code would need to be refactored to abstract the AssemblyAccessor out.
Yes, you'd be welcome to open a PR. A few things, though:
JSONConfiguration
use, since we won't be able to write to the Info.plist file. However, a better way to do this would be to implement a new IAssemblyAccessor
implementation that reads from Info.plist
, since the JSONConfiguration
should work fine for everything else. We'd need some way to pass in the appropriate AssemblyAccessor
to the Configuration
subclass, which might take a little more work. (The configuration classes need read/write capabilities and store info on when updates were checked, etc. The assembly accessor classes just give info on the actual assembly and only need read permissions.)If you're working on it, why don't you do an IAssemblyAccessor
subclass that reads from Info.plist? I would need a little more time to see how to do the other work.
Edit: Also, believe it or not, Microsoft.Win32.Registry
targets .NET Standard
!
If you're on macOS, I highly recommend using Sparkle instead of this lib
Thanks for the recommendation, but maintaining native bindings has its own set of issues, and it can be very time consuming. I'd like to explore what supporting Xamarin (Mac, Android, iOS) apps might look like. Using sharpie to generate ApiDefintions is very tedious.
If you're working on it, why don't you do an IAssemblyAccessor subclass that reads from Info.plist?
I can do this, but in order to read the Info.plist at runtime, I would need to add Xamarin.Mac as a dependency in order to call NSBundle.MainBundle.ObjectForInfoDictionary
i.e.
public string AssemblyVersion => GetInfoPlistValue("CFBundleShortVersionString");
private string GetInfoPlistValue(string identifier)
{
return NSBundle.MainBundle.ObjectForInfoDictionary(identifier).ToString();
}
I doubt you want Xamarin as a project dependency, is there a way to pass this in somehow. I didn't see anything obvious in code.
JSONConfiguration is not public so I can't access that in the main project - but also it reeds from the file system. In Xamarin apps you'd want to use app preferences or NSUserDefaults
Is there a way to allow a developer manually create something to pass in the constructor like an IConfiguration
Thanks for the recommendation, but maintaining native bindings has its own set of issues, and it can be very time consuming. I'd like to explore what supporting Xamarin (Mac, Android, iOS) apps might look like. Using sharpie to generate ApiDefintions is very tedious.
Understood.
Is there a way to allow a developer manually create something to pass in the constructor like an IConfiguration
You can set SparkleUpdater.Configuration = myConfig;
(see here) or do something like
var sparkle = new SparkleUpdater(...)
{
Configuration = new MyConfig()
};
Just don't call the default constructor in the subclass for now.
Hm...regarding Info.plist: I don't see yet why we couldn't just read that in as XML. We don't really need a lib for reading that file, do we?
Regarding NSUserDefaults
-- I can see why we'd need a dependency for this one. I don't know of a way to do this without some sort of native code. I am not unopposed to adding a NetSparkleUpdater.XamarinMac
project or similar that has the extra dependency in it along with special Configuration
or other classes that are specific to Xamarin
. That way it's not a dependency in the main project.
(I have to apologize, here: normally I'd do a bit more research on my end, but life is very busy right now, and I don't have a lot of time during the work week for extra things. I've not used Xamarin before, so I am depending on your experience here.)
Hm...regarding Info.plist: I don't see yet why we couldn't just read that in as XML. We don't really need a lib for reading that file, do we?
I think that would work. I thought in the past I saw binary data in the info.plist once compiled, but looking around I don't see it. I think parsing the info.plist as xml works, but if you add a new project it could all be done with native calls.
I would propose this, a new project named:
NetSparkleUpdater.Xamarin
with NetSparkleUpdater
as a reference.
It would hold OS specific implications for iOS and MacOS to start, with Android added a little later as I find time.
In the main project I think there would be compiler directive to do this:
#if __MACOS__ || __IOS__
using NetSparkleUpdater.Xamarin;
#endif
...
#if __MACOS__ || __IOS__
_configuration = new PListInfoConfiguration(_appReferenceAssembly); // class located in NetSparkleUpdater.Xamarin
#endif
Thoughts?
NetSparkleUpdater.Xamarin
sounds fine along with the ref. You don't need to touch the main project though since you can set the Configuration
property on SparkleUpdater
without SparkleUpdater
needing to know about the extra refs.
Posted this in PR #98 too, but for historical reference regarding referencing Xamarin in VS:
I'll try to look at the Xamarin.Mac thing too. I do have a Mac on hand and can take a look, I think. Perhaps if the project were created on macOS then referenced from the SLN manually? I'm not opposed to having a separate SLN if we have to. I did a quick test, and a Xamarin library project can reference the latest previews of NetSparkle on macOS, so it should be possible...
I was able to add a Xamarin project to the solution from Visual Studio for macOS. Visual Studio on Windows is complaining on my end, but no big deal.
I had to run a manual dotnet restore
from within src/NetSparkle
before Visual Studio for macOS would build the Xamarin DLL project.
Once things are working, a new GitHub action can be set up to build and deploy that package to NuGet.
So, I would actually recommend a few things. Configuration
classes, as they are right now, are more for saving and loading the info on last version seen, etc. The IAssemblyAccessor
classes are used by Configuration
subclasses to load things. So, I think the following needs to happen for Xamarin support:
PListInfoAccessor
class -- implements IAssemblyAccessor
and grabs data from the PListNSUserDefaultsConfiguration
class -- subclasses Configuration
and saves/loads data from NSUserDefaults
.Configuration
(and subclasses) to accept an IAssemblyAccessor
so that the user can determine how product/company/version/etc. properties are loaded rather that Configuration
thinking it knows all.
JSONConfiguration
(store on disk as JSON) or the NSUserDefaultsConfiguration
.NetSparkleUpdater.Xamarin
NuGet NetSparkleUpdater.Xamarin
packageGiven that all Xamarin support is ending on May 1, 2024 (https://dotnet.microsoft.com/en-us/platform/support/policy/xamarin), and no one else has asked for this nor helped to contribute code to this, I don't see the point of adding this to the NetSparkle library at this time. :)
Running a Xamarin.mac app that uses NetSparkle crashes on instantiation of NetSparkle with version 2.0 with the exception:
Attribute of type System.Reflection.AssemblyProductAttribute
Supporting NetSparkle on Xamarin.mac would be a great addition. I noticed the core package has some windows specific references like
Microsoft.Win32.Registry
. If that was moved from the core package and into the Windows specific UI implementation it would allow NetSparkle to be used on Linux, Mac, Windows and maybe even iOS/Android (In-app dialogs about new versions).Thanks.