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
mystes
May 31, 2006

I'm trying to manipulate XPS files in C# like this but I'm having a really weird problem. The original VS project works fine for me, but I've tried to modify it so I can either run it from powershell or so I can run it as a console application and in both cases on the output from the file I'm testing it on, only the first page of the output file works in the XPS viewer, but I don't get any error messages.

Here is my last attempt to make it into a console application while modifying it as little as possible to try to figure out where the problem is (note the hardcoded paths partway down): http://pastebin.com/qmDik1b5

I've tried targeting different .net versions but even with .net 4.5 / x86 like in the demo program I can't get it to work. Am I missing something really obvious here?

Also it's really lame that there seems to be no sane way to modify XPS files. You can open them and read them using the not-quite-so-lovely WPF interface, but there isn't any way to copy content from them without messing around with XML (you can't just copy the child elements on each fixedpage because they reference other resources like fonts in the original archive). It seems like you should be able to be able to open XPS files and just change some stuff before saving it again, but it seems like you aren't actually able to do that.

It's frustrating because I was able to extract the text from an xps file in a few lines of powershell code, and it seemed like it would be just as easy to make some changes, but boy was I wrong.

Edit: Rather than modifying the XPS file, is there any other easy way to manipulate the content and then display it? I tried modifying the fixeddocument in memory and then passing it to a DocumentViewer control but that didn't really work either (it sort of worked sporadically, but I think that's unintended behavior); is there some way I can render a single fixedpage to a window at a time and then be able to modify it?

mystes fucked around with this message at 23:43 on May 21, 2016

Adbot
ADBOT LOVES YOU

mystes
May 31, 2006

mystes posted:

I'm trying to manipulate XPS files in C#
OK, to reply to my own post, after poking around more, the apis for XPS documents are really annoying but I figured out a simpler solution. Basically, the APIs are very much not intended to allow you to modify existing XPS files as WPF objects, which is a pity because it would be really simple if it worked, but you quickly run into the problem that if you read it back as actual FixedDocument objects you then can't really modify them as-is. If you try to stick them directly onto a visual or naiively serialize and then deserialize them it may sort of work, but there seem to be issues with glyphs sometimes, which I think may possibly be a result of the stupid font situation where all fonts must be embedded, but are typically subsetted/obfuscated (to deter copying). (The problem with the obfuscated fonts is that the obfuscation is based on the GUID in the filename, and while you can easily copy the font to another package, if you write glyphs to a new visual, when you turn it back into a fixeddocument windows will helpfully change the guid.) You would think you could easily just throw out the embedded font files and start over except that the XPS files don't even have the original font names so that may be hard or impossible.

All that said, I realized that while the approach of modifying the document as xml is unavoidable, it could be much simpler than the c# example I was looking at if rather than building a new package file, I simply *copied* the original XPS file and modified it in place. This avoids the need to copy the parts from one package to another.

Here is a simple example of turning all the text red in powershell:

code:
$oldfile = "$env:userprofile\documents\test2.xps"
$newfile = "$env:userprofile\documents\test2_out.xps"
cp $oldfile $newfile

$container = [System.IO.Packaging.Package]::Open($newfile, [System.IO.FileAccess]::ReadWrite)
$fixedpage_parts = $container.GetParts() | ? {$_.ContentType -eq "application/vnd.ms-package.xps-fixedpage+xml"}

$xmldoc = New-Object System.Xml.XmlDocument
$ns = New-Object System.Xml.XmlNamespaceManager($xmldoc.NameTable)
$ns.AddNamespace("xps", "http://schemas.microsoft.com/xps/2005/06")

foreach ($part in $fixedpage_parts) {
	$stream = $part.GetStream()
	$xmldoc.Load($stream)
	
	$xmldoc.SelectNodes("//xps:Glyphs",$ns) | % {$_.Fill = "#FFFF0000"}
	
	$stream.position = 0
	$xmldoc.Save($stream)
	$stream.SetLength($stream.Position)
}

