Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
crashdome
Jun 28, 2011
You could create a notification property like IsBusy and make the setter private. I do this because I usually want to disable more than one control/button.

Edit: Can't do code on my phone worth a drat. Basically make a property IsBusy and hook it up to OnNotifyPropChanged. Set it during any of your background tasks and change your RelayCommand enabled code to just check that property.

crashdome fucked around with this message at 23:27 on Oct 16, 2015

Adbot
ADBOT LOVES YOU

Sedro
Dec 31, 2008
You should fire ICommand.CanExecuteChanged (your RelayCommand may or may not have an API to fire it)

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


crashdome posted:

You could create a notification property like IsBusy and make the setter private. I do this because I usually want to disable more than one control/button.

Edit: Can't do code on my phone worth a drat. Basically make a property IsBusy and hook it up to OnNotifyPropChanged. Set it during any of your background tasks and change your RelayCommand enabled code to just check that property.

Oh yeah, that'd work, thanks.

I was trying to skip the extra property by monitoring the Task directly. Doesn't work so well when properties of Task don't trigger INPC...

This is what I get for trying to actually be productive on a Friday :saddowns:

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost
I'm having an issue with a C++ library in a UWP. In VLC for Windows Store, we have a wrapper library in C++ that interacts with LibVLC (for handling video, audio, all that jazz). Right now there is a Windows 8 and a Windows Phone 8.1 version, with a shared base, each assigned to the correct universal project. In our UWP solution currently, the desktop X86 version points to the Windows 8.1 x86 version, the phone pointing to the Windows Phone 8.1 ARM version. Others on the team think that just recompiling these existing libraries should just work on UWP. However, if I try that, I get this:

