|
In case anyone is interested on the status of my topic. After several more days of probing, I have successfully been able to run a WPF application by unpacking a much smaller .NET distributable compared to having to install the entire framework. My app is simplistic, and just is a WPF window with a button inside that when clicked shows a messagebox. I wanted to just get this working and test the theory. I have packed all the necessary files: registry entries, .NET framework folder, and my simple WPF app into a file. After purging the .NET framework folder of everything unneeded (dll, install files, configuration files), the resulting distributable folder is 48.1MB. Using 7z to pack this results in a file that is 12MB. This includes system.dll, PresentationFramework.dll, PresentationCore.dll, System.xaml, and system.xml managed assemblies. Also, using the method I have devised, you can unpack this distributable file to any location and run the application from there. This will come in handy when I elaborate on the end goal in the next sections.
So let me take a step back and explain why I did this. Here is the scenario. We want to deploy our application to manufacturing; however, the computers that are being used are running a minimum of XP. This means that we have to plan for no .NET framework install on the system. Keep in mind that the people running our application don't understand anything about installs, etc., therefore we have to make it a click once solution. The most that they know how to do is download a file from the internet, copy it to a flash drive and run it on the computer.
With this in mind, we of course can say to them: hey, install the .NET framework first then use our program. This introduces another step for them. Believe me when I say introducing steps into this system is a bad idea. These people are computer illiterate and do not have the time to be tracking down files and installs. The less stuff you have in the system the better. We also have the goal of having a custom branded UI the entire way. Lastly, we want to run a few custom program / build steps before we actually install our program to verify certain things on the computer beforehand. In the end, we will install the .NET framework 4 if it is on the computer, BUT, we also want this entire process to be inline with our custom branding. Thus we cannot run the .NET installer as is. Luckily, the .NET installer allows us to install silently and also pipe progress to our program via a memory map. Also, keep in mind that the .NET installer will take several tens of seconds to fully install on the system.
So.. here is the series of events that will happen: User downloads our click once file and runs it on their computer. We get and create a temporary directory. If .NET is not installed on the system, we unpack our .NET redistributable. We then unpack our custom WPF app. Additionally, a standalone version of 7zip is unpacked to the directory so that we can unpack stuff. In order to run the WPF app without .NET, we need to install some registry keys. They get installed. Next, our WPF app is started. It then deletes the registry keys that it installed. Since the WPF app is already started, it can do this, because the registry is not needed anymore. The user then presses next to install our real application. During this process, since .NET is not installed, we unpack the .NET installer and pipe the progress to our WPF app and install the framework.
With this method, the .NET installer has no knowledge that we are in fact running a WPF app without the framework installed, because the registry keys used are already cleaned up, and we are running the framework from a temp directory. Of course, the above method is watered down, but if anybody is interested in specifics, I can explain further.
Now, the reason it took so long to figure this out was because I was missing a piece of the puzzle. It turns out that the .NET framework uses TWO important registry nodes to get directory information. This is how you can run the framework from a directory outside of C:\Windows\.NET.... etc.. The two important nodes are HKLM.....software\microsoft\.NETFramework AND HKLM...software\.NETFrameworkSetup... and all associated keys. There are I think 4 path keys that point to directories for the framework. If you redirect them all, to your custom framework folder, you can run the framework from the custom directory.
Next, there are a few more things we have to realize. The framework needs a set of native dlls to run that are installed with the framework into the system32 folder. I believe we can also reroute these dlls into our custom .NET folder and have it work. As I write this, I kick myself for forgetting to test that aspect out. Anyhow, the important dlls are mscoree.dll, mscoreei.dll, mscoreeis.dll, msvcxxx_xxxclr.dll. I don't know the exact list off the top of my head, but as long as you have these in a path that can be found by distributable, it will run fine. These dlls are unpacked with the .NET framework and are not shipped with a bare install of XP. Windows 7 might already have some of these dlls due to .NET already being installed. In addition to the above dlls, you need to also put mscorwks.dll into the .NET distributable framework folder.
Lastly, it turns out that if the clr cannot find the managed assembly that it needs, it actually falls back to looking in the directory where you started the original exe from. The clr uses the registry to determine locations of assemblies, such as the GAC assemblies. I couldn't be bothered to track down these keys or figure out how they worked and solely relied on the fact that the clr will look at the directory you started the exe in. Therefore any assembly you need for the program can safely be packed in the same directory as the program itself and be found. When I was testing, the clr tried to look for GAC assemblies using the registry, and of course they were not in the registry, because I tested my method by uninstalling the framework first.
So overall, this entire process should take around 3 - 5 seconds to execute on a slow XP machine without the .NET framework. So within that time you can copy the files, modify the registry and execute a WPF program without installing the framework. If anybody is actually interested in more detail, drop a line.
|
|
|
|
|
Drop a line? Heck, I'd love to see an article on this. It could, potentially, be the most interesting article of the year.
|
|
|
|
|
Haha, glad to see a person with jesus status is interested. Unfortunately, I have not worked out all the kinks yet such as the placement of the system32 dlls. I believe I tried them in the framework folder at one point and it worked, but I can't remember. Today I started from scratch and tested the WPF portion, because ultimately, we want a nice WPF UI to be able to run without .NET installed. Also, there is the issue of the wow6432 node as well.
Overall, I have to make essentially a shim program that does all of the above and checks various things on the system, one of them being if the system is 64 bit and putting the registry entires in the proper place. This will be done in native win32 c++. However, since all we are doing is modifying the registry, unpacking and copying files, and run processes through CreateProcess, this shim should not be hard to do.
Once I get that up and running with all the needed components, I could write an article. Keep in mind that that all sprouted from the fact that we wanted a custom branded WPF UI on a computer without the .NET framework installed. The user can of course spend 20 seconds installing the framework, but then they see the crusty default win32 installer UI. We wanted to make it so that the entire process of installing our program AND the full .NET framework resided in our custom branded UI. If the user is willing have a delay of 5 seconds before they see our screen due to the fact the framework is not installed initially, I think that is acceptable. 5 seconds is relative to tests that I did awhile ago with extracting 7z files into a folder. It could very well be much shorter on a modern SSD based computer. I am testing on a very old 5400RPM harddrive core 2 duo system with XP on it, because that is our base metric.
It turns out that its very simple to do all the things that I once thought were magic such as getting your program to show up as a program in windows and the control panel. Its 2 registry keys. Add a few more registry keys and now you are on the right click context menu on the desktop. I think I have learned more about how the windows registry works in these past couple of weeks than I have since I became a programmer more than half a decade ago. It's also more than I wanted to know too.
I was throwing around various ideas in order to attempt to meet our requirements. My first idea was to write the program in mono and a UI in GTK to do what we wanted. This is because you can distribute a standalone exe and have it work. However, mkbundle sucks on windows, and I posted several problems in trying to get that work on their forums. Of course, nobody cares on their forums. On the bright side, you can package a few dlls with your exe in mono and it just simply works. This is because mono does not rely on the windows registry at all and will look for the dll's it needs in a defined directory. You need to define a lib folder and a root folder and that's it. Even though to get the mono solution working was easy, I just kept coming back to: "Nothing can beat WPF, nothing can beat WPF". Its true in my opinion. After trying out GTK for a few days, you realize how awesome WPF really is with its layout system and just everything about it.
The next idea was to use silverlight. The SL installer takes about 9 seconds on the machines I tested with. With this option, I was planning on making a bare simple mono GTK UI with the method described above that just popped up a custom branded windows that told the user "Please wait, installer initializing" while silverlight silently installed in the background. Then I could use silverlight with the power of WPF to make our custom branded UI after that. This turned out to be doable, and I even tried to reroute registry keys so that I could run silverlight from a directory other than the install directory just like I accomplished with the .NET option. Even though I got my application to run, there are problems with this mechanism. The first is that its hard to pass command line arguments to a silverlight program. The second is that now we have 3 technologies working in our system: mono, silverlight, and .NET when it comes down to installing the real program. A little bit of a head scratcher when trying to figure out what is going on. I would have to tell my boss that it would be hard to wrap his head around what was going on. Therefore, this option is out.
Finally, with my method described with the .NET redist, you only have a single framework: .NET and WPF AND you can pass command line arguments to the program. The program has full trust and a powerful UI framework to go with it. Any control libraries I make for the .NET redist in WPF I can then reuse in my real .NET app that we are packaging with the installer.
|
|
|
|
|
CMurphy77 wrote: My company is spending no money on this solution
So you work for free?
|
|
|
|
|
Question for you. Do you like attempting to short circuit conversations for no purpose other than to make cheap shots and make people look bad? Why don't you focus on the situation at hand, and if you can't do that, then don't respond in such an aggressive, pointless manner. I am not interested in your 'many years of experience' in saying things are not possible just because they are inherently unsupported, meaning nobody has tried them: not that they cannot be done.
Secondly, to answer your question directly... No I don't work for free. I am looking at the packaging option presented here on my own time. One does not need to be paid in order to dabble in a hobby.
|
|
|
|
|
CMurphy77 wrote: in saying things are not possible just because they are inherently unsupported
Oh, no, no, no. There are things that are not worth the cost if they've already been done cheaper. There have been way too many questions around here where the person thinks they cannot afford a paid solution, but completely forget to factor in the cost of their own time when trying to "roll their own" because they think it's cheaper.
|
|
|
|
|
Believe me, I work in an environment where you have to have the mindset to not roll your own. The people I work for want results 100% of the time. At any given time I am literally working on 5 different projects. Not because management is scatterbrained, but because they want results. This is completely different. I find this topic fascinating: Trying to make windows do something it was not intended to do.
If the solution I am looking into right now proved to be as complicated as writing a linker or rolling my own whatever, then it probably wouldn't be worth it as you said. I agree with you that many people think they can storm in and write something and realize after the fact it is going to take a year to do. Been there done that.
If what I want to do is as easy as injecting some hooks into some process code to modify the basic operation of a function, then it is worth it. It seems possible.
After taking a look at ZwOpenFile, it looks like it may be able to handle named pipes natively, meaning that the HANDLE the function gives to LoadLibrary may just work. One could load the dll from the exe resource into memory, then shove that in some sort of named pipe. ZwCreateFile would then just create a file HANDLE out of that.
|
|
|
|
|
LostTime77 wrote: I would treat this as more of a "what if" question besides trying to worry about
what is happening with why I am asking the question. If it were possible, people would abandon the runtime and go for the native option. Anything else? Seems you've already forbidden every remark I can make
FWIW, there are more runtimes available, and some of them are open-source.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Blurbs from Boxed App suggest that rather explicitly that they are using virtualization - there is a windows API for that. That shouldn't require tricks with other windows APIs.
Virtualization that I have seen creates a single file. That single file could be the exe with an appropriate data area.
|
|
|
|
|
I happened to read the white paper on boxed app, and it stated that they were hooking all the file system calls and creating a virtual file system within the process memory.
I didn't want to tinker with that, because intercepting all file system calls would be fairly complicated to get correct. I stopped into their forums, and the fact that there are threads that say "bug here... Found bug here... This doesn't work in this way..., etc." suggests to me that its not a robust way to do things.
Also note, that the article where they packaged .NET was when .NET 3.5 was available. Who knows what has changed since then.
I am fairly new to API hooking, so it if it possible to hook all file system calls easily and reliably like they apparently do, I can be persuaded otherwise.
However, note that I did some hooking tests to see what the Win32 LoadLibrary was doing. It turns out that it used ZwOpenFile to open a file, but never calls ZwReadFile. This means that windows is somehow internally reading the file without using its own API, unless I am missing something. If this is true, I have no clue how BoxedApp is seemingly intercepting ZwOpenFile and modifying the PHANDLE parameter to point to a valid file handle in memory. Sure if you knew the layout and structure of Win32 file handles AND can create your own arbitrary, valid Win32 handles (which I am not aware that you can), then maybe you can do what they are doing.
With that said, I don't know how they are hooking the file system calls if ReadFile is never called from LoadLibrary. If you could hook ReadFile, then you would have a much better chance of getting something done, because I would think you could just manually return some byte arrays from memory to the LoadLibrary call.
|
|
|
|
|
This is probably the wrong place to ask this question,...please direct me to the proper forum if it is.
The question is:
Is it possible to invoke a NET Framework interface (an object and its member functions) from a MASM assembly language program ??? Obviously, this assumes that a version of the NET Framework library exists on the computer that the program runs on, and, that the exported function is prototyped correctly.
|
|
|
|
|
Yes you can. It won't be easy, but it is possible.
|
|
|
|
|
PETE,
Thanks for the response. I assumed that it was possible, but, very inconvenient. I'll have to do some more research.
Just out of curiosity,...how exactly do you know it is possible ???
|
|
|
|
|
For example -> Windows C++ app hosts CLR[^]
You just have to do the same thing in Assembly Language. If you can write a Windows app in Assembly, you can host the CLR in it too.
|
|
|
|
|
DAVE,
Thanks,...I'll read through the source code. This is very encouraging.
modified 17-Jul-13 13:54pm.
|
|
|
|
|
Also, every .NET application starts as a normal Win32 application and then calls into the .NET runtime library. The rest of the executable 'contents' is usually MIDL (an intermediate language for .NET), which is then interpreted by the .NET runtime.
|
|
|
|
|
i want to show report based on date condition and show it in gridview. It is working in my local machine but not working in server after hosting.
query is SELECT * FROM table WHERE DATE(colmn1) between 'startdate' and 'enddate'
What could be the problem.
If anybody knows please reply me.
Thanks in advance
|
|
|
|
|
This has nothing to do with the .NET framework.
You would probably be better off posting this in the appropriate forum, the database forum for example[^]
You might want to supply a bit more information than "not working" as "not working" is neither helpful nor informative in describing a problem.
|
|
|
|
|
ven753 wrote: If anybody knows please reply me.
Could be several reasons due to bad assumptions some of possibilities of which follow.
- You are not running that code in production.
- You think you know what dates should work but they do not in fact represent data in the data base.
- Your code is working on one database and you are looking at another (thus the dates do not match.)
- The dates that you think are being used in the code are not in fact the ones being used.
- Your only information comes from someone else reporting the problem and they are reporting in wrong.
|
|
|
|
|
|
Sorry, flagged as spam.
Member 10154869 wrote: They have programmers online to help you now. Only cooks and werewolves here?
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hi all,
I'm a newbie at VB.net,
I want connect to access via VB.net and manager two table with a relation type "master-child",
Master table named "Book" consists of three columns: BookID [AutoNumber], Author [Text], Description [Text],
Child table named "Chapter" with three columns: ChapterID [AutoNumber], BookID [Number], Title [Text],
Then I create an application VB.net that has one main window using a dataset with two table Book and Chapter. I make a relation between them, from BookID in the table Chapter to BookID in the master table. I use a databindingsource to manager them, the table Book is displayed by a form detail, the Chapter by a datagridview. When I delete a row in Book-table, I also want delete all chapter located it. I tried to use Tableadapter but the chapters were not deleted.
Help me,
|
|
|
|
|
|
Truth be told I wanted to put this in design and infrastructure but for some reason the page was blank. Anyways this is a good spot because it has some .net specific issues. I am starting to write a rather large program. Easily my biggest ever by a long shot. Now I am having an issue with how the interface should deal with requirements of the dll. I will give an example. The dll will make a submission to a website and the submission should have at least 1 image. So as I see it I have 2 options and could actually do both. Should the interface know this requirement and check if the user has added at least one image (therefore alerting the user and not making the submission) or should the dll throw an exception to which the interface will catch and then let the user know. Or should I do both? Or is there another way that I am not thinking of?
|
|
|
|
|
I will make sure if I want to make only website submission's DLL or make another DLLs using the same interface.
In the first case make sense to write the check at application level because you'll produce less code at DLL level.
But if you want to write not only website submission plug-in I will write the check at plug-in level and will have the exception handling at application level as you write.
Generally whatever you choose it should be clear and documented for plug-in programming purposes.
|
|
|
|
|