$container.close()
The only problem with this approach is that if I want to add new text back to the document, even if I want to use a font in the original document, I think I can't necessarily assume that the font will have all the characters I need, so I'm back to needing to actually add stuff to the package. Adding images would also require adding them to the package. Otherwise, simply creating a new canvas in a visual with stuff I want to overlay and serializing it would probably be the easiest approach.

It would be so much easier if it was actually possible to render a fixedpage to a visual and then use the normal api for generating an XPS file again.

Edit: It turns out the font name is actually preserved in the obfuscated file (although you have to deobfuscate it, write out to the filesystem as a ttf file, and examine it to get at it). This makes me think that I might be able to switch back to the approach of adding the existing fixedpage to a visual, and then just cleaning it up a little bit.

mystes fucked around with this message at 17:09 on May 22, 2016

mystes
May 31, 2006

OK, so I doubt anybody cares, but it turns out that if you want to render a page of an XPS file via WPF so you can manipulate it, it's actually not that complicated once you know what to do (it was a serious pain to work out the exact details, however).

The key trick for the fonts is to open the XPS file as an XPSDocument and call the ToGlyphRun method on the Glyphs objects. Then you can access the GlyphTypeface, which will tell you the font family, so you can figure out what resource urls correspond to what fonts, if you want to use the system fonts. (Otherwise, you can deobfuscate the subsetted fonts from the font stream via the GlyphTypeface, so you could probably use a private font collection but that would be more complicated and if you're actually trying to edit the text it would be pretty pointless anyway).

Then you can access the XPS file as a package to get the images. You could probably serialize the FixedPage from the XPSDocument directly, but right now what I'm doing is getting the XML out the package and then simply rewriting the font uris to the system fonts and the image uris in the ImageBrushes to extracted copies of the images.

As far as I can tell, the fonts in glyphs and the images in ImageBrushes are the only two places where FixedPages actually reference resources in the XPS package, so if you just fix these two things, you can parse whatever's inside the FixedPage element in the XML as XAML and write it to a window.

Anyway, all this was pretty dumb and my advice for anyone who needs to work with XPS files would be to convert them to PDFs and then use PDFBox which has an API that's only moderately annoying

mystes
May 31, 2006

john donne posted:

I wonder if there will ever be a good framework for building GUIs in .NET that isn't html-driven
You don't have to use XAML (I assume that's what you mean?) to use WPF, so there's no reason you couldn't use a DSL or wherever. The bigger problem is that it seems like all the underlying API's are deprecated right now. I guess the official recommendation is WPF on UWP, but nobody wants to make windows store apps. As a result, it seems crazy to put a lot of effort into Windows GUIs when anything could happen, to the point where the standard advice already seems to be to just be to make websites instead.

With .net core existing now, I'm hoping that someone will finish decent cross-platform .net QT bindings, which might well be the least lovely cross-platform option by default. It's amazing that there still isn't a decent cross-platform gui option for .net, but the gui framework options are limited in the first place, and .net certainly hasn't seemed like a realistic choice outside of windows until like 1 day ago.

mystes fucked around with this message at 02:19 on Jun 29, 2016

mystes
May 31, 2006

Mr Shiny Pants posted:

Xamarin forms?
I don't think it has linux support.

mystes
May 31, 2006

BirdOfPlay posted:

Does FileInfo.Attributes tell me only if the file is flagged as Read Only or will it be flagged as ReadOnly if the file directory is write-protected as well? If I uncheck "Read Only" for the file in Program Files, it's still write protected. I know this because I've tried using an unelevated hex editor on the file and cannot save changes because of lowered permissions..
The read only attribute is just something that can be set as a gentle request that a program not write to a file. It's different than actual permissions. To actually determine whether you had the permissions to write to a file without trying to open it for writing would probably require messing around with the ACLs in a complicated way [Edit: actually it looks like it's not too crazy, but still more complicated than necessary]. Do what Plorkyeran said, or reconsider the way you're going about this entirely (e.g. provide a separate interface to show a list of premade files that are present in program files, rather than a file picker).

mystes fucked around with this message at 02:13 on Jul 13, 2016

mystes
May 31, 2006

Combat Pretzel posted:

In an UWA, I want to use a Polyline for a linechart and use relative coordinates and use Stretch="Fill", so that I don't have to recalculate point coordinates every time when I resize or whatever. The issue however is that say if the points used for Y axis goes from 0.25 to 0.75, it'll normalize it and stretch it as much as possible instead of leaving 25% on top and bottom blank as the min/max Y coordinates of the points suggest. A cheap temporary fix right now is to draw a first segment from top to bottom. How can I do this properly, because the cheap fix leaves an artifact.

--edit:
Basically, this is how it is supposed to look, but uses the cheap fix:
http://i.imgur.com/L9sYaHZ.png

This happens when I don't add a first segment going from 0,0 to 0,1:
http://i.imgur.com/bkpZYrf.png
I don't know a ton about WPF and nothing about UWA, but assuming they work the same way, I think in this case you want to add the polyline to a canvas in a viewbox and use the viewbox to handle the resizing or something like that?

mystes fucked around with this message at 23:02 on Jul 17, 2016

mystes
May 31, 2006

amotea posted:

I can't figure out what we as developers are supposed to get out of this... we have to jump through a metric poo poo ton of hoops to get our perfectly working desktop apps to become a UWP package or something? WPF applications run just fine on Windows 10 lol. Are they implying people want to run our boring industrial business app on their xbox?
But how will you get users for your boring industrial business app if your customer's procurement department can't find it in the app store?!

mystes
May 31, 2006

From the earlier discussion about combining Windows Forms and WPF, which direction is less horrible? I was trying to do something in a DataGridView in WPF and it was way too slow, so I switched to Windows Forms, but it would also be really convenient to be able to use a WPF RichTextBox so I don't have to deal with RTF or something like that.

Edit: ElementHost is actually OK, right? So I should be able to keep the application as windows forms and just embed the WPF control without too much trouble?

mystes
May 31, 2006

If I have one thread writing (only) to an array of integers (I assume this would cause problems with individually heap allocated objects) and one thread reading (only), can I get away with not doing any synchronization if I don't mind the results possibly getting out of date?

If so, if a small amount of the time I want the writing thread to signal the reading thread (via a bufferblock or something) that a value has been updated but do want the value pulled from the array to be up to date, is there anything special I need to do to ensure this?

mystes
May 31, 2006

raminasi posted:

If you're looking for the lowest-effort solution to whatever your actual problem is, it's a BlockingCollection.
But I don't want reading the value from the array to block because I need to do that from the GUI thread right as the result is going to be used to change the style of something that's about to be drawn.

I guess I could just set a really low timeout and use a default value in that case, but it just seems like then there's no point in using the blockingcollection. I'm also just curious because I have always carefully avoided threading whenever possible but now I'm interested in how it works.

mystes fucked around with this message at 23:31 on Aug 22, 2016

mystes
May 31, 2006

ljw1004 posted:

Short answer: Yes.

But you haven't told us the exact correctness guarantee you want. Here's my attempt at fleshing out your requirements:

"If thread X writes an integer to index i of an array, and thread Y reads from that index, then thread Y must retrieve either the old value or the new value. Moreover, once Y has started to retrieve the new value, subsequent reads on thread Y will still retrieve the new value at least until such time as a new value is written."

That works!

One question is about are "tearing" -- e.g. if you write a four-byte integer, might another thread be able to read the integer and read the first two bytes from the old value and the next two bytes from the new value? No it can't, not if the int is properly aligned. And in an array it will be.

Another question is about "side effects" -- e.g. if you write at index i, might that possibly affect the value at index i+1 ? No it can't.



But the guarantee I wrote above is a pretty small guarantee. Unless you're careful, you won't be able to build a working algorithm out of just that guarantee. Here's a scenario...

1. Array starts with values [0,1,2,3]
2. Thread X writes in a new value for index0: [15,1,2,3]
3. Thread X writes in a new value for index1: [15,27,2,3]
4. Thread Y reads index 1 followed by index 0.

It's possible that thread Y will read the new value "27" of index 1 but then read the old value "0" of index 0 -- even though they were written in reverse order! This scenario is possible, and doesn't contradict the guarantee.