code:
System.BadImageFormatException occurred
  HResult=-2147024703
  Message= is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)
  Source=mscorlib
  StackTrace:
       at System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD)
       at libVLCX.Instance..ctor(IList`1 argv, SwapChainPanel panel)
       at VLC_WinRT.Services.RunTime.VLCService.Initialize(Object panel)
  InnerException: 
Now, those other wrapper use Windows 8.1 specific APIs that are not in UWP, so even if they did work, I think there would still be issues anyway. If I try and make a C++ UWP library with the same code, I still get the same error as above. I'm not sure what I'm doing wrong. Any ideas?

Polio Vax Scene
Apr 5, 2009



What would be the best way to have a .net 3.5 console app communicate with a .net 4.0 console app?

RICHUNCLEPENNYBAGS
Dec 21, 2010

Manslaughter posted:

What would be the best way to have a .net 3.5 console app communicate with a .net 4.0 console app?

Do they run on the same machine? PowerShell may be an option.

ljw1004
Jan 18, 2005

rum

Drastic Actions posted:

I'm having an issue with a C++ library in a UWP. In VLC for Windows Store, we have a wrapper library in C++ that interacts with LibVLC (for handling video, audio, all that jazz). Right now there is a Windows 8 and a Windows Phone 8.1 version, with a shared base, each assigned to the correct universal project. In our UWP solution currently, the desktop X86 version points to the Windows 8.1 x86 version, the phone pointing to the Windows Phone 8.1 ARM version. Others on the team think that just recompiling these existing libraries should just work on UWP. However, if I try that, I get this:

System.BadImageFormatException (in VLC_WinRT.Services.RunTime.VLCService.Initialize

Now, those other wrapper use Windows 8.1 specific APIs that are not in UWP, so even if they did work, I think there would still be issues anyway. If I try and make a C++ UWP library with the same code, I still get the same error as above. I'm not sure what I'm doing wrong. Any ideas?

Drastic, I find your post confusing, so I'm going to spell out the basics.

(1) Understand that the "Win10 Desktop" operating system has a set of WinRT APIs. This set of APIs is equal to "UWP + DesktopExtensionSDK". Likewise, the "Win10 Mobile" operating system has a set of APIs that is equal to "UWP + MobileExtensionSDK".

(2) If you have a UWP DLL, e.g. a class library, that invokes APIs just from UWP then it is guaranteed to be able to run fine on both. But if it invokes APIs that are only found in the Desktop extension SDK then, if you try to run it on Mobile, it will crash at runtime when it attempts to invoke that API or create that class.

(3) If you have a .NET dll from Win8.1 or WP8.1, then it will load and run fine on Win10, so long as only invokes APIs that are present on the operating system it's running on.

(4) The set of Win8.1 WinRT APIs is a subset of "UWP + DesktopExtensionSDK". The set of WP8.1 APIs is a subset of "UWP + MobileExtensionSDK". Therefore, if you have an 8.1 .NET dll, then it is guaranteed to run fine on either Win10Desktop or Win10Mobile depending on whether it was a Win8.1 or WP8.1 dll. It might run okay on the other Win10 OS, depending on which APIs it happens to invoke.

(5) For C++ the story is different with respect to part (3). A C++ dll that was compiled for 8.1 has the wrong set of lib references or APIsets or something like that in its binary. Therefore the C++ dll must be recompiled in order to work in UWP apps. As to whether it can easily be recompiled or not, that depends on which APIs it happens to use, as per (4).



I found it hard to understand what you're doing. You said that if you try just recompiling your native source code then you get a BadImageFormatException. But you say "there would be issues anyway because they use APIs that are not in UWP".

* Did you or did you not recompile your source code as a UWP project? If you did, then how did you get around the fact that you used APIs that aren't in UWP? (as per my point (1), you should have been able to recompile it after doing work to incorporate extension SDKs or APISets or whatever the C++ technology is, and you should have been disciplined to protect the Mobile-specific or Desktop-specific code with adaptive lightup checks).

* BadImageFormatException sounds like you in fact didn't recompile your native dll, and you just tried to make your UWP app reference that 8.1 native dll. In this case your UWP app would compile fine, but when you tried to load it, it would try to load the native DLL, and would try to IMPLIB all the imports required by that native DLL. And so it would fail at loadtime saying that there was something wrong with the DLL image.

Polio Vax Scene
Apr 5, 2009



RICHUNCLEPENNYBAGS posted:

Do they run on the same machine? PowerShell may be an option.

I ended up just publishing a web site with a .svc :downs:

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

I'm not shocked what I said made no sense, because I don't really understand it myself.



Originally, we had a Windows 8.1 and a Windows Phone 8.1 C++ dll project. They were referenced to our UWP solution. The other VLC developers think that we can just use our Windows 8.1 project in the UWP, and that the only error I'm getting is that it's not compiling the right DLL for the project. They assumed that the same Windows 8.1 DLL would work in the UWP solution too. It won't. So I figured I would make a Universal Library which would work.

First I looked into the Windows 8.1 project. There are two files, MMDeviceLocator.cpp and Thumbnailer.cpp which have API calls that can't be used in UWP.

In MMDeviceLocator, there is this

code:
AudioClientProperties props = AudioClientProperties{
                sizeof(props),
                FALSE,
                AudioCategory_BackgroundCapableMedia,
                AUDCLNT_STREAMOPTIONS_NONE
            };
AudioCategory_BackgroundCapableMedia is not supported in UWP. It's not in the extension SDKs as far as I know. In fact, I don't actually know of a workaround for that one. For now I just removed it until I could figure something out.

In Thumbnailer:

code:
        // Create a local representation to allow it to be captured
        auto sce = sys->screenshotCompleteEvent;
        sys->cancellationTask = concurrency::create_task( [sce, timeoutMs] {
            concurrency::wait( timeoutMs );
            if( !concurrency::is_task_cancellation_requested() )
                sce.set( nullptr );
        }, sys->timeoutCts.get_token() );
This won't work in a UWP app.

So I made my new Universal project, change the calls from above to ones that should work, and reference that in my UWP app. That, I think, should get me the native DLL I'm looking for. And when I did... I still got the same BadImageFormatException. I've tried cleaning the solution, making sure that the only DLLs I'm making are the Universal ones. But nothing. So I'm not sure which element of this is failing, and what I'm doing wrong.

EDIT: As a further test, I just build the library project as x86, and referenced the winmd files directly in my UWP project, building that under x86 as well. Still get the same BadImageFormatException :(.

Drastic Actions fucked around with this message at 21:19 on Oct 19, 2015

epswing
Nov 4, 2003

Soiled Meat
Another stupid WPF question.

I have an old UserControl called ImageButton (probably every single WPF project has one of these):

XML code:
<UserControl x:Class="WinDispatchClientWpf.src.controls.ImageButton"
             x:Name="Self"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Button Name="btnButton">
        <StackPanel Orientation="Horizontal">
            <Image Name="btnImage" Stretch="None" Source="{Binding ElementName=Self, Path=Image}"/>
            <TextBlock Name="btnText" Text="{Binding ElementName=Self, Path=Text}"/>
        </StackPanel>
    </Button>
</UserControl>
Call site:

XML code:
<wpfControl:ImageButton Text="Save Record" Image="/img/icons/silk/disk.png" />
Sometimes I want it to be a Tab Stop, sometimes I don't. I've tried all combinations of adding the following attributes to the call site and the UserControl and I still can't get what I want:

Focusable="True/False"
IsTabStop="True/False"
KeyboardNavigation.IsTabStop="True/False"
KeyboardNavigation.TabNavigation="None/Continue"

Adding KeyboardNavigation.TabNavigation="None" to the UserControl tag does in fact cause a tab to skip the button, but this affects all ImageButtons and no amount of tweaking to the call site will allow a particular ImageButton to be a tab stop.

Any advice?

The request made by the client is painfully simple ("when I tab, I want to skip this button"), which makes this all the more infuriating.

raminasi
Jan 25, 2005

a last drink with no ice
What happens if you set the property via a style setter somewhere?

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

Has anybody read (an earlier edition of) Expert F# and has an opinion on it?

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.
Random IIS question: Is there any reason I would want to set the X-Frame-Options header (for clickjacking) at the site level as opposed for the entire server? I keep getting pushback from the sysadmins about setting this at the server level. (Part of the problem is that they don't know how to set headers for the entire server, but that's another issue that can be easily solved by point them at https://technet.microsoft.com/en-us/library/cc753133(v=ws.10).aspx)

EssOEss
Oct 23, 2006
128-bit approved
It rather depends on the overall devops workflow and how such policies apply. On my deployments, each product/service is completely independent and I would be aghast at hearing of some server-global configuration being applied to my service. The only configuration I want to see applied is that which my dev team and my operations team explicitly and intentionally configure, and such decisions are always done on a per-site basis, as each site is an independent product/service.

Overall, server-level configuration is something I have never seen, except on some forums and blogs where it has always smelled to me. But, to play the devil's advocate, I can imagine it making sense if you have e.g. 200 customer blog websites on one server that you manage and you want to enforce proper security practices on all of them.

What exactly is your scenario about? Why do you want to apply this header? To what sort of sites?

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.

EssOEss posted:

It rather depends on the overall devops workflow and how such policies apply. On my deployments, each product/service is completely independent and I would be aghast at hearing of some server-global configuration being applied to my service. The only configuration I want to see applied is that which my dev team and my operations team explicitly and intentionally configure, and such decisions are always done on a per-site basis, as each site is an independent product/service.

Overall, server-level configuration is something I have never seen, except on some forums and blogs where it has always smelled to me. But, to play the devil's advocate, I can imagine it making sense if you have e.g. 200 customer blog websites on one server that you manage and you want to enforce proper security practices on all of them.

What exactly is your scenario about? Why do you want to apply this header? To what sort of sites?

This header needs to be applied to address issues that come up in Acunetix PCI compliance scans. Some of these sites are basically marketing sites, but some are B2B management portals for the products/services we offer. There are also a small handful of consumer-facing sites for managing their end of things. Probably about 15-20 sites total that this needs to be done for across 5 or 6 server environements (some load-balanced, some not).

epswing
Nov 4, 2003

Soiled Meat

GrumpyDoctor posted:

What happens if you set the property via a style setter somewhere?

Added this to my UserControl:

C# code:
public KeyboardNavigationMode TabNavigation
{
    set { KeyboardNavigation.SetTabNavigation(this, value); }
}
And this works like a charm:

XML code:
<wpfControl:ImageButton Text="Save Record" Image="/img/icons/silk/disk.png" TabNavigation="None" />
Thanks Doc!

epswing fucked around with this message at 15:58 on Oct 20, 2015

RICHUNCLEPENNYBAGS
Dec 21, 2010
This is less a technical question, but now that Windows Runtime stuff can be windowed is that the way that desktop GUI stuff is going to go in the future? Are they going to invest in WPF and maybe make the XAML less unwieldy? It just feels to me like this is one area where C#/.NET/the MS universe has been weirdly stagnant.

EssOEss
Oct 23, 2006
128-bit approved

RICHUNCLEPENNYBAGS posted:

This is less a technical question, but now that Windows Runtime stuff can be windowed is that the way that desktop GUI stuff is going to go in the future? Are they going to invest in WPF and maybe make the XAML less unwieldy? It just feels to me like this is one area where C#/.NET/the MS universe has been weirdly stagnant.

Perhaps it might be interesting to turn this question on its head: what needs do you have that are not being met by UWP? I wonder how big the needs for non-UWP apps will be in 5 years (in the context of something that actually has a GUI - obviously services and such are relevant).

Finster Dexter posted:

This header needs to be applied to address issues that come up in Acunetix PCI compliance scans. Some of these sites are basically marketing sites, but some are B2B management portals for the products/services we offer. There are also a small handful of consumer-facing sites for managing their end of things. Probably about 15-20 sites total that this needs to be done for across 5 or 6 server environements (some load-balanced, some not).

I can't really give more input regarding your actual question but having gone through implementing PCI compliance in the recent past, I can share some advice on the actual PCI aspect. The main thing to understand here is that being PCI DSS compliant is about following a process, it is not about builing "secure" software, for whatever definition of secure.

This means that as long as warnings such as this one are properly understood, the impact documented and the risk taken into account, all is well. To reiterate, PCI compliance is about having a process that can detect and, if the stakeholders consider it relevant, help prevent vulnerabilities. However, there is no requirement to always follow every secure coding guideline in the world. If clickjacking is considered an acceptable risk by the product owner, having non-clickjacking-proof software is just fine as far as PCI goes.

I say this because it seems to be a common fallacy to believe that PCI means nailing down every leak and closing all vulnerabilities but this is just not the case. Obviously, many PCI consultants and auditors like to give that sort of impression since it gives opportunities for good upselling of various services that might otherwise not really be needed. Thankfully, our auditors were a reasonable bunch who helped us understand the real story and did not try to give us the runaround.

EssOEss fucked around with this message at 17:18 on Oct 20, 2015

raminasi
Jan 25, 2005

a last drink with no ice

epalm posted:

Added this to my UserControl:

C# code:
public KeyboardNavigationMode TabNavigation
{
    set { KeyboardNavigation.SetTabNavigation(this, value); }
}
And this works like a charm:

XML code:
<wpfControl:ImageButton Text="Save Record" Image="/img/icons/silk/disk.png" TabNavigation="None" />
Thanks Doc!

Oh, I was thinking of doing it entirely in the XAML but I'm glad you got it working :shobon:

RICHUNCLEPENNYBAGS
Dec 21, 2010

EssOEss posted:

Perhaps it might be interesting to turn this question on its head: what needs do you have that are not being met by UWP? I wonder how big the needs for non-UWP apps will be in 5 years (in the context of something that actually has a GUI - obviously services and such are relevant).

Well, I don't have any, but to be honest GUI programming is kind of boring to me so I'd rather not invest a lot of time learning a new way of doing it unless it's got legs. The only real desktop GUI stuff I've done is Windows Forms (which kind of blows but hey).

epswing
Nov 4, 2003

Soiled Meat

GrumpyDoctor posted:

Oh, I was thinking of doing it entirely in the XAML but I'm glad you got it working :shobon:

Oh, ha, a Style setter. Gotcha :shobon:

The UserControl C# property seems to do the trick, so I'll stick to that until it breaks :P

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe
I'm looking to move an application from a basic desktop executable to a Windows Universal App for Windows 10, and so far things have been going well; hamburger buttons and working in XAML is a change of pace from C# but not bad. I've run into a snag however:

The point of the application is to change the desktop background image, which I was previously doing using the registry. However, the Windows Universal App doesn't seem to allow that; if I add " using Microsoft.Win32; " I'm still unable to reference the RegistryKey class. I've read a few snippets about Universal Apps being self-contained in that regard, does that mean they can't access the registry period? If so, does anyone know off the top of their head if they exposed access to the desktop background image settings anywhere else, or could I round-about it calling something like a command prompt script or powershell script?

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Mo_Steel posted:

I'm looking to move an application from a basic desktop executable to a Windows Universal App for Windows 10, and so far things have been going well; hamburger buttons and working in XAML is a change of pace from C# but not bad. I've run into a snag however:

The point of the application is to change the desktop background image, which I was previously doing using the registry. However, the Windows Universal App doesn't seem to allow that; if I add " using Microsoft.Win32; " I'm still unable to reference the RegistryKey class. I've read a few snippets about Universal Apps being self-contained in that regard, does that mean they can't access the registry period? If so, does anyone know off the top of their head if they exposed access to the desktop background image settings anywhere else, or could I round-about it calling something like a command prompt script or powershell script?

You can't use Win32 in a UWP. You can't call the command line or powershell either.

You should be able to call "Windows.System.UserProfile.UserProfilePersonalizationSettings.Current.TrySetWallpaperImageAsync(StorageFile file)".

C# code:
            // This may not work if group policies are set on the machine to disable changing these settings.
            // Also not all devices support it either.
            // Make sure you check before you try it!
            if (UserProfilePersonalizationSettings.IsSupported())
            {
                UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
                if (useLocalFile)
                {
                    SelectedImage = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/ejp.jpg"));
                }
                success = await profileSettings.TrySetWallpaperImageAsync(SelectedImage);
            }
I set up a Github Repo so you can check it out. There is one weird thing about it though: I can't get it to work with the file picker. If the StorageFile is from the file picker, TrySetWallpaperImageAsync will always return false, no matter what. If the file is stored in the apps storage, or bundled with it, then it's fine. So I think in your case if you download the image and store it in the app, or bundle it with it, you should be okay? I'm not sure if it's a bug in the API though :shrug:

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

Drastic Actions posted:

You can't use Win32 in a UWP. You can't call the command line or powershell either.

You should be able to call "Windows.System.UserProfile.UserProfilePersonalizationSettings.Current.TrySetWallpaperImageAsync(StorageFile file)".

C# code:
            // This may not work if group policies are set on the machine to disable changing these settings.
            // Also not all devices support it either.
            // Make sure you check before you try it!
            if (UserProfilePersonalizationSettings.IsSupported())
            {
                UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
                if (useLocalFile)
                {
                    SelectedImage = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/ejp.jpg"));
                }
                success = await profileSettings.TrySetWallpaperImageAsync(SelectedImage);
            }
I set up a Github Repo so you can check it out. There is one weird thing about it though: I can't get it to work with the file picker. If the StorageFile is from the file picker, TrySetWallpaperImageAsync will always return false, no matter what. If the file is stored in the apps storage, or bundled with it, then it's fine. So I think in your case if you download the image and store it in the app, or bundle it with it, you should be okay? I'm not sure if it's a bug in the API though :shrug:

Ahh, that makes sense.

For a little more clarity, I put together some code a while pack that goes and retrieves the Astronomy Picture of the Day and makes it the desktop each day when the user first signs in. I was hoping to move it up to a Universal App so people could get it off the app store and the like and as an excuse to toy around with UWP some, but it sounds like it'll be a total rework if it even functions. I've got the old, perfectly fine version out on a repo here and aside from when they post videos it works pretty great. I was thinking of moving to PowerShell to handle making scheduled tasks at "install" rather than the task scheduler c# wrapper I've been using.

EssOEss
Oct 23, 2006
128-bit approved
There is apparently something called Project Centennial which enables oldschool non-UWP apps to be distributed via the Store, so you might not really need to make it an UWP app. It appears to still be unreleased even as a preview, though. Possibly even vaporware?

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

EssOEss posted:

There is apparently something called Project Centennial which enables oldschool non-UWP apps to be distributed via the Store, so you might not really need to make it an UWP app. It appears to still be unreleased even as a preview, though. Possibly even vaporware?

I'd heard closed beta maybe next year, and figured I'd rather try it myself and take a look at the new stuff in the platform.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Mo_Steel posted:

Ahh, that makes sense.

For a little more clarity, I put together some code a while pack that goes and retrieves the Astronomy Picture of the Day and makes it the desktop each day when the user first signs in. I was hoping to move it up to a Universal App so people could get it off the app store and the like and as an excuse to toy around with UWP some, but it sounds like it'll be a total rework if it even functions. I've got the old, perfectly fine version out on a repo here and aside from when they post videos it works pretty great. I was thinking of moving to PowerShell to handle making scheduled tasks at "install" rather than the task scheduler c# wrapper I've been using.

Updated my Github page. You can download images from there to apps local storage and it works just fine. You should be able to make a background task and schedule it every day to auto update too. Just as long as you're downloading the image to local storage, it should work.

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.

EssOEss posted:

Perhaps it might be interesting to turn this question on its head: what needs do you have that are not being met by UWP? I wonder how big the needs for non-UWP apps will be in 5 years (in the context of something that actually has a GUI - obviously services and such are relevant).


I can't really give more input regarding your actual question but having gone through implementing PCI compliance in the recent past, I can share some advice on the actual PCI aspect. The main thing to understand here is that being PCI DSS compliant is about following a process, it is not about builing "secure" software, for whatever definition of secure.

This means that as long as warnings such as this one are properly understood, the impact documented and the risk taken into account, all is well. To reiterate, PCI compliance is about having a process that can detect and, if the stakeholders consider it relevant, help prevent vulnerabilities. However, there is no requirement to always follow every secure coding guideline in the world. If clickjacking is considered an acceptable risk by the product owner, having non-clickjacking-proof software is just fine as far as PCI goes.

I say this because it seems to be a common fallacy to believe that PCI means nailing down every leak and closing all vulnerabilities but this is just not the case. Obviously, many PCI consultants and auditors like to give that sort of impression since it gives opportunities for good upselling of various services that might otherwise not really be needed. Thankfully, our auditors were a reasonable bunch who helped us understand the real story and did not try to give us the runaround.

Wise words. I think on this particular issue, the powers that be have decided NOT to risk except this, but your arguments about server-wide configuration being smelly and maybe an anti-pattern make me think I should just implement this on each site and call it good.

e: next problem on the list... I see a lot of conflicting reports for how SERVER_NAME is populated in IIS. I'm thinking of replacing HTTP_HOST with SERVER_NAME in some web.config rewrite rules in order to mitigate Host header attacks. But it seems like SERVER_NAME is dependent on doing a reverse DNS lookup for the server? Or some people think it just uses HTTP_HOST anyway? Or there is some way to set "host headers" in IIS to configure the value of SERVER_NAME? Anyone have experience with this?

Finster Dexter fucked around with this message at 15:36 on Oct 21, 2015

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

Drastic Actions posted:


"Windows.System.UserProfile.UserProfilePersonalizationSettings.Current.TrySetWallpaperImageAsync(StorageFile file)".


:monocle:

This is some simpleproxybeanfactoryfactor poo poo. That is one hell of a path.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

LeftistMuslimObama posted:

:monocle:

This is some simpleproxybeanfactoryfactor poo poo. That is one hell of a path.

You don't have to use the whole thing, it was just to make it easer to explain where the namespace is.

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

Drastic Actions posted:

You don't have to use the whole thing, it was just to make it easer to explain where the namespace is.

I haven't done much UWP, but how likely is someone to have a reference to Windows.System.UserProfile.UserProfilePersonalizationSettings.Current just hanging out in their program? I just love precariously long paths like that.

\/\/\/ edit: Yeah, that makes sense.

The MUMPSorceress fucked around with this message at 18:08 on Oct 21, 2015

brap
Aug 23, 2004

Grimey Drawer
Well, in practice you probably import Windows.System.UserProfile and then say UserProfilePersonalizationSettings.Current.

Gul Banana
Nov 28, 2003

EssOEss posted:

Perhaps it might be interesting to turn this question on its head: what needs do you have that are not being met by UWP?

- run on older windows versions
- access the filesystem
- connect to sql databases
- exes/installers without going through the windows store

there are some smaller details but it doesn't seem worth investigating workarounds for other stuff unless those dealbreakers are resolved.

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

Drastic Actions posted:

Updated my Github page. You can download images from there to apps local storage and it works just fine. You should be able to make a background task and schedule it every day to auto update too. Just as long as you're downloading the image to local storage, it should work.

I'll take another look, thanks.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Does anyone have a link or an explanation of how a viewmodel-first MVVM solution is started in practical terms? Like, I get the idea, but haven't a clue what/where the code or XAML or linkages look like or are.

crashdome
Jun 28, 2011
I typically start ViewModel first but, I don't know if I am following a best practice or not. I just decided it was more comfortable for me to do it this way.

I usually start with an Interface for my VMs so I can create a design-time ViewModel with mock values for UI design.
I then create a stub ViewModel for production
Wire both in to the Service Locator
Create a new View and add the binding for the Service Locator ViewModel path
Then I start designing the UI which dictates if I need to change the ViewModel Interface at all
When I'm happy with the View, I start filling in the real ViewModel with code for the services/models.

Having a design-time ViewModel first means I can tweak the View until I know it is designed to my preference. It also is a good way to get screenshots if I need to ask the client usability questions before any actual code is written.

Edit: I use MVVM Light so most of the boilerplate is already there when I start. I have a few of my own classes I may port in but, generally I follow the structure it gives me. I also work on more than one ViewModel at a time. When I do, the design VMs are filled with mock data and the real VMs are filled with TODO or Not Implemented Exceptions so I don't forget to write the actual code in my methods. Unit tests are placed against the real VMs only and usually I only test methods or Properties that do service calls. These also helps let me know if I forgot anything.

crashdome fucked around with this message at 22:50 on Oct 22, 2015

EssOEss
Oct 23, 2006
128-bit approved
I will try to give you a real example based on an UWP app that I recently created.

If there is some backend business logic (downloading feeds or whatnot), I build that logic first and use automated tests to verify that it works. This becomes part of the model. Only really feasible if you have some strict requirements that you know will not change based on the view, or if you have enough experience to be able to predict exactly what the view will need from the model. Everything in the app serves the view.

Any special model-building aside, I start from the view first. I create the various pages of the application as Page objects and fill in placeholder XAML that has the right elements but dummy data (hardcoded) and very rough styling. Something like this:

code:
<Button Text="Do you have stairs in your house?" />
This is only for the very beginning - like, the first hour I work on a Page and just create it's basic visuals. You kind of start needing viewmodels fast if you don't want to rewrite your dummy logic later, so once the page is sort of okay looking and I want to start adding interactivity, I start creating the viewmodel for it. I use x:Bind exclusively (except where it is technically impossible) for data binding, which wants you to access your data via the Page/UserControl instance, so I add this to my Page or UserControl:

code:
public sealed partial class CatalogItemOverview : UserControl
{
	private CatalogItemOverviewVm Viewmodel => (CatalogItemOverviewVm)DataContext;
This allows me to use the following binding syntax:

code:
{x:Bind Viewmodel.MyButtonText}
But remember that instances of view objects can be reused by the GUI infrastructure (e.g. list virtualization)! Watch out for data context changes and be sure to update bindings when it happens!

code:
public sealed partial class CatalogItemOverview : UserControl
{
	private CatalogItemOverviewVm Viewmodel => (CatalogItemOverviewVm)DataContext;

	public CatalogItemOverview()
	{
		this.InitializeComponent();

		DataContextChanged += delegate { Bindings.Update(); };
	}
}
A viewmodel is simply a class that implements INotifyPropertyChanged. I don't use any MVVM "framework" as I do not hold any in high regard - MVVM just is a way of thinking and a method of structuring object relations; if you require a library for it you are probably doing something way too complex.

The viewmodel serves the view, so what goes in there is 100% dictated by the view. If I have a bottom pane that may or may not be visible, I make a BottomPaneVisibility property of type Visibility.

code:
<Button Visibility="{x:Bind Viewmodel.StartDownloadButtonVisibility, Mode=OneWay}">
	...
</Button>

public sealed class CatalogItemOverviewVm : INotifyPropertyChanged
	{
		public string Title { get; } // Never changes, so no need to wire up INPC

		#region Visibility StartDownloadButtonVisibility (read-only)
		public Visibility StartDownloadButtonVisibility
		{
			get { return _startDownloadButtonVisibility; }
			private set
			{
				if (_startDownloadButtonVisibility == value)
					return;

				_startDownloadButtonVisibility = value;
				RaisePropertyChanged(nameof(StartDownloadButtonVisibility));
			}
		}

		private Visibility _startDownloadButtonVisibility;
		#endregion
During initial design, I just fill the viewmodels with pseudo-random dummy data in their constructors, like this:

code:
public CatalogItemOverviewVm()
{
	Title = Helpers.Random.GetWords(1, 5);
	DownloadProgress = Helpers.Random.GetDouble();
	LicenseStatus = Helpers.Random.GetEnum<LicenseStatus>();
	DownloadState = Helpers.Random.GetEnum<MediaAgentState>();
	DownloadFunctionalityAvailable = true;

	UpdateVisibilities();
}
Once the app progresses so far that real data from the Model is available, I stop maintaining the dummy data. Now, I used to keep maintaining it for use in design mode, but unfortunately x:Bind does not show you the dummy data in design mode, so it is no longer meaningful. It just displays the binding path. Here is an example of a view and what it looks like in the designer:



For real testing, you need to run the app - the design view is only suitable as a very rough guideline. During initial stages, I just set whatever thing I am working on as the root page shown on startup. Later, it can get more annoying once the app fills out more with functionality.

Hmmm what else matters... aha, associating view and viewmodel and model. The view is always provided the viewmodel on "startup". Specifically, for Pages, the viewmodel to use is the navigation parameter. So in my App.xaml.cs I have this in the OnLaunched method:

code:
_rootFrame.Navigate(typeof(MainPage), new MainPageVm(ContentCatalog));
Which in MainPage is handled as:

code:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
	DataContext = (MainPageVm)e.Parameter;
}
For UserControls, the viewmodel is the data context. Custom controls do not use a viewmodel, they take data from their own (dependency) properties, as provided by the developer.

Viewmodels are provided any Model references in their constructor parameters. For larger apps, I use a dependency injection container to automatically wire stuff up via this constructor. For smaller apps, I just do it manually. Okay but what calls the constructor? Other viewmodel objects! Say, if I want to navigate from MainPage to PlaybackPage when some button is pressed, I have a command in whatever viewmodel matches up with that button:

code:
public sealed class CatalogItemOverviewVm : INotifyPropertyChanged
{
	public ICommand PlayCommand { get; }

	/// <summary>
	/// Raised when the item requests the app to navigate to the playback page, using the provided viewmodel.
	/// </summary>
	public event EventHandler<PlaybackPageVm> RequestPlaybackPage;

	public CatalogItemOverviewVm(CatalogItem item)
	{
	}

	PlayCommand = new DelegateCommand
	{
		Execute = delegate
		{
			var request = RequestPlaybackPage;
			request?.Invoke(this, new PlaybackPageVm(_item));
		}
	};
}
Now RequestPlaybackPage exists because the viewmodel does not have access to the navigation frame. It needs to fire a request to the view in order to perform the actual navigation. This worked for this app but I do not find it the most convenient, so likely in the next app I will change it to give viewmodels direct access to navigation.

On the topic of events, make sure that your view always detaches from the viewmodel and your viewmodel always detaches the from model! Keeping event handlers hooked up when the views and viewmodels are not needed is a very easy way to end up with resource leaks!

Example of viewmodel event registration and de-registration in the view:

code:
	public sealed partial class MainPage : Page
	{
		protected override void OnNavigatedTo(NavigationEventArgs e)
		{
			DataContext = (MainPageVm)e.Parameter;

			foreach (var item in Viewmodel.CatalogItems)
				item.RequestPlaybackPage += OnRequestPlayback;

			base.OnNavigatedTo(e);
		}

		protected override void OnNavigatedFrom(NavigationEventArgs e)
		{
			foreach (var item in Viewmodel.CatalogItems)
				item.RequestPlaybackPage -= OnRequestPlayback;

			base.OnNavigatedFrom(e);
		}
Example of model event registration and de-registration in the viewmodel:

code:
public CatalogItemOverviewVm(CatalogItem item)
{
	var itemListener = new WeakEventListener<CatalogItemOverviewVm, object, PropertyChangedEventArgs>(this);
	itemListener.OnEventAction = (instance, source, args) => instance.OnCatalogItemPropertyChanged(source, args);
	itemListener.OnDetachAction = (wel) => _item.PropertyChanged -= wel.OnEvent;
	_item.PropertyChanged += itemListener.OnEvent;
That's a weak event listener - it does not keep any strong reference to the viewmodel and automatically cleans itself up once the viewmodel is destroyed. This is important because there is no "navigating away" event on viewmodels (I suppose you could do with IDisposable but ehh that has its own set of issues).

I think this covers the basics... feel free to ask if you have any questions related to this! Obviously, this is just my interpretation of MVVM and there are many others. However, I stand by it as a very practical one and I have been using it for around 5 years now, from the good old days of Silverlight 2.

Here is an example GitHub repository with a partial sample of the app in question (it's an internal development workbench type of app for a library): https://github.com/sandersaares/mvvm-example

EssOEss fucked around with this message at 09:06 on Oct 23, 2015

crashdome
Jun 28, 2011
That seems like a lot of code-behind for an MVVM app. If you had a design VM you could forego a lot of the hard-coded text and having a Service Locator that swaps between design-time and run-time automatically would mean far less work to hunt down that manually entered stuff later.

I agree that a View dictates a lot of VM work but, it's pretty trivial to write up a VM Interface and change it as the view changes design.

It's also true you don't need a framework but, these lighter ones really cut down the need to boilerplate things like weak events and ViewModel base classes.

I'll see if I can write up a simple step by step that I use and post it here in a moment.


Edit: This example uses an Interface for the underlying service of the VM and is based on the MVVM Light samples. I've modified this process a bit for myself because I hated having a unique "Service" for each VM but, the majority of principles are the same.
Ignore the methods and such as they may not pertain to you or you might want something different based on any models or base classes you develop on your own.

Start with an Interface with all the items your viewmodel might need
C# code:
    public interface ICustomerEditorService
    {
        ObservableCollection<Customer> Customers { get; }
        Customer InitialSelection { get; }

        void AddCommand(Customer customer);
        void RemoveCommand(Customer customer);
        void SaveAllCommand();
        void ReloadCommand(Customer customer);
        void RefreshAllQuery();
        bool HasErrors { get; }
    }
Build a Design Service/VM to help with design
Note most of the methods don't need to function but need to be implemented to not throw any errors
C# code:
    public class DesignCustomerEditorService : ICustomerEditorService
    {
        ObservableCollection<Customer> customers;

        public DesignCustomerEditorService()
        {
            customers = new ObservableCollection<Customer>();
            customers.Add(new Customer
            {
                Id = 0,
                // add other properties
            });
            customers.Add(new Customer
            {
                Id = 1,
                // add other properties
            });
            customers.Add(new Customer
            {
                Id = 2,
                // add other properties
            });
            customers.Add(new Customer
            {
                Id = 3,
                // add other properties
            });
        }

        public ObservableCollection<Customer> Customers
        {
            get { return customers; }
        }

        public Customer InitialSelection
        {
            get
            {
		//I like to select something in the middle
                return customers[3];
            }
        }

        public void AddCommand(Customer Customer)
        {
            //
        }

        public void RemoveCommand(Customer Customer)
        {
            //
        }

        public void SaveAllCommand()
        {
            //
        }

        public void ReloadCommand(Customer Customer)
        {
            //
        }

        public void RefreshAllQuery()
        {
            //
        }

        public void CleanUp()
        {
            //
        }


        public bool HasErrors
        {
            get { return false; }
        }

        public void Cleanup()
        {
            //
        }
    }
I'm going to skip pasting the run-time service class because it is basically the same as above but with no mock data. Methods will be stubs with NotImplementedExceptions instead of comments or "//" so my unit tests fail if I forget to come back to them.

Also, I'll skip posting the Unit tests. Basically I unit test some of the methods that interact with my Data/Model layer and any that I know I need to fill in and remove the NotImplementedExceptions.

Create the actual VM
C# code:
    public class CustomerEditorViewModel : ViewModelBase //or your own base viewmodel class
    {
        ICustomerEditorService _customerEditorService;

        public CustomerEditorViewModel(ICustomerEditorService customerEditorService) //and maybe other services?
        {
            _customerEditorService = customerEditorService;
            InitRelayCommands();

	    //Wire up any initial values
	    SelectedCustomer = _customerEditorService.InitialSelection;
        }

        //I have this method required as abstract in my base class to force me to remember but, you could do this in the constructor instead
        private override void InitRelayCommands()
        {
            //TODO: CustomerEditorViewModel - Add code for initializing relay commands
        }

        // Add bindable properties for the ViewModel - i.e. Observable collections, 
        // Maybe a Title string, RelayCommands, etc..
        // Most will call the underlying service and probably be one line of code
	//e.g. 
	public RelayCommand SaveAllCommand { get; protected set;}

	//and e.g
	private Customer _selectedCustomer;
	public Customer SelectedCustomer
        {
            get
            {
                return _selectedCustomer;
            }
            set
            {
                if (IsEditing)  //My VM might have View specific properties like this
                    {
                        if (CancelCommand.CanExecute(1))
                            CancelCommand.Execute(1);
                    }
                    _selectedCustomer = value;
                    RaisePropertyChanged(); //MVVM Light specific NPC method
            }
        }
    }
Then add all of them to the Service Locator so the View can be designed
C# code:
    public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            if (ViewModelBase.IsInDesignModeStatic)
            {
                SimpleIoc.Default.Register<ICustomerEditorService, Design.DesignCustomerEditorService>();
            }
            else
            {
                SimpleIoc.Default.Register<ICustomerEditorService, CustomerEditorService>();
            }

            SimpleIoc.Default.Register<CustomerEditorViewModel>();
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public CustomerEditorViewModel CustomerEditor
        {
            get
            {
                return ServiceLocator.Current.GetInstance<CustomerEditorViewModel>();
            }
        }
    }
Create the View and begin designing
C# code:
<UserControl x:Class="MyProject.Views.CustomerEditorUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d"
             DataContext="{Binding CustomerEditor, Mode=OneWay, Source={StaticResource Locator}, ValidatesOnDataErrors=True}"
             >

//ETC ETC ETC
Then you can start adding controls and binding them in the View. Design service/VM values should show up automatically and not appear in debug/release mode.

Unit Tests should point anything you forgot in run-time service (NotImplementedException) as should any TODO comments if you follow that practice.

It's different than EssOEss's method but then, the MVVM Light framework eliminates much of the boilerplate he wrote. I also like that the ServiceLocator eliminates Context binding in the View's code behind for design mode. You don't need MVVM Light for this practice but, you'd need to do all the boilerplate MVVM stuff ahead of time like the base ViewModel class and any Navigation services or such. I hate code-behind in my View and I have 99.9% code-behind free views. The only exception is some custom code-behind for reducing some boilerplate code for some specific Views I use and consists of usually a single line of code in the View constructor.

crashdome fucked around with this message at 20:50 on Oct 23, 2015

brap
Aug 23, 2004

Grimey Drawer
I am really put off by the service locator/view model locator/big ball of singletons pattern. Am I crazy?

Adbot
ADBOT LOVES YOU

RICHUNCLEPENNYBAGS
Dec 21, 2010

fleshweasel posted:

I am really put off by the service locator/view model locator/big ball of singletons pattern. Am I crazy?

I'm with you.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply