Can anyone help me with enabling ODP.Net logging on a Windows XP machine? I googled and found following link but it did not work for me.
http://download.oracle.com/docs/html/E10927_01/featConfig.htm
I set the "TraceLevel" setting to "63" in registry but it did not help
Basically I want to capture all the database call happening from my C# code through the log.
I wish there was a tool like "SQL Profiler" for Oracle.
I had the same issues on certain machines when troubleshooting some issues with Oracle Support. I found that changing the path to the output file a couple of times and multiple restarts finally forced the ODP client to start logging. Make sure that the output file is to a directory that your calling application identity has access to.
Check the following things in the registry keys. Here is an example from my machine for .net4 and 11.2.
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\ODP.NET\4.112.2.0
32 or 64 bit (correct node)
Change the Trace Level to 8 (or 64 I think for complete logging)
Change the Trace Option = 1
Set a valid TraceFileName
Note that the trace will default to go in the root of the C drive. For Windows 7 and later, this requires administrator privilege or it will just fail silently. So either make sure your app is running as administrator or that you change the path of the file.
Also note, that if you want to trace ODP.NET fully managed, you need to put the settings inside the app or web config file, not the registry, AND the settings for TraceLevel are different (1 through 7).
And finally, when tracing unmanaged ODP.NET remember that there is a separate WOW registry node for 32 bit Windows. If your app is 32 bit, don't accidentally set it under the 64 bit portion of the registry.
You can also use AOP-based approach - generate proxy using library like Castle Dynamic Proxy, intercept the calls you're interested in and log the arguments like SQL and parameters. This is more powerful method in my opinion although it can somehow affect performance. See this Gist for sample implementation: https://gist.github.com/Buthrakaur/b1124c08f8521f39f8fd
Related
Good day everyone,
I am writing a C# application that will allow users to dynamically set the database they want to connect to (I'll work a bit with the database data and such, but that's not important). The important part is that I'm allowing my users to connect to data-stores from OLEDB using the code below.
ADODB.Connection connection;
MSDASC.DataLinks instance = new MSDASC.DataLinksClass();
if( (connection = instance.PromptNew() as ADODB.Connection) == null ) return;
This will open the very same Dialog that windows opens for *.udl files, and that's exactly what I want.
However, I hit a interesting problem to which your brightness could come in handy: some customer WILL have to browse for x86 drivers, and the vast majority will certainly use x64.
I know you can open x86 UDL files with the following command-line:
"C:\Windows\syswow64\rundll32.exe" "C:\Program Files (x86)\Common Files\System\Ole DB\oledb32.dll",OpenDSLFile "C:\myConnectionFile.udl"
When the default (64 bit) command is:
"C:\Program Files\Common Files\System\Ole DB\oledb32.dll",OpenDSLFile "C:\myConnectionFile.udl"
In other words: windows' allowing users to create entries in both fashion. I would like to do the same in my app, using the API.
I have considered the option of creating a temp UDL file and opening from the command-line above, which made my conversation with my technical lead rather unpleasant, so that's not an option.
All suggestions are welcome. I will not dismiss unsafe coding nor the thought of building wrapper in C++ if we get to that (although my C++ is inconveniently rusty nowadays).
Thank you all in advance and happy coding...
Good day fellow developers,
After a tedious and lengthy research process I have around the answer I was looking for.
In order to use OLEDB providers for both 32 and 64 bit platform from one single C# 64bit app I'll need to create an Out-of-Process Wrapper to the 32bit call, and make the call over IPC (Internal Process Calls). Because the amount of functionalities I'm exposing is moderate, the hindrance was just re-creating some method calls on the wrapper.
This blog helped me put the parts together, and now I'm able to determine what type of OLEDB connection I'll allow my user create, and I'm also able to perform all operations I need regardless of the Provider Architecture.
I hope this will benefit other people who might be having the issue.
If time (and NDA) allows, I'll get the code here for people to copy and try it later.
These links were also very useful on my research
http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
Registering the DLL Server for Surrogate Activation
https: // msdn.microsoft.com/en-us/library/windows/desktop/ms686606(v=vs.85).aspx)
Writing Serviced Component
https: // msdn.microsoft.com/en-us/library/3x7357ez(VS.80).aspx)
How to: Create Serviced Component
https: // msdn.microsoft.com/en-us/library/ty17dz7h(VS.80).aspx)
Create Out-Of-Process COM in C#/.Net?http: // stackoverflow.com/questions/446417/create-out-of-process-com-in-c-net
Thanks everyone
D
I'm trying to get data from the registry of windows to my software but there is one thing i'm having trouble with it:
if my software runs on a 64 bit system the registry path will be :
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\AVAST Software\Avast ProgramFolder
and if my software runs on 32 bit system the registry path will be :
HKEY_LOCAL_MACHINE\SOFTWARE\AVAST Software\Avast ProgramFolder
What can i do ? to double check every time ?
maybe i will check only the second option(without the \Wow6432Node\) and when the software runs on 64 bit it will automatically add to the path the \Wow6432Node\ ?
What is the best solution for this issue ?
Before you do anything further, you should have a good read of the documentation of the registry redirector. It's really important that you have a clear understanding of what it does.
OK, now that you understand the registry redirector, let's look at how to tackle your problem. You have a few options. The simplest is build your program to target x86, and access HKEY_LOCAL_MACHINE\SOFTWARE\AVAST Software\Avast ProgramFolder no matter what bitness system you run on. That way your code will always run in a 32 bit process and so always see the 32 bit view of the registry. The registry redirector will handle the mapping onto the true physical Wow6432Node transparently.
Alternatively, if you must use AnyCPU, and must cater for running inside a 64 bit process, you need to use the RegistryView enumeration. This allows you to read from the 32 bit view of the registry, even from a 64 bit process. But again you access HKEY_LOCAL_MACHINE\SOFTWARE\AVAST Software\Avast ProgramFolder but ask for that key with respect to the 32 bit view of the registry.
The golden rule with the registry redirector is that you must not hard code Wow6432Node into your paths. The documentation says it like this:
Redirected keys are mapped to physical locations under Wow6432Node. For example, HKEY_LOCAL_MACHINE\Software is redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node. However, the physical location of redirected keys should be considered reserved by the system. Applications should not access a key's physical location directly, because this location may change.
Don't be tempted to break that rule. The system provides mechanisms to read from the 32 bit view in a supported manner.
You don't state which version of the framework you're using, but if you're using 4+ then you can use Environment.Is64BitOperatingSystem to determine the bitiness of the environment and therefore look/write to the correct place.
A new game released has been provided with server files that do not currently have the option of configuring an IP Address/Port for binding. Unfortunately this limits the ability to run more than one instance of the application per machine as it is hard-coded to port "12345".
Many years ago I was using c++ and hex editors to change hard coded values like this and while that knowledge has long since been forgotten, would it be possible to improve this by writing a secondary application to change that value at runtime?
You still can use hex editor in order to change the hard coded constant.
Another way is to use debug api, provided by any decent OS. In Windows it is WriteProcessMemory function.
It looks following way - the launch application runs the modified application in debug mode. Changes needed constant and then runs it.
Of course, the modified application may use anti debugging techniques - in this case the solution is not trivial.
In both cases, you have to know where this value resides in the memory (executable file). This way some reverse engineering have to be provided.
Note, after the last question edits: All this answer is for native executable files. For managed code it probably is more complex.
I have an assignment, and it has (amongst others) two demands:
make an installer
make it so that if it is installed on one computer, anyone trying to run the same files on another computer will fail.
I'm using VS9 (2008) express, I think I can do the installer part, but I'm not sure how to do the "security" part. I don't need any hard to crack safety, just a dumb condition that will stop most users from copying the files to another computer. (Like checking the MAC address).
Any ideas?
EDIT:
I would like to check the MAC address but I want the program finalized during installation. Meaning that after I install I can't move the program to another machine. It also does not have to be a very smart or difficult condition, just bare minimum. I just don't know how to do it in the installation.
EDIT:
It's sad I don't have the complete VS then I would be able to do it easily.
If you're looking for some way to mark the first computer as the "authorized" computer, then you need some external service you can ask for permission to launch.
The first person to ask permission would be allowed, the rest would be prevented.
You'll also need to come up with some way of identifying a particular instance of your application that's different for every install.
If your app needs to be authorized for the machine, then you will need to calculate some fingerprint for the machine it can use each time (eg across installs).
[Edit]
This approach is useful when you're worried about copies of the installer being distributed as well. You did specify that its ok to install on multiple machines, so in that case MasterMind's approach is superior. It will work, and does not requires a 3rd party server
[Edit 2]
If you're looking for info on how to build a custom installer, try here
First of all, come up with some function to generate a unique PC signature, like Windows does for activation.
Your installer will be creating this signature and writing it to a local file (better encrypted). You can create a simple console executable to generate this file and include that executable into your installer package, setting it up to run silently after the successful installation.
Your program when starting will be creating the signature again using the same algorithm and comparing it to the one created during installation. If the new signature is different from the original one or the signature file is missing, then exit without loading the UI.
ADDED: If you don't need it very complex, you can just choose a few unique values like the MAC address you suggested, maybe the hard drive serial number, mainboard serial number, concatenate them into a single string and generate the hash out of it.
This approach will allow for an unlimited number of copies to run (but each installation will only be workable on one single machine where it was installed). If you stick to the identification by hardware (or OS product key as well), then the application can run on various OS installations on the same machine.
This strategy, however, implies that you control all installations (or perform them yourself) or absolutely trust your client not to install additional copies elsewhere or distribute your installer. If you need that kind of protection as well, then you should consider product activation. It can be quite complicated if you do it yourself. There are however third party products to help you. Some offer product activation services: Google: activation service
Once you have a decent fingerprint, the rest is easy. Personally I'd take something like the MAC address and the windows product ID (at HKLM\Software\Microsoft\Windows\CurrentVersion\ProductId) and use a hashing algorithm to get something reasonably obscure.
edit:
Here's a question that shows you how to get your MAC address as a string:
Read MAC Address from network adapter in .NET
Then grab your windows product ID (in case they don't have a network adapter) from the above registry key. Concatenate both strings and do a GetHashCode() (or use your favorite hashing algorithm) on the result. This is a simple way to get a UID for a computer.
Write the hash to a file or to a registry entry when your installer is executing and check it when your program starts up.
Consider using two or more values that potentially identify the machine, e.g.
Windows product code
Volume serial number of the C: drive
MAC address of an ethernet interface
And if just one of these changes but the others match, update that one value in the registry and continue running normally. Hard drives get replaced (regularly), Windows gets upgraded (occasionally), Ethernet adapters get replaced (rarely but it does happen.) It can be very frustrating when old software stops working because of this.
Bare minimum answer, assuming the only requirement here is that the software should run if installed through the installer, and won't run if copied to another computer:
Write a simple key to the registry. Most likely your product's version number, incase they copy a newer version to the computer, it has a different number to check for.
In your software, just make sure this registry value exists.
For packaging installations, I enjoy using NSIS which has simple methods for writing to the registry.
I like the idea of checking the MAC address.
I have also seen product key/online activation combinations where you enter the product key and the software contacts a web service that logs the product key and # of installs.
This isn't the most secure option or anything but you did say it didn't have to be smart...
On install, you could set a program variable to be the machine name (or a hash of it if you like).
Like:
myProgram.Properties.Settings.Default.Machine = System.Environment.MachineName;
myProgram.Properties.Settings.Default.Save();
then check that on startup:
if (System.Environment.MachineName != myProgram.Properties.Settings.Default.Machine)
{
MessageBox.Show("Can't run on this computer");
this.Close();
}
To get the installer to only work for one machine, you'd pretty much have to build it for the target machine. I dont think it would be possible to make an installer that assumes the first machine it sees is it's mommy and is attached for life.
-1 for clinging to an antiquated license-restriction policy that is a poor practice in general. Hardware dongles and "device detection" are SO 1990.
People own more than one computer. They buy new computers. They upgrade their computers. Computers break, resulting in replacement of motherboards or network cards.
All of these, given your design, will result in honest, paying customers being locked out of what they've paid for and will have to call you for support to "reset" their activation.
And each time you do so, your overhead will increase by, very likely, more than the actual cost of a license.
I'm not suggesting you give up and just send your app off to the torrentverse, but you should think more creatively about how to allow customers the freedom to use what they paid for, keep your support costs low, and discourage pirates.
One creative solution would be to cache the user's settings on your server, keyed by their serial number, and synchronize them every time the application starts and is connected to the Net.
This will allow a user to install the app on, say, both a laptop and desktop, and will actually be a value-add for customers because their settings are synchronized between devices.
But it actively discourages users from sharing their license key, since doing so would mean they would be sharing their settings with every pirate user, or that they would have to remember to stay disconnected from the Interwebs when they open or close the app.
I have been trying to access a .NET Assembly that I have created in classic ASP using
dim foo
set foo = Server.CreateObject("TestAssembly.MyClass")
The problem is I'm getting an error:
Server object error 'ASP 0177 : 800401f3'
Server.CreateObject Failed
/test.asp, line 4
Invalid class string
I have registered the assembly (TestAssembly.dll) using gacutil and regasm as instructed in the article: Replacing Old Classic ASP COM Components with .NET Assemblies which I referenced from another question. It supplies two methods in which to install the assembly and I have tried both, but to no avail.
Getting this working would be great because it would allow me to gradually migrate a classic ASP site to .NET
Another thing to check: make sure your .Net assembly is set to be COM Visible.
Check in the registry here: *HKLM\SOFTWARE\Classes* and see if the namespace.class is there (e.g. "TestAssembly.MyClass") and that it has a key called "CLSID" with a valid ID.
If the registry entry isn't there then make sure that Project > Properties > Assembly Information has "Make assembly COM-Visible", then recompile.
Once compiled, run regasm (if you're on a 64bit machine they you will have to explicitly reference the 64bit version of regasm - c:\Windows\microsoft.net\framework64\v4.0.30319\regasm) with:
regasm /codebase /tlb TestAssembly.dll
This error means "Invalid class string" -- in other words the call to CreateObject failed because the name object cannot be found by the OLE sub-system. Causes include:
You really didn't run regsvr32 on the server after all.
You ran regsvr32 but it reported an error.
Someone modified security on part of the registry that's preventing the OLE subsystem from reading all or part of the HKEY_CLASSES_ROOT tree.
The name of the object you are trying to create was mispelled or is incorrect.
Determine if it's a permissions problem
Add the anonymous user (used by IIS) to the Administrators group. The test page then worked, proving it was a permissions problem. Do not forget to remove the anonymous IIS user from the Admin group!
Determine if it is a file permissions problem:
After removing the Anonymous user from the Admin group, add failure auditing to the file (smtpsvg.dll), which will determine if the file was ever accessed (by the lack of the failure event). If it isn't, this makes it clear that the failure is prior to file access but go ahead and check file/directory permissions to make sure the anonymous IIS user can access the file.
Check registry permissions
Using Regedt32, do find on smtpsvg.dll. Check the permissions for the key (and sub keys), and make sure that the anonymous user has read rights. Do a find on the class-id, which contains the location value, and version, and check those permissions as well.
source: http://forums.digitalpoint.com/showthread.php?t=21069
I have had problems in the past with calling .NET assemblies from ASP Classic. I think this was one of the several problems I ran into along the way.
One of the things I had to do to make things work was to make sure the Application Pool for the ASP site was using the same identity as the anonymous user (by default it uses "System User" or something like that). So I ended up creating a new local user (making sure it is a member of the IIS_WPG group) and using that for both the IIS anonymous user and the App Pool identity.
This is a troublesome area though, the app I was using it for was a shrink wrapped product and we found that some machine were screwed up in such a way that we simply couldn't get ASP Classic to .net calls to work even after lots of tweaking of permissions and the like.
Edit:
I guess I should say that I'm not claiming this change will fix this particular problem, just that this was one of the changes we had to make to make out ASP Classic -> .NET code work on a wide range of random customers servers.
I used icepicker's solution and it worked for me. I spent over a day looking into this error i was getting
Microsoft VBScript runtime error '800a01ad'
ActiveX component can't create object: 'namespace.class'
/page.asp, line 15
The solution was to use the c:\Windows\microsoft.net\framework64(folder of framework used)\regasm). I was running this from c:\Windows\microsoft.net\framework64 & c:\Windows\microsoft.net\framework and it did not work. My assumption is that if you run REGASM it will default to the 32 bit version. Unless you specify the framework64/v4.0.x.x.x (or whatever version) folder, only then it will run the 64-bit.