The .NET memory model is documented in the ECMA CLI spec: http://www.ecma-international.org/publications/standards/Ecma-335.htm

Actually, the memory model used by Microsoft's implementations of .NET are a bit stronger (i.e. less bizarre) than the minimum mandated by ECMA. But I don't know the details.


CAVEAT: This isn't my area. I've always found it confusing and baffling. I'm just trying to answer as best I can :)
Thanks! Your summary of my requirements is exactly what I was trying to say and I don't need any consistency guarantees, so the scenario you described shouldn't be a problem.

mystes
May 31, 2006

Inverness posted:

I'd like to know more about your DataGridView issue. Were you using row virtualization?
I was trying to; it's on by default, right? I may very well have been doing something wrong, causing it to load more rows than necessary, however. The problem was that scrolling seemed pretty slow, but I didn't try to debug it too much, because it seemed like the WPF datagridview control would be really inappropriate for my next goal (changing the color of individual cells based on the result of calculations performed in another thread). Frankly, the whole row virtualization thing was much clearer with Windows Forms since you essentially just have to implement one function to provide the data when required, rather than setting the itemsource and praying that your object will work with row virtualization (different tutorials seem to do different cryptic things which may or may not be required to actually get row virtualization to function in WPF).

mystes
May 31, 2006

Cuntpunch posted:

Eh, Silverlight was a late-to-the-party attempt to fight Flash. If it had shown up 5 years earlier it probably would have had some sticking power - but instead it was just too late to matter - Flash itself was already showing its age and being replaced by HTML5, etc, and then suddenly a "oh boy another plugin for rich web content!" shows up. Just old-school Microsoft lovely timing.
It was a total failure as a flash killer, but it mattered to the companies that were using it internally.

mystes fucked around with this message at 02:35 on Sep 14, 2016

mystes
May 31, 2006

Uziel posted:

Both are List<int>.
Are you trying to pass a list to contains?

mystes
May 31, 2006

Uziel posted:

Yes, or figure out the equivalent if I can't do that? Intellisense is giving me the impression that I can though.
I don't think you can but I'm on my phone and I'm not super knowledgeable about c#. I would think you need to use the linq all method to make sure a list contains each element of another list.

mystes
May 31, 2006

NihilCredo posted:

This is perhaps my favourite. VB.Net has an interesting legacy keyword called 'Static'. It has nothing to do with C-like static entities (those are called "Shared"). Rather, it can be used to declare a local variable in place of the usual Dim. If you do, the value of the variable is retained between each call of the function where the static variable appears.
This is what the static keyword does in c. Also, please don't use it. You shouldn't randomly hide global state inside functions.

mystes
May 31, 2006

Jewel posted:

to be fair, winxp also has a huge user base. doesn't mean you shouldn't wane it out and try to persuade to change the standard
Microsoft will never be able to kill vb.net.

mystes
May 31, 2006

Ugh I've been trying to use f# on linux but it's such a disaster. VSCode works great as an editor but I randomly just can't get its breakpoints to work with mono so I can't debug. I thought I would try to see if .net core would work instead, but of course f# is completely broken in .net Core 2.0 Preview. I guess I could either try to use something else for mono debugging if there's anything else that supports f#, or I could try to install an older version of dotnet core, but I'm not totally sure if the released version of ionide even actually suppports debugging on dotnet core.

It seems like other people have had the breakpoint issue but there just aren't enough people using f# with VSCode to care or something. Unfortunately it seems like dotnet core has actually made the f# situation more unstable on linux too, because probably all the effort is going to be focused on that from now on. I just hope .net core gets somewhat stabilized soon, but I'll probably have given up on f# again by then.

mystes fucked around with this message at 15:16 on May 18, 2017

mystes
May 31, 2006

quote:

Use Windows and deploy on Linux? I know, sucky solution but at least on Windows the debugger works great.
Part of the reason for using f# was because I was hoping it would work on both linux and windows conveniently :(

Now I'm trying to use .net core 1.0, and I haven't even gotten to the point of seeing if I can debug with it because I'm having a type issue that I didn't have with mono.

I have a line that's like
code:
let readline = if debugging then Console.In.ReadLine else StreamReader("/home/user/file").ReadLine
but I get a type constraint error saying that "string" isn't compatible with "Stream". I'm sort of confused; fsharp under mono thought that both of these had the type unit -> string so why is fsharp under dotnet core unhappy with this? Does Readline have a different type signature on dotnet core?

mystes fucked around with this message at 15:49 on May 18, 2017

mystes
May 31, 2006

Mr Shiny Pants posted:

It is complaining about the output of the function? Use ignore on both cases?
I'm not invoking the functions. Console.In.ReadLine and StreamReader should both be unit -> string and I am selectively setting my readline function to one of them.

However it turns out I misunderstood the problem. I don't know if it's a problem in this version of the fsharp compiler or dotnet core itself, but the actual problem is that it doesn't like StreamReader(string) for some reason, and it's determined to call StreamReader(stream) (one of the other constructors).

Looking at the .net standard reference at https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader?view=netstandard-1.6 the table of constructors at the bottom doesn't even have StreamReader(string) which makes me wonder if .net core therefore doesn't? And yet the example on that very page actually gives an example of using StreamReader(string)!
code:
...
String filename = "TestFile1.txt";
Char[] buffer;
        
using (var sr = new StreamReader(filename)) {
...
so if that's correct the example is just wrong? I'm pretty confused now.

Edit: Oh god it appears to be true: http://stackoverflow.com/questions/37785384/new-streamreader-class-doesnt-accept-filename

Why, Microsoft, why?

Edit 2: OK, I changed it to System.IO.File.OpenText and it builds with dotnet core 1.0, and I can debug it in VSCode. However, since the auto-completion and error highlighting are I think still based on mono this is probably going to lead to its own headaches if it doesn't match the actual compiler.

Drastic Actions posted:

What do you mean? That .NET Core is going to get more focus than Mono? I can tell you that's not that case.

Which version of mono are you running? We released 5.0 a few days ago to stable. I'm not sure if that impacts VS Code or not, but it might be worth checking the versions to see if 5.0+ fixes your breakpoint issues.You can also try using MonoDevelop and see if that integration works better. And try using the flatpak we release, as that's more up to date than what's probably in the distro's repo.

If you're still having issues, you can file a bug and I can poke people to see if they have any ideas, or if it's a VS Code/Ionide issue.
I didn't mean in terms of .net core and mono in general, but in terms of the infrastructure around fsharp on linux. It would be nice if I'm wrong, though. It just seems like fsharp isn't popular enough as it is, and with more configuration options the tooling is just going to get increasing fragmented, though.

I'm sure it's an issue with ionide rather than mono, but I might try seeing if upgrading mono helps.

mystes fucked around with this message at 16:37 on May 18, 2017

mystes
May 31, 2006

Oh never mind, I'm dumb. The breakpoint wasn't working because it was just using a version of the file I had compiled manually without debug information, so I'm back to mono and it's working fine now. I still apparently don't understand how to configure builds in VSCode at all, though.

Luckily that means I can postpone learning anything about .net core.

mystes
May 31, 2006

ljw1004 posted:

I know you were asking about memory leaks with lambdas, but (1) you should be using async-await rather than lambda callbacks, (2) you should be cancelling the web request if its result is no longer needed, (3) what is this HTTPRequest/HTTPResponse class anyway? It looks like it's not System.Web.HttpRequest (which has different capitalization and lacks a Callback property) and I can't find it on Google, so I don't know how to write the code I think you should be writing instead. Why aren't you using "HttpClient' ?
Considering the type parameter constraint it's probably part of Unity, so that may impose some limitations.

mystes
May 31, 2006

Is there some way to use the NEST c# elasticsearch API without tons of crazy lambda expressions? I'm talking about stuff like:
code:
searchResponse = client.Search<Project>(s => s
   .Query(q => q
       .Bool(b => b
           .Filter(bf => bf
               .DateRange(r => r
                   .Field(f => f.StartedOn)
                   .GreaterThanOrEquals(new DateTime(2017, 01, 01))
                   .LessThan(new DateTime(2018, 01, 01))
               )
           )
       )

   )
);
I assume this is a side effect of providing a "fluent" API in c# but it seems pretty awful to me.

Actually, in general the API seems way crazier/dumber than the python one. There are also like 5 different ways to specify property mappings for objects, and for some reason the documentation doesn't seem to like to discuss the only one that seems to be even remotely readable (using attributes).

Edit: Oh never mind. It does seem like an alternative does exist, although there don't seem to be as many examples for it. Argh, it looks like if you use that syntax you just end up entering stuff as strings without type safety, though.

mystes fucked around with this message at 01:11 on Jun 26, 2017

mystes
May 31, 2006

.NET Core 2.0 Preview 2 has been released, and f# appears to be working again for the moment.

mystes
May 31, 2006

Xeom posted:

New to this guys and I'm having an issue. I'm just trying to go through an array of strings in order to check if the word in the string is also in "enable1.txt".
Every time a word does match, it should up score by one. However, as far as I can tell it is only processing the first element of "input" even when other words are in "enable1.txt".

What am I doing wrong?

code:
    public static int compareText(string[] input) {
        StreamReader reader = new StreamReader("enable1.txt");
        int score = 0;
        foreach (string x in input)
            while (reader.EndOfStream == false)
                if (reader.ReadLine() == x) {
                    score += 1;
                    //Console.WriteLine(x); // for debugging
                }
        reader.Close();
        return score;
    }
Since nobody actually explained why this doesn't work:

The while loop keeps advancing in the file until the end, and you don't do anything to reset the position to the beginning. This means that after the first time you go through the while loop, it will already be at the end. To make this code work, you would need to either open the file again in each iteration of the for loop (really terrible) or seek to the beginning each time (less terrible).

The first code that B-Nasty gave is more efficient and solves this issue by switching the order of the loops, so that the outer loop reads through the file and you only have to do this a single time.

quote:

The lambda expression is the really confusing part. It seems to say "look for x, but hey x itself is a search function". Does the lambda function just tell Contains() give me everything you can find and put it into a list?
Lambda expressions are just a way to define functions without giving them names. The actual lambda expressions shouldn't be confusing, although code that actually uses them may be confusing if you aren't familiar with this style.

x => input.Contains(x) is just like
code:
bool myfunction(x) {
return input.Contains(x)
}

mystes fucked around with this message at 03:46 on Jul 9, 2017

mystes
May 31, 2006

Probably direct2d or something.

mystes
May 31, 2006

Mr Shiny Pants posted:

This is probably very simple, but my Google Fu is failing me and I can't seem to make it work so maybe you guys know:
How can I make a Map or a List that contains the Type of an object in F#?

Like:
code:
uuid, System.Guid
text, System.String
etc.
Without resorting to strings? I would like to map database type to their respective CLR counterparts but I can't seem to get the syntax right.
The types will have type System.Type, and when you write individual type names you will have to use typeof<System.String> etc., but otherwise there's nothing special I think.

I'm not sure if "uuid" is supposed to a string or an object or whatever, but if it's supposed to be a string:
code:
> let typemap = Map.empty.Add("text",typeof<System.String>).Add("uuid",typeof<System.Guid>);;

val typemap : Map<string,System.Type> =
  map [("text", System.String); ("uuid", System.Guid)]

mystes fucked around with this message at 23:59 on Aug 6, 2017

mystes
May 31, 2006

LongSack posted:

Is there a way in visual studio to have classes automatically created when I start a new solution? Like when I start a new WPF project, I know that I am going to want
  • NotifyBase
  • ViewModelBase
  • DialogSupport
  • WaitCursor
  • Styles.xaml
  • Pallette

It would be really nice if all that could be automatically added when I create a new project. Is there a way to do that?
Why don't you just make your own project template?

mystes
May 31, 2006

Completely Ignoring the whole first paragraph and the WPF part, it sounds sort of like maybe LongSack just wants to create his own ORM essentially where he can create a class that corresponds to a database row and then use reflection or code generation for the actual database code based on the fields in the class?

mystes
May 31, 2006

From what I've been reading, it seems like there are people within Microsoft who hate .net and like UWP because it provides an alternative vision where .net isn't the only way to produce WPF applications going forward, so I can't see those people giving up on UWP any time soon. Maybe they could give up on the store and try to integrate the desktop .net framework and UWP again though? I don't know if that would be possible.

mystes fucked around with this message at 13:55 on Oct 9, 2017

mystes
May 31, 2006

LongSack posted:

Also, can someone help me avoid the “unsigned application” thing with my installers? I have nearly a dozen tools that I have made available to my coworkers, and every time they run the installer, they have to go through the “install anyway” thing. I’d love to get rid of that warning. This page tells me what I need to do, but doesn’t really tell me how to do it.
You need a code signing certificate. I think the cheapest ones are like $20? You can also probably also use an internal ca if you have that set up.

Edit to expand slightly:
You need a code a code signing certificate. If you don't have an internal certificate authority set up as part of your windows domain, you will have to buy one (like buying an SSL certficate), but an internal certificate authority is probably actually the correct solution. Unfortunately, your company probably either won't have one or won't create a code signing certificate for you.

Actually you might also just be able to generate your own self-signed code signing certificate and get your coworkers to add it to the windows certificate store, but even if windows allows that, I don't know if that would be better than having them click through the warnings.

mystes fucked around with this message at 03:40 on Nov 1, 2017

mystes
May 31, 2006

LongSack posted:

I have an SSL cert from let’s encrypt for my website. Can I leverage that or is this something completely different? $20 is no big deal. $20 a year is no big deal. $200 is eh. $200 a year is a non starter.
No it's similar but not exactly the same. Part of the problem is there's no domain for code signing so it can only identify you by name, meaning that all code signing certs are essentially EV certs and therefore can't be automated with something like let's encrypt.

Actually it looks like I misremembered and the cheapest ones are more like $70, unfortunately.

mystes
May 31, 2006

B-Nasty posted:

We need a LetsEncrypt for CSCs.
As I stated earlier, all code signing certificates are effectively EV certificates, so this wouldn't be possible. Simply validating that an application really came from a web server at ksjhgsjsghkjgskjhg.com would be pointless (that's what SSL already does)..

mystes
May 31, 2006

B-Nasty posted:

They aren't, though. EV certs give you SmartScreen bonus points, but aren't required for desktop apps.
There are actual EV code signing certificates, but don't all code signing certificates require actual identity verification similar to EV SSL certificates? What I was trying to say was that just as granting of EV SSL certificates inherently can't be automated, code signing certificates also inherently require manual identity verification.

quote:

As far as locking a CSC to a website...at least that would help to prevent download hosting sites from injecting malware into installers or even compromised servers from the company. Though, that didn't help CCleaner.
If the code signing certificate just had to match the website you were actually downloading from, that would be no different than just having an SSL certificate. Otherwise, you could just grant code signing certificates for domains but the user would have to know what domain the software should have come from, which is probably not realistic. I think the goals of the current system are 1) you want to be able prevent random people from saying they're a major company like Microsoft, and 2) you want to hopefully be able to revoke certificates used to create malware. I don't know how well this system actually works in practice, though.

mystes fucked around with this message at 01:11 on Nov 3, 2017

mystes
May 31, 2006

B-Nasty posted:

I would argue that it's still better to have a CSC. Ideally, FooBarCorp would sign its binaries/installers on a reasonably secure development machine/CI server, where their marketing/download site might be running on some insecure shared host or using outdated Wordpress. When I download FooBar-Paint-Installer.exe and see that it is signed by foobarcorp.com, I have a slightly higher confidence than just the fact that my download was served by a server identified as foobarcorp.com.
This is currently arguably true but in the context we were discussing, it would stop being true if it were possible to automatically acquire code signing certificates as with let's encrypt, because when your ssl server was hacked it would just request a new code signing certificate.

mystes
May 31, 2006

B-Nasty posted:

Certs can be revoked when the hack is discovered, and with modern Windows versions, UAC will give you an ugly, un-skippable error message if you try to run an elevated, revoked exe. Also you could use certificate authority auth in your DNS to prevent new certs from being issued after you've obtained your CSC.
Interesting. I didn't know about certificate authority auth. Is it actually in use? This still doesn't really help that much with cscs though, does it? Are you even required to have a URL in them?

mystes fucked around with this message at 18:55 on Nov 3, 2017

mystes
May 31, 2006

fankey posted:

Given a list of IP addresses, I'm using the following to determine the first address to response with a valid HTTP response
code:
    static async Task<string> DownloadCheck(HttpClient client, string ip)
    {
      try
      {
        var rsp = await client.GetAsync( "http://"+ip, HttpCompletionOption.ResponseHeadersRead);
        if (rsp.StatusCode != System.Net.HttpStatusCode.OK) ip = null;
      }
      catch( TaskCanceledException)
      {
        // expected...
      }
      catch(Exception)
      {
        // not able to contact ip
        ip = null;
      }
      return ip;
    }

    static async Task<string> GetBestIpAsyncInternal(IEnumerable<string> ips)
    {
      using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) })
      {
        IEnumerable<Task<string>> requests = ips.Select(ip => DownloadCheck(client, ip));
        Task<string> winner = await Task.WhenAny(requests);
        return await winner;
      }
    }
The issue is that if a given address fails and returns null before a valid response then my code returns null. Ideally I could call something like Task.WhenAnyEqual(requests, (ip)=> ip != null ) but such a thing doesn't exist. Any ideas how to accomplish this? I don't want to use Task.WhenAll because I don't want to wait around for some calls to timeout before returning a response.
If you don't need to be able to cancel the remaining requests, couldn't you use parallel linq or something?

mystes
May 31, 2006

I have a powershell script that calls some C# based on this using a nativewindow to create a global hotkey because that was the first thing I found a while ago, but it was inconvenient because then it's in the event loop and ties up the powershell interpreter, so I changed it to run in a separate thread. However, now I have the problem that I don't have a way to signal the thread to shut down (there's no Form so I can't use Invoke). Since the code already has to override WndProc should I just use PostMessage or something? I guess I could use SetTimer from user32.dll to set a timer and then check a variable periodically to see if the thread should shut down, but this would just add an extra step I think?

Maybe there's a better way to do this, but I know absolutely nothing about the low level win32 api. I'm not sure if there's a higher level way to get at the event loop in this situation?

Adbot
ADBOT LOVES YOU

mystes
May 31, 2006

Bind a global hotkey without creating a visible window, in an object that I can manipulate from powershell for autohotkey type functionality. This is working, I just don't have a way to signal the thread running that to shut down, which means that the process won't actually terminate when I close the powershell interpreter. All of the examples I can find for this sort of situation use Control.Invoke, but I don't have any winforms controls, so I don't know if there's some other way to queue some sort of action from the other thread?

The background of what I'm trying to do: The idea is that I will be able to instantiate my class from powershell and register various hotkeys. Before I changed it to be multithreaded I was passing powershell functions as delegates that were then called by the C# code, but currently I am now using a ConcurrentQueue which the thread with the nativewindow object uses to signal that the hotkey have been pressed, which is working fine, but I just don't know how to signal the thread to shut down.

I could also switch to using a keyboad hook but I don't know if this would make any difference?

Basically, does just using Application.Run without an actual winforms window create some sort of message queue that I can access directly? I tried searching, but as I said, the only thing I can find is Control.Invoke which normally handles this automatically. It seems like there should be a more direct way to do whatever Control.Invoke does myself, but I can't figure it out. Since I have no idea how Control.Invoke works, it's also possible that it literally just sends a message to the window and there's handler code in winforms for this that won't exist in this case because it's not a winforms window, but I have no idea. I may be fundamentally misunderstanding how this stuff works, but I find it a bit annoying that I can't find any actual explanation.

mystes fucked around with this message at 04:56 on Dec 7, 2017